Merge tag 'secureexec-v4.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux

Pull secureexec update from Kees Cook:
"This series has the ultimate goal of providing a sane stack rlimit
when running set*id processes.

To do this, the bprm_secureexec LSM hook is collapsed into the
bprm_set_creds hook so the secureexec-ness of an exec can be
determined early enough to make decisions about rlimits and the
resulting memory layouts. Other logic acting on the secureexec-ness of
an exec is similarly consolidated. Capabilities needed some special
handling, but the refactoring removed other special handling, so that
was a wash"

* tag 'secureexec-v4.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
exec: Consolidate pdeath_signal clearing
exec: Use sane stack rlimit under secureexec
exec: Consolidate dumpability logic
smack: Remove redundant pdeath_signal clearing
exec: Use secureexec for clearing pdeath_signal
exec: Use secureexec for setting dumpability
LSM: drop bprm_secureexec hook
commoncap: Move cap_elevated calculation into bprm_set_creds
commoncap: Refactor to remove bprm_secureexec hook
smack: Refactor to remove bprm_secureexec hook
selinux: Refactor to remove bprm_secureexec hook
apparmor: Refactor to remove bprm_secureexec hook
binfmt: Introduce secureexec flag
exec: Correct comments about "point of no return"
exec: Rename bprm->cred_prepared to called_set_creds

