diff options
Diffstat (limited to 'security/commoncap.c')
| -rw-r--r-- | security/commoncap.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/security/commoncap.c b/security/commoncap.c index beac0258c2a8..e3097c0a1311 100644 --- a/security/commoncap.c +++ b/security/commoncap.c | |||
| @@ -28,6 +28,28 @@ | |||
| 28 | #include <linux/prctl.h> | 28 | #include <linux/prctl.h> |
| 29 | #include <linux/securebits.h> | 29 | #include <linux/securebits.h> |
| 30 | 30 | ||
| 31 | /* | ||
| 32 | * If a non-root user executes a setuid-root binary in | ||
| 33 | * !secure(SECURE_NOROOT) mode, then we raise capabilities. | ||
| 34 | * However if fE is also set, then the intent is for only | ||
| 35 | * the file capabilities to be applied, and the setuid-root | ||
| 36 | * bit is left on either to change the uid (plausible) or | ||
| 37 | * to get full privilege on a kernel without file capabilities | ||
| 38 | * support. So in that case we do not raise capabilities. | ||
| 39 | * | ||
| 40 | * Warn if that happens, once per boot. | ||
| 41 | */ | ||
| 42 | static void warn_setuid_and_fcaps_mixed(char *fname) | ||
| 43 | { | ||
| 44 | static int warned; | ||
| 45 | if (!warned) { | ||
| 46 | printk(KERN_INFO "warning: `%s' has both setuid-root and" | ||
| 47 | " effective capabilities. Therefore not raising all" | ||
| 48 | " capabilities.\n", fname); | ||
| 49 | warned = 1; | ||
| 50 | } | ||
| 51 | } | ||
| 52 | |||
| 31 | int cap_netlink_send(struct sock *sk, struct sk_buff *skb) | 53 | int cap_netlink_send(struct sock *sk, struct sk_buff *skb) |
| 32 | { | 54 | { |
| 33 | NETLINK_CB(skb).eff_cap = current_cap(); | 55 | NETLINK_CB(skb).eff_cap = current_cap(); |
| @@ -464,6 +486,15 @@ int cap_bprm_set_creds(struct linux_binprm *bprm) | |||
| 464 | 486 | ||
| 465 | if (!issecure(SECURE_NOROOT)) { | 487 | if (!issecure(SECURE_NOROOT)) { |
| 466 | /* | 488 | /* |
| 489 | * If the legacy file capability is set, then don't set privs | ||
| 490 | * for a setuid root binary run by a non-root user. Do set it | ||
| 491 | * for a root user just to cause least surprise to an admin. | ||
| 492 | */ | ||
| 493 | if (effective && new->uid != 0 && new->euid == 0) { | ||
| 494 | warn_setuid_and_fcaps_mixed(bprm->filename); | ||
| 495 | goto skip; | ||
| 496 | } | ||
| 497 | /* | ||
| 467 | * To support inheritance of root-permissions and suid-root | 498 | * To support inheritance of root-permissions and suid-root |
| 468 | * executables under compatibility mode, we override the | 499 | * executables under compatibility mode, we override the |
| 469 | * capability sets for the file. | 500 | * capability sets for the file. |
| @@ -478,6 +509,7 @@ int cap_bprm_set_creds(struct linux_binprm *bprm) | |||
| 478 | if (new->euid == 0) | 509 | if (new->euid == 0) |
| 479 | effective = true; | 510 | effective = true; |
| 480 | } | 511 | } |
| 512 | skip: | ||
| 481 | 513 | ||
| 482 | /* Don't let someone trace a set[ug]id/setpcap binary with the revised | 514 | /* Don't let someone trace a set[ug]id/setpcap binary with the revised |
| 483 | * credentials unless they have the appropriate permit | 515 | * credentials unless they have the appropriate permit |
| @@ -952,3 +984,33 @@ int cap_vm_enough_memory(struct mm_struct *mm, long pages) | |||
| 952 | cap_sys_admin = 1; | 984 | cap_sys_admin = 1; |
| 953 | return __vm_enough_memory(mm, pages, cap_sys_admin); | 985 | return __vm_enough_memory(mm, pages, cap_sys_admin); |
| 954 | } | 986 | } |
| 987 | |||
| 988 | /* | ||
| 989 | * cap_file_mmap - check if able to map given addr | ||
| 990 | * @file: unused | ||
| 991 | * @reqprot: unused | ||
| 992 | * @prot: unused | ||
| 993 | * @flags: unused | ||
| 994 | * @addr: address attempting to be mapped | ||
| 995 | * @addr_only: unused | ||
| 996 | * | ||
| 997 | * If the process is attempting to map memory below mmap_min_addr they need | ||
| 998 | * CAP_SYS_RAWIO. The other parameters to this function are unused by the | ||
| 999 | * capability security module. Returns 0 if this mapping should be allowed | ||
| 1000 | * -EPERM if not. | ||
| 1001 | */ | ||
| 1002 | int cap_file_mmap(struct file *file, unsigned long reqprot, | ||
| 1003 | unsigned long prot, unsigned long flags, | ||
| 1004 | unsigned long addr, unsigned long addr_only) | ||
| 1005 | { | ||
| 1006 | int ret = 0; | ||
| 1007 | |||
| 1008 | if (addr < dac_mmap_min_addr) { | ||
| 1009 | ret = cap_capable(current, current_cred(), CAP_SYS_RAWIO, | ||
| 1010 | SECURITY_CAP_AUDIT); | ||
| 1011 | /* set PF_SUPERPRIV if it turns out we allow the low mmap */ | ||
| 1012 | if (ret == 0) | ||
| 1013 | current->flags |= PF_SUPERPRIV; | ||
| 1014 | } | ||
| 1015 | return ret; | ||
| 1016 | } | ||