+91 -159
+1 -1
fs/binfmt_elf.c
··· 252 NEW_AUX_ENT(AT_EUID, from_kuid_munged(cred->user_ns, cred->euid)); 253 NEW_AUX_ENT(AT_GID, from_kgid_munged(cred->user_ns, cred->gid)); 254 NEW_AUX_ENT(AT_EGID, from_kgid_munged(cred->user_ns, cred->egid)); 255 - NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm)); 256 NEW_AUX_ENT(AT_RANDOM, (elf_addr_t)(unsigned long)u_rand_bytes); 257 #ifdef ELF_HWCAP2 258 NEW_AUX_ENT(AT_HWCAP2, ELF_HWCAP2);
··· 252 NEW_AUX_ENT(AT_EUID, from_kuid_munged(cred->user_ns, cred->euid)); 253 NEW_AUX_ENT(AT_GID, from_kgid_munged(cred->user_ns, cred->gid)); 254 NEW_AUX_ENT(AT_EGID, from_kgid_munged(cred->user_ns, cred->egid)); 255 + NEW_AUX_ENT(AT_SECURE, bprm->secureexec); 256 NEW_AUX_ENT(AT_RANDOM, (elf_addr_t)(unsigned long)u_rand_bytes); 257 #ifdef ELF_HWCAP2 258 NEW_AUX_ENT(AT_HWCAP2, ELF_HWCAP2);
+1 -1
fs/binfmt_elf_fdpic.c
··· 650 NEW_AUX_ENT(AT_EUID, (elf_addr_t) from_kuid_munged(cred->user_ns, cred->euid)); 651 NEW_AUX_ENT(AT_GID, (elf_addr_t) from_kgid_munged(cred->user_ns, cred->gid)); 652 NEW_AUX_ENT(AT_EGID, (elf_addr_t) from_kgid_munged(cred->user_ns, cred->egid)); 653 - NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm)); 654 NEW_AUX_ENT(AT_EXECFN, bprm->exec); 655 656 #ifdef ARCH_DLINFO
··· 650 NEW_AUX_ENT(AT_EUID, (elf_addr_t) from_kuid_munged(cred->user_ns, cred->euid)); 651 NEW_AUX_ENT(AT_GID, (elf_addr_t) from_kgid_munged(cred->user_ns, cred->gid)); 652 NEW_AUX_ENT(AT_EGID, (elf_addr_t) from_kgid_munged(cred->user_ns, cred->egid)); 653 + NEW_AUX_ENT(AT_SECURE, bprm->secureexec); 654 NEW_AUX_ENT(AT_EXECFN, bprm->exec); 655 656 #ifdef ARCH_DLINFO
+1 -1
fs/binfmt_flat.c
··· 890 * as we're past the point of no return and are dealing with shared 891 * libraries. 892 */ 893 - bprm.cred_prepared = 1; 894 895 res = prepare_binprm(&bprm); 896
··· 890 * as we're past the point of no return and are dealing with shared 891 * libraries. 892 */ 893 + bprm.called_set_creds = 1; 894 895 res = prepare_binprm(&bprm); 896
+41 -15
fs/exec.c
··· 1259 perf_event_comm(tsk, exec); 1260 } 1261 1262 int flush_old_exec(struct linux_binprm * bprm) 1263 { 1264 int retval; ··· 1292 if (retval) 1293 goto out; 1294 1295 - bprm->mm = NULL; /* We're using it now */ 1296 1297 set_fs(USER_DS); 1298 current->flags &= ~(PF_RANDOMIZE | PF_FORKNOEXEC | PF_KTHREAD | ··· 1343 1344 void setup_new_exec(struct linux_binprm * bprm) 1345 { 1346 arch_pick_mmap_layout(current->mm); 1347 1348 - /* This is the point of no return */ 1349 current->sas_ss_sp = current->sas_ss_size = 0; 1350 1351 - if (uid_eq(current_euid(), current_uid()) && gid_eq(current_egid(), current_gid())) 1352 - set_dumpable(current->mm, SUID_DUMP_USER); 1353 - else 1354 set_dumpable(current->mm, suid_dumpable); 1355 1356 arch_setup_new_exec(); 1357 perf_event_exec(); ··· 1385 * some architectures like powerpc 1386 */ 1387 current->mm->task_size = TASK_SIZE; 1388 - 1389 - /* install the new credentials */ 1390 - if (!uid_eq(bprm->cred->uid, current_euid()) || 1391 - !gid_eq(bprm->cred->gid, current_egid())) { 1392 - current->pdeath_signal = 0; 1393 - } else { 1394 - if (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP) 1395 - set_dumpable(current->mm, suid_dumpable); 1396 - } 1397 1398 /* An exec changes our domain. We are no longer part of the thread 1399 group */ ··· 1574 retval = security_bprm_set_creds(bprm); 1575 if (retval) 1576 return retval; 1577 - bprm->cred_prepared = 1; 1578 1579 memset(bprm->buf, 0, BINPRM_BUF_SIZE); 1580 return kernel_read(bprm->file, 0, bprm->buf, BINPRM_BUF_SIZE);
··· 1259 perf_event_comm(tsk, exec); 1260 } 1261 1262 + /* 1263 + * Calling this is the point of no return. None of the failures will be 1264 + * seen by userspace since either the process is already taking a fatal 1265 + * signal (via de_thread() or coredump), or will have SEGV raised 1266 + * (after exec_mmap()) by search_binary_handlers (see below). 1267 + */ 1268 int flush_old_exec(struct linux_binprm * bprm) 1269 { 1270 int retval; ··· 1286 if (retval) 1287 goto out; 1288 1289 + /* 1290 + * After clearing bprm->mm (to mark that current is using the 1291 + * prepared mm now), we have nothing left of the original 1292 + * process. If anything from here on returns an error, the check 1293 + * in search_binary_handler() will SEGV current. 1294 + */ 1295 + bprm->mm = NULL; 1296 1297 set_fs(USER_DS); 1298 current->flags &= ~(PF_RANDOMIZE | PF_FORKNOEXEC | PF_KTHREAD | ··· 1331 1332 void setup_new_exec(struct linux_binprm * bprm) 1333 { 1334 + /* 1335 + * Once here, prepare_binrpm() will not be called any more, so 1336 + * the final state of setuid/setgid/fscaps can be merged into the 1337 + * secureexec flag. 1338 + */ 1339 + bprm->secureexec |= bprm->cap_elevated; 1340 + 1341 + if (bprm->secureexec) { 1342 + /* Make sure parent cannot signal privileged process. */ 1343 + current->pdeath_signal = 0; 1344 + 1345 + /* 1346 + * For secureexec, reset the stack limit to sane default to 1347 + * avoid bad behavior from the prior rlimits. This has to 1348 + * happen before arch_pick_mmap_layout(), which examines 1349 + * RLIMIT_STACK, but after the point of no return to avoid 1350 + * needing to clean up the change on failure. 1351 + */ 1352 + if (current->signal->rlim[RLIMIT_STACK].rlim_cur > _STK_LIM) 1353 + current->signal->rlim[RLIMIT_STACK].rlim_cur = _STK_LIM; 1354 + } 1355 + 1356 arch_pick_mmap_layout(current->mm); 1357 1358 current->sas_ss_sp = current->sas_ss_size = 0; 1359 1360 + /* Figure out dumpability. */ 1361 + if (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP || 1362 + bprm->secureexec) 1363 set_dumpable(current->mm, suid_dumpable); 1364 + else 1365 + set_dumpable(current->mm, SUID_DUMP_USER); 1366 1367 arch_setup_new_exec(); 1368 perf_event_exec(); ··· 1350 * some architectures like powerpc 1351 */ 1352 current->mm->task_size = TASK_SIZE; 1353 1354 /* An exec changes our domain. We are no longer part of the thread 1355 group */ ··· 1548 retval = security_bprm_set_creds(bprm); 1549 if (retval) 1550 return retval; 1551 + bprm->called_set_creds = 1; 1552 1553 memset(bprm->buf, 0, BINPRM_BUF_SIZE); 1554 return kernel_read(bprm->file, 0, bprm->buf, BINPRM_BUF_SIZE);
+19 -5
include/linux/binfmts.h
··· 25 struct mm_struct *mm; 26 unsigned long p; /* current top of mem */ 27 unsigned int 28 - cred_prepared:1,/* true if creds already prepared (multiple 29 - * preps happen for interpreters) */ 30 - cap_effective:1;/* true if has elevated effective capabilities, 31 - * false if not; except for init which inherits 32 - * its parent's caps anyway */ 33 #ifdef __alpha__ 34 unsigned int taso:1; 35 #endif
··· 25 struct mm_struct *mm; 26 unsigned long p; /* current top of mem */ 27 unsigned int 28 + /* 29 + * True after the bprm_set_creds hook has been called once 30 + * (multiple calls can be made via prepare_binprm() for 31 + * binfmt_script/misc). 32 + */ 33 + called_set_creds:1, 34 + /* 35 + * True if most recent call to the commoncaps bprm_set_creds 36 + * hook (due to multiple prepare_binprm() calls from the 37 + * binfmt_script/misc handlers) resulted in elevated 38 + * privileges. 39 + */ 40 + cap_elevated:1, 41 + /* 42 + * Set by bprm_set_creds hook to indicate a privilege-gaining 43 + * exec has happened. Used to sanitize execution environment 44 + * and to set AT_SECURE auxv for glibc. 45 + */ 46 + secureexec:1; 47 #ifdef __alpha__ 48 unsigned int taso:1; 49 #endif
+5 -9
include/linux/lsm_hooks.h
··· 43 * interpreters. The hook can tell whether it has already been called by 44 * checking to see if @bprm->security is non-NULL. If so, then the hook 45 * may decide either to retain the security information saved earlier or 46 - * to replace it. 47 * @bprm contains the linux_binprm structure. 48 * Return 0 if the hook is successful and permission is granted. 49 * @bprm_check_security: ··· 75 * linux_binprm structure. This hook is a good place to perform state 76 * changes on the process such as clearing out non-inheritable signal 77 * state. This is called immediately after commit_creds(). 78 - * @bprm_secureexec: 79 - * Return a boolean value (0 or 1) indicating whether a "secure exec" 80 - * is required. The flag is passed in the auxiliary table 81 - * on the initial stack to the ELF interpreter to indicate whether libc 82 - * should enable secure mode. 83 - * @bprm contains the linux_binprm structure. 84 * 85 * Security hooks for filesystem operations. 86 * ··· 1386 1387 int (*bprm_set_creds)(struct linux_binprm *bprm); 1388 int (*bprm_check_security)(struct linux_binprm *bprm); 1389 - int (*bprm_secureexec)(struct linux_binprm *bprm); 1390 void (*bprm_committing_creds)(struct linux_binprm *bprm); 1391 void (*bprm_committed_creds)(struct linux_binprm *bprm); 1392 ··· 1707 struct list_head vm_enough_memory; 1708 struct list_head bprm_set_creds; 1709 struct list_head bprm_check_security; 1710 - struct list_head bprm_secureexec; 1711 struct list_head bprm_committing_creds; 1712 struct list_head bprm_committed_creds; 1713 struct list_head sb_alloc_security;
··· 43 * interpreters. The hook can tell whether it has already been called by 44 * checking to see if @bprm->security is non-NULL. If so, then the hook 45 * may decide either to retain the security information saved earlier or 46 + * to replace it. The hook must set @bprm->secureexec to 1 if a "secure 47 + * exec" has happened as a result of this hook call. The flag is used to 48 + * indicate the need for a sanitized execution environment, and is also 49 + * passed in the ELF auxiliary table on the initial stack to indicate 50 + * whether libc should enable secure mode. 51 * @bprm contains the linux_binprm structure. 52 * Return 0 if the hook is successful and permission is granted. 53 * @bprm_check_security: ··· 71 * linux_binprm structure. This hook is a good place to perform state 72 * changes on the process such as clearing out non-inheritable signal 73 * state. This is called immediately after commit_creds(). 74 * 75 * Security hooks for filesystem operations. 76 * ··· 1388 1389 int (*bprm_set_creds)(struct linux_binprm *bprm); 1390 int (*bprm_check_security)(struct linux_binprm *bprm); 1391 void (*bprm_committing_creds)(struct linux_binprm *bprm); 1392 void (*bprm_committed_creds)(struct linux_binprm *bprm); 1393 ··· 1710 struct list_head vm_enough_memory; 1711 struct list_head bprm_set_creds; 1712 struct list_head bprm_check_security; 1713 struct list_head bprm_committing_creds; 1714 struct list_head bprm_committed_creds; 1715 struct list_head sb_alloc_security;
-7
include/linux/security.h
··· 85 const kernel_cap_t *inheritable, 86 const kernel_cap_t *permitted); 87 extern int cap_bprm_set_creds(struct linux_binprm *bprm); 88 - extern int cap_bprm_secureexec(struct linux_binprm *bprm); 89 extern int cap_inode_setxattr(struct dentry *dentry, const char *name, 90 const void *value, size_t size, int flags); 91 extern int cap_inode_removexattr(struct dentry *dentry, const char *name); ··· 231 int security_bprm_check(struct linux_binprm *bprm); 232 void security_bprm_committing_creds(struct linux_binprm *bprm); 233 void security_bprm_committed_creds(struct linux_binprm *bprm); 234 - int security_bprm_secureexec(struct linux_binprm *bprm); 235 int security_sb_alloc(struct super_block *sb); 236 void security_sb_free(struct super_block *sb); 237 int security_sb_copy_data(char *orig, char *copy); ··· 537 538 static inline void security_bprm_committed_creds(struct linux_binprm *bprm) 539 { 540 - } 541 - 542 - static inline int security_bprm_secureexec(struct linux_binprm *bprm) 543 - { 544 - return cap_bprm_secureexec(bprm); 545 } 546 547 static inline int security_sb_alloc(struct super_block *sb)
··· 85 const kernel_cap_t *inheritable, 86 const kernel_cap_t *permitted); 87 extern int cap_bprm_set_creds(struct linux_binprm *bprm); 88 extern int cap_inode_setxattr(struct dentry *dentry, const char *name, 89 const void *value, size_t size, int flags); 90 extern int cap_inode_removexattr(struct dentry *dentry, const char *name); ··· 232 int security_bprm_check(struct linux_binprm *bprm); 233 void security_bprm_committing_creds(struct linux_binprm *bprm); 234 void security_bprm_committed_creds(struct linux_binprm *bprm); 235 int security_sb_alloc(struct super_block *sb); 236 void security_sb_free(struct super_block *sb); 237 int security_sb_copy_data(char *orig, char *copy); ··· 539 540 static inline void security_bprm_committed_creds(struct linux_binprm *bprm) 541 { 542 } 543 544 static inline int security_sb_alloc(struct super_block *sb)
+2 -19
security/apparmor/domain.c
··· 758 file_inode(bprm->file)->i_mode 759 }; 760 761 - if (bprm->cred_prepared) 762 return 0; 763 764 ctx = cred_ctx(bprm->cred); ··· 807 aa_label_printk(new, GFP_ATOMIC); 808 dbg_printk("\n"); 809 } 810 - bprm->unsafe |= AA_SECURE_X_NEEDED; 811 } 812 813 if (label->proxy != new->proxy) { ··· 841 error)); 842 aa_put_label(new); 843 goto done; 844 - } 845 - 846 - /** 847 - * apparmor_bprm_secureexec - determine if secureexec is needed 848 - * @bprm: binprm for exec (NOT NULL) 849 - * 850 - * Returns: %1 if secureexec is needed else %0 851 - */ 852 - int apparmor_bprm_secureexec(struct linux_binprm *bprm) 853 - { 854 - /* the decision to use secure exec is computed in set_creds 855 - * and stored in bprm->unsafe. 856 - */ 857 - if (bprm->unsafe & AA_SECURE_X_NEEDED) 858 - return 1; 859 - 860 - return 0; 861 } 862 863 /*
··· 758 file_inode(bprm->file)->i_mode 759 }; 760 761 + if (bprm->called_set_creds) 762 return 0; 763 764 ctx = cred_ctx(bprm->cred); ··· 807 aa_label_printk(new, GFP_ATOMIC); 808 dbg_printk("\n"); 809 } 810 + bprm->secureexec = 1; 811 } 812 813 if (label->proxy != new->proxy) { ··· 841 error)); 842 aa_put_label(new); 843 goto done; 844 } 845 846 /*
-1
security/apparmor/include/domain.h
··· 30 #define AA_CHANGE_STACK 8 31 32 int apparmor_bprm_set_creds(struct linux_binprm *bprm); 33 - int apparmor_bprm_secureexec(struct linux_binprm *bprm); 34 35 void aa_free_domain_entries(struct aa_domain *domain); 36 int aa_change_hat(const char *hats[], int count, u64 token, int flags);
··· 30 #define AA_CHANGE_STACK 8 31 32 int apparmor_bprm_set_creds(struct linux_binprm *bprm); 33 34 void aa_free_domain_entries(struct aa_domain *domain); 35 int aa_change_hat(const char *hats[], int count, u64 token, int flags);
-3
security/apparmor/include/file.h
··· 101 #define AA_X_INHERIT 0x4000 102 #define AA_X_UNCONFINED 0x8000 103 104 - /* AA_SECURE_X_NEEDED - is passed in the bprm->unsafe field */ 105 - #define AA_SECURE_X_NEEDED 0x8000 106 - 107 /* need to make conditional which ones are being set */ 108 struct path_cond { 109 kuid_t uid;
··· 101 #define AA_X_INHERIT 0x4000 102 #define AA_X_UNCONFINED 0x8000 103 104 /* need to make conditional which ones are being set */ 105 struct path_cond { 106 kuid_t uid;
-1
security/apparmor/lsm.c
··· 694 LSM_HOOK_INIT(bprm_set_creds, apparmor_bprm_set_creds), 695 LSM_HOOK_INIT(bprm_committing_creds, apparmor_bprm_committing_creds), 696 LSM_HOOK_INIT(bprm_committed_creds, apparmor_bprm_committed_creds), 697 - LSM_HOOK_INIT(bprm_secureexec, apparmor_bprm_secureexec), 698 699 LSM_HOOK_INIT(task_setrlimit, apparmor_task_setrlimit), 700 };
··· 694 LSM_HOOK_INIT(bprm_set_creds, apparmor_bprm_set_creds), 695 LSM_HOOK_INIT(bprm_committing_creds, apparmor_bprm_committing_creds), 696 LSM_HOOK_INIT(bprm_committed_creds, apparmor_bprm_committed_creds), 697 698 LSM_HOOK_INIT(task_setrlimit, apparmor_task_setrlimit), 699 };
+11 -39
security/commoncap.c
··· 285 return 0; 286 } 287 288 - /* 289 - * Clear proposed capability sets for execve(). 290 - */ 291 - static inline void bprm_clear_caps(struct linux_binprm *bprm) 292 - { 293 - cap_clear(bprm->cred->cap_permitted); 294 - bprm->cap_effective = false; 295 - } 296 - 297 /** 298 * cap_inode_need_killpriv - Determine if inode change affects privileges 299 * @dentry: The inode/dentry in being changed with change marked ATTR_KILL_PRIV ··· 434 int rc = 0; 435 struct cpu_vfs_cap_data vcaps; 436 437 - bprm_clear_caps(bprm); 438 439 if (!file_caps_enabled) 440 return 0; ··· 467 468 out: 469 if (rc) 470 - bprm_clear_caps(bprm); 471 472 return rc; 473 } ··· 576 if (WARN_ON(!cap_ambient_invariant_ok(new))) 577 return -EPERM; 578 579 - bprm->cap_effective = effective; 580 - 581 /* 582 * Audit candidate if current->cap_effective is set 583 * ··· 603 if (WARN_ON(!cap_ambient_invariant_ok(new))) 604 return -EPERM; 605 606 - return 0; 607 - } 608 - 609 - /** 610 - * cap_bprm_secureexec - Determine whether a secure execution is required 611 - * @bprm: The execution parameters 612 - * 613 - * Determine whether a secure execution is required, return 1 if it is, and 0 614 - * if it is not. 615 - * 616 - * The credentials have been committed by this point, and so are no longer 617 - * available through @bprm->cred. 618 - */ 619 - int cap_bprm_secureexec(struct linux_binprm *bprm) 620 - { 621 - const struct cred *cred = current_cred(); 622 - kuid_t root_uid = make_kuid(cred->user_ns, 0); 623 - 624 - if (!uid_eq(cred->uid, root_uid)) { 625 - if (bprm->cap_effective) 626 - return 1; 627 - if (!cap_issubset(cred->cap_permitted, cred->cap_ambient)) 628 - return 1; 629 } 630 631 - return (!uid_eq(cred->euid, cred->uid) || 632 - !gid_eq(cred->egid, cred->gid)); 633 } 634 635 /** ··· 1052 LSM_HOOK_INIT(capget, cap_capget), 1053 LSM_HOOK_INIT(capset, cap_capset), 1054 LSM_HOOK_INIT(bprm_set_creds, cap_bprm_set_creds), 1055 - LSM_HOOK_INIT(bprm_secureexec, cap_bprm_secureexec), 1056 LSM_HOOK_INIT(inode_need_killpriv, cap_inode_need_killpriv), 1057 LSM_HOOK_INIT(inode_killpriv, cap_inode_killpriv), 1058 LSM_HOOK_INIT(mmap_addr, cap_mmap_addr),
··· 285 return 0; 286 } 287 288 /** 289 * cap_inode_need_killpriv - Determine if inode change affects privileges 290 * @dentry: The inode/dentry in being changed with change marked ATTR_KILL_PRIV ··· 443 int rc = 0; 444 struct cpu_vfs_cap_data vcaps; 445 446 + cap_clear(bprm->cred->cap_permitted); 447 448 if (!file_caps_enabled) 449 return 0; ··· 476 477 out: 478 if (rc) 479 + cap_clear(bprm->cred->cap_permitted); 480 481 return rc; 482 } ··· 585 if (WARN_ON(!cap_ambient_invariant_ok(new))) 586 return -EPERM; 587 588 /* 589 * Audit candidate if current->cap_effective is set 590 * ··· 614 if (WARN_ON(!cap_ambient_invariant_ok(new))) 615 return -EPERM; 616 617 + /* Check for privilege-elevated exec. */ 618 + bprm->cap_elevated = 0; 619 + if (is_setid) { 620 + bprm->cap_elevated = 1; 621 + } else if (!uid_eq(new->uid, root_uid)) { 622 + if (effective || 623 + !cap_issubset(new->cap_permitted, new->cap_ambient)) 624 + bprm->cap_elevated = 1; 625 } 626 627 + return 0; 628 } 629 630 /** ··· 1079 LSM_HOOK_INIT(capget, cap_capget), 1080 LSM_HOOK_INIT(capset, cap_capset), 1081 LSM_HOOK_INIT(bprm_set_creds, cap_bprm_set_creds), 1082 LSM_HOOK_INIT(inode_need_killpriv, cap_inode_need_killpriv), 1083 LSM_HOOK_INIT(inode_killpriv, cap_inode_killpriv), 1084 LSM_HOOK_INIT(mmap_addr, cap_mmap_addr),
-5
security/security.c
··· 351 call_void_hook(bprm_committed_creds, bprm); 352 } 353 354 - int security_bprm_secureexec(struct linux_binprm *bprm) 355 - { 356 - return call_int_hook(bprm_secureexec, 0, bprm); 357 - } 358 - 359 int security_sb_alloc(struct super_block *sb) 360 { 361 return call_int_hook(sb_alloc_security, 0, sb);
··· 351 call_void_hook(bprm_committed_creds, bprm); 352 } 353 354 int security_sb_alloc(struct super_block *sb) 355 { 356 return call_int_hook(sb_alloc_security, 0, sb);
+6 -20
security/selinux/hooks.c
··· 2356 2357 /* SELinux context only depends on initial program or script and not 2358 * the script interpreter */ 2359 - if (bprm->cred_prepared) 2360 return 0; 2361 2362 old_tsec = current_security(); ··· 2442 2443 /* Clear any possibly unsafe personality bits on exec: */ 2444 bprm->per_clear |= PER_CLEAR_ON_SETID; 2445 - } 2446 2447 - return 0; 2448 - } 2449 - 2450 - static int selinux_bprm_secureexec(struct linux_binprm *bprm) 2451 - { 2452 - const struct task_security_struct *tsec = current_security(); 2453 - u32 sid, osid; 2454 - int atsecure = 0; 2455 - 2456 - sid = tsec->sid; 2457 - osid = tsec->osid; 2458 - 2459 - if (osid != sid) { 2460 /* Enable secure mode for SIDs transitions unless 2461 the noatsecure permission is granted between 2462 the two SIDs, i.e. ahp returns 0. */ 2463 - atsecure = avc_has_perm(osid, sid, 2464 - SECCLASS_PROCESS, 2465 - PROCESS__NOATSECURE, NULL); 2466 } 2467 2468 - return !!atsecure; 2469 } 2470 2471 static int match_file(const void *p, struct file *file, unsigned fd) ··· 6253 LSM_HOOK_INIT(bprm_set_creds, selinux_bprm_set_creds), 6254 LSM_HOOK_INIT(bprm_committing_creds, selinux_bprm_committing_creds), 6255 LSM_HOOK_INIT(bprm_committed_creds, selinux_bprm_committed_creds), 6256 - LSM_HOOK_INIT(bprm_secureexec, selinux_bprm_secureexec), 6257 6258 LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security), 6259 LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security),
··· 2356 2357 /* SELinux context only depends on initial program or script and not 2358 * the script interpreter */ 2359 + if (bprm->called_set_creds) 2360 return 0; 2361 2362 old_tsec = current_security(); ··· 2442 2443 /* Clear any possibly unsafe personality bits on exec: */ 2444 bprm->per_clear |= PER_CLEAR_ON_SETID; 2445 2446 /* Enable secure mode for SIDs transitions unless 2447 the noatsecure permission is granted between 2448 the two SIDs, i.e. ahp returns 0. */ 2449 + rc = avc_has_perm(old_tsec->sid, new_tsec->sid, 2450 + SECCLASS_PROCESS, PROCESS__NOATSECURE, 2451 + NULL); 2452 + bprm->secureexec |= !!rc; 2453 } 2454 2455 + return 0; 2456 } 2457 2458 static int match_file(const void *p, struct file *file, unsigned fd) ··· 6266 LSM_HOOK_INIT(bprm_set_creds, selinux_bprm_set_creds), 6267 LSM_HOOK_INIT(bprm_committing_creds, selinux_bprm_committing_creds), 6268 LSM_HOOK_INIT(bprm_committed_creds, selinux_bprm_committed_creds), 6269 6270 LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security), 6271 LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security),
+3 -31
security/smack/smack_lsm.c
··· 917 struct superblock_smack *sbsp; 918 int rc; 919 920 - if (bprm->cred_prepared) 921 return 0; 922 923 isp = inode->i_security; ··· 950 bsp->smk_task = isp->smk_task; 951 bprm->per_clear |= PER_CLEAR_ON_SETID; 952 953 - return 0; 954 - } 955 - 956 - /** 957 - * smack_bprm_committing_creds - Prepare to install the new credentials 958 - * from bprm. 959 - * 960 - * @bprm: binprm for exec 961 - */ 962 - static void smack_bprm_committing_creds(struct linux_binprm *bprm) 963 - { 964 - struct task_smack *bsp = bprm->cred->security; 965 - 966 if (bsp->smk_task != bsp->smk_forked) 967 - current->pdeath_signal = 0; 968 - } 969 - 970 - /** 971 - * smack_bprm_secureexec - Return the decision to use secureexec. 972 - * @bprm: binprm for exec 973 - * 974 - * Returns 0 on success. 975 - */ 976 - static int smack_bprm_secureexec(struct linux_binprm *bprm) 977 - { 978 - struct task_smack *tsp = current_security(); 979 - 980 - if (tsp->smk_task != tsp->smk_forked) 981 - return 1; 982 983 return 0; 984 } ··· 4619 LSM_HOOK_INIT(sb_parse_opts_str, smack_parse_opts_str), 4620 4621 LSM_HOOK_INIT(bprm_set_creds, smack_bprm_set_creds), 4622 - LSM_HOOK_INIT(bprm_committing_creds, smack_bprm_committing_creds), 4623 - LSM_HOOK_INIT(bprm_secureexec, smack_bprm_secureexec), 4624 4625 LSM_HOOK_INIT(inode_alloc_security, smack_inode_alloc_security), 4626 LSM_HOOK_INIT(inode_free_security, smack_inode_free_security),
··· 917 struct superblock_smack *sbsp; 918 int rc; 919 920 + if (bprm->called_set_creds) 921 return 0; 922 923 isp = inode->i_security; ··· 950 bsp->smk_task = isp->smk_task; 951 bprm->per_clear |= PER_CLEAR_ON_SETID; 952 953 + /* Decide if this is a secure exec. */ 954 if (bsp->smk_task != bsp->smk_forked) 955 + bprm->secureexec = 1; 956 957 return 0; 958 } ··· 4645 LSM_HOOK_INIT(sb_parse_opts_str, smack_parse_opts_str), 4646 4647 LSM_HOOK_INIT(bprm_set_creds, smack_bprm_set_creds), 4648 4649 LSM_HOOK_INIT(inode_alloc_security, smack_inode_alloc_security), 4650 LSM_HOOK_INIT(inode_free_security, smack_inode_free_security),
+1 -1
security/tomoyo/tomoyo.c
··· 76 * Do only if this function is called for the first time of an execve 77 * operation. 78 */ 79 - if (bprm->cred_prepared) 80 return 0; 81 #ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER 82 /*
··· 76 * Do only if this function is called for the first time of an execve 77 * operation. 78 */ 79 + if (bprm->called_set_creds) 80 return 0; 81 #ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER 82 /*