diff options
Diffstat (limited to 'security')
| -rw-r--r-- | security/apparmor/lsm.c | 8 | ||||
| -rw-r--r-- | security/capability.c | 1 | ||||
| -rw-r--r-- | security/commoncap.c | 24 | ||||
| -rw-r--r-- | security/security.c | 35 | ||||
| -rw-r--r-- | security/selinux/hooks.c | 44 |
5 files changed, 27 insertions, 85 deletions
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 68d50c54e431..97ce8fae49b3 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c | |||
| @@ -136,16 +136,16 @@ static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective, | |||
| 136 | return 0; | 136 | return 0; |
| 137 | } | 137 | } |
| 138 | 138 | ||
| 139 | static int apparmor_capable(struct task_struct *task, const struct cred *cred, | 139 | static int apparmor_capable(const struct cred *cred, struct user_namespace *ns, |
| 140 | struct user_namespace *ns, int cap, int audit) | 140 | int cap, int audit) |
| 141 | { | 141 | { |
| 142 | struct aa_profile *profile; | 142 | struct aa_profile *profile; |
| 143 | /* cap_capable returns 0 on success, else -EPERM */ | 143 | /* cap_capable returns 0 on success, else -EPERM */ |
| 144 | int error = cap_capable(task, cred, ns, cap, audit); | 144 | int error = cap_capable(cred, ns, cap, audit); |
| 145 | if (!error) { | 145 | if (!error) { |
| 146 | profile = aa_cred_profile(cred); | 146 | profile = aa_cred_profile(cred); |
| 147 | if (!unconfined(profile)) | 147 | if (!unconfined(profile)) |
| 148 | error = aa_capable(task, profile, cap, audit); | 148 | error = aa_capable(current, profile, cap, audit); |
| 149 | } | 149 | } |
| 150 | return error; | 150 | return error; |
| 151 | } | 151 | } |
diff --git a/security/capability.c b/security/capability.c index 3b5883b7179f..2f680eb02b59 100644 --- a/security/capability.c +++ b/security/capability.c | |||
| @@ -998,7 +998,6 @@ void __init security_fixup_ops(struct security_operations *ops) | |||
| 998 | set_to_cap_if_null(ops, sem_semctl); | 998 | set_to_cap_if_null(ops, sem_semctl); |
| 999 | set_to_cap_if_null(ops, sem_semop); | 999 | set_to_cap_if_null(ops, sem_semop); |
| 1000 | set_to_cap_if_null(ops, netlink_send); | 1000 | set_to_cap_if_null(ops, netlink_send); |
| 1001 | set_to_cap_if_null(ops, netlink_recv); | ||
| 1002 | set_to_cap_if_null(ops, d_instantiate); | 1001 | set_to_cap_if_null(ops, d_instantiate); |
| 1003 | set_to_cap_if_null(ops, getprocattr); | 1002 | set_to_cap_if_null(ops, getprocattr); |
| 1004 | set_to_cap_if_null(ops, setprocattr); | 1003 | set_to_cap_if_null(ops, setprocattr); |
diff --git a/security/commoncap.c b/security/commoncap.c index ee4f8486e5f5..7ce191ea29a0 100644 --- a/security/commoncap.c +++ b/security/commoncap.c | |||
| @@ -56,17 +56,8 @@ int cap_netlink_send(struct sock *sk, struct sk_buff *skb) | |||
| 56 | return 0; | 56 | return 0; |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | int cap_netlink_recv(struct sk_buff *skb, int cap) | ||
| 60 | { | ||
| 61 | if (!cap_raised(current_cap(), cap)) | ||
| 62 | return -EPERM; | ||
| 63 | return 0; | ||
| 64 | } | ||
| 65 | EXPORT_SYMBOL(cap_netlink_recv); | ||
| 66 | |||
| 67 | /** | 59 | /** |
| 68 | * cap_capable - Determine whether a task has a particular effective capability | 60 | * cap_capable - Determine whether a task has a particular effective capability |
| 69 | * @tsk: The task to query | ||
| 70 | * @cred: The credentials to use | 61 | * @cred: The credentials to use |
| 71 | * @ns: The user namespace in which we need the capability | 62 | * @ns: The user namespace in which we need the capability |
| 72 | * @cap: The capability to check for | 63 | * @cap: The capability to check for |
| @@ -80,8 +71,8 @@ EXPORT_SYMBOL(cap_netlink_recv); | |||
| 80 | * cap_has_capability() returns 0 when a task has a capability, but the | 71 | * cap_has_capability() returns 0 when a task has a capability, but the |
| 81 | * kernel's capable() and has_capability() returns 1 for this case. | 72 | * kernel's capable() and has_capability() returns 1 for this case. |
| 82 | */ | 73 | */ |
| 83 | int cap_capable(struct task_struct *tsk, const struct cred *cred, | 74 | int cap_capable(const struct cred *cred, struct user_namespace *targ_ns, |
| 84 | struct user_namespace *targ_ns, int cap, int audit) | 75 | int cap, int audit) |
| 85 | { | 76 | { |
| 86 | for (;;) { | 77 | for (;;) { |
| 87 | /* The creator of the user namespace has all caps. */ | 78 | /* The creator of the user namespace has all caps. */ |
| @@ -222,9 +213,8 @@ static inline int cap_inh_is_capped(void) | |||
| 222 | /* they are so limited unless the current task has the CAP_SETPCAP | 213 | /* they are so limited unless the current task has the CAP_SETPCAP |
| 223 | * capability | 214 | * capability |
| 224 | */ | 215 | */ |
| 225 | if (cap_capable(current, current_cred(), | 216 | if (cap_capable(current_cred(), current_cred()->user->user_ns, |
| 226 | current_cred()->user->user_ns, CAP_SETPCAP, | 217 | CAP_SETPCAP, SECURITY_CAP_AUDIT) == 0) |
| 227 | SECURITY_CAP_AUDIT) == 0) | ||
| 228 | return 0; | 218 | return 0; |
| 229 | return 1; | 219 | return 1; |
| 230 | } | 220 | } |
| @@ -874,7 +864,7 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, | |||
| 874 | & (new->securebits ^ arg2)) /*[1]*/ | 864 | & (new->securebits ^ arg2)) /*[1]*/ |
| 875 | || ((new->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/ | 865 | || ((new->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/ |
| 876 | || (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/ | 866 | || (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/ |
| 877 | || (cap_capable(current, current_cred(), | 867 | || (cap_capable(current_cred(), |
| 878 | current_cred()->user->user_ns, CAP_SETPCAP, | 868 | current_cred()->user->user_ns, CAP_SETPCAP, |
| 879 | SECURITY_CAP_AUDIT) != 0) /*[4]*/ | 869 | SECURITY_CAP_AUDIT) != 0) /*[4]*/ |
| 880 | /* | 870 | /* |
| @@ -940,7 +930,7 @@ int cap_vm_enough_memory(struct mm_struct *mm, long pages) | |||
| 940 | { | 930 | { |
| 941 | int cap_sys_admin = 0; | 931 | int cap_sys_admin = 0; |
| 942 | 932 | ||
| 943 | if (cap_capable(current, current_cred(), &init_user_ns, CAP_SYS_ADMIN, | 933 | if (cap_capable(current_cred(), &init_user_ns, CAP_SYS_ADMIN, |
| 944 | SECURITY_CAP_NOAUDIT) == 0) | 934 | SECURITY_CAP_NOAUDIT) == 0) |
| 945 | cap_sys_admin = 1; | 935 | cap_sys_admin = 1; |
| 946 | return __vm_enough_memory(mm, pages, cap_sys_admin); | 936 | return __vm_enough_memory(mm, pages, cap_sys_admin); |
| @@ -967,7 +957,7 @@ int cap_file_mmap(struct file *file, unsigned long reqprot, | |||
| 967 | int ret = 0; | 957 | int ret = 0; |
| 968 | 958 | ||
| 969 | if (addr < dac_mmap_min_addr) { | 959 | if (addr < dac_mmap_min_addr) { |
| 970 | ret = cap_capable(current, current_cred(), &init_user_ns, CAP_SYS_RAWIO, | 960 | ret = cap_capable(current_cred(), &init_user_ns, CAP_SYS_RAWIO, |
| 971 | SECURITY_CAP_AUDIT); | 961 | SECURITY_CAP_AUDIT); |
| 972 | /* set PF_SUPERPRIV if it turns out we allow the low mmap */ | 962 | /* set PF_SUPERPRIV if it turns out we allow the low mmap */ |
| 973 | if (ret == 0) | 963 | if (ret == 0) |
diff --git a/security/security.c b/security/security.c index 214502c772ab..d7542493454d 100644 --- a/security/security.c +++ b/security/security.c | |||
| @@ -155,35 +155,16 @@ int security_capset(struct cred *new, const struct cred *old, | |||
| 155 | effective, inheritable, permitted); | 155 | effective, inheritable, permitted); |
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | int security_capable(struct user_namespace *ns, const struct cred *cred, | 158 | int security_capable(const struct cred *cred, struct user_namespace *ns, |
| 159 | int cap) | 159 | int cap) |
| 160 | { | 160 | { |
| 161 | return security_ops->capable(current, cred, ns, cap, | 161 | return security_ops->capable(cred, ns, cap, SECURITY_CAP_AUDIT); |
| 162 | SECURITY_CAP_AUDIT); | ||
| 163 | } | 162 | } |
| 164 | 163 | ||
| 165 | int security_real_capable(struct task_struct *tsk, struct user_namespace *ns, | 164 | int security_capable_noaudit(const struct cred *cred, struct user_namespace *ns, |
| 166 | int cap) | 165 | int cap) |
| 167 | { | 166 | { |
| 168 | const struct cred *cred; | 167 | return security_ops->capable(cred, ns, cap, SECURITY_CAP_NOAUDIT); |
| 169 | int ret; | ||
| 170 | |||
| 171 | cred = get_task_cred(tsk); | ||
| 172 | ret = security_ops->capable(tsk, cred, ns, cap, SECURITY_CAP_AUDIT); | ||
| 173 | put_cred(cred); | ||
| 174 | return ret; | ||
| 175 | } | ||
| 176 | |||
| 177 | int security_real_capable_noaudit(struct task_struct *tsk, | ||
| 178 | struct user_namespace *ns, int cap) | ||
| 179 | { | ||
| 180 | const struct cred *cred; | ||
| 181 | int ret; | ||
| 182 | |||
| 183 | cred = get_task_cred(tsk); | ||
| 184 | ret = security_ops->capable(tsk, cred, ns, cap, SECURITY_CAP_NOAUDIT); | ||
| 185 | put_cred(cred); | ||
| 186 | return ret; | ||
| 187 | } | 168 | } |
| 188 | 169 | ||
| 189 | int security_quotactl(int cmds, int type, int id, struct super_block *sb) | 170 | int security_quotactl(int cmds, int type, int id, struct super_block *sb) |
| @@ -994,12 +975,6 @@ int security_netlink_send(struct sock *sk, struct sk_buff *skb) | |||
| 994 | return security_ops->netlink_send(sk, skb); | 975 | return security_ops->netlink_send(sk, skb); |
| 995 | } | 976 | } |
| 996 | 977 | ||
| 997 | int security_netlink_recv(struct sk_buff *skb, int cap) | ||
| 998 | { | ||
| 999 | return security_ops->netlink_recv(skb, cap); | ||
| 1000 | } | ||
| 1001 | EXPORT_SYMBOL(security_netlink_recv); | ||
| 1002 | |||
| 1003 | int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) | 978 | int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) |
| 1004 | { | 979 | { |
| 1005 | return security_ops->secid_to_secctx(secid, secdata, seclen); | 980 | return security_ops->secid_to_secctx(secid, secdata, seclen); |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 7cd4c3affac8..6a3683e28426 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -1415,8 +1415,7 @@ static int current_has_perm(const struct task_struct *tsk, | |||
| 1415 | #endif | 1415 | #endif |
| 1416 | 1416 | ||
| 1417 | /* Check whether a task is allowed to use a capability. */ | 1417 | /* Check whether a task is allowed to use a capability. */ |
| 1418 | static int task_has_capability(struct task_struct *tsk, | 1418 | static int cred_has_capability(const struct cred *cred, |
| 1419 | const struct cred *cred, | ||
| 1420 | int cap, int audit) | 1419 | int cap, int audit) |
| 1421 | { | 1420 | { |
| 1422 | struct common_audit_data ad; | 1421 | struct common_audit_data ad; |
| @@ -1427,7 +1426,7 @@ static int task_has_capability(struct task_struct *tsk, | |||
| 1427 | int rc; | 1426 | int rc; |
| 1428 | 1427 | ||
| 1429 | COMMON_AUDIT_DATA_INIT(&ad, CAP); | 1428 | COMMON_AUDIT_DATA_INIT(&ad, CAP); |
| 1430 | ad.tsk = tsk; | 1429 | ad.tsk = current; |
| 1431 | ad.u.cap = cap; | 1430 | ad.u.cap = cap; |
| 1432 | 1431 | ||
| 1433 | switch (CAP_TO_INDEX(cap)) { | 1432 | switch (CAP_TO_INDEX(cap)) { |
| @@ -1811,7 +1810,7 @@ static int selinux_ptrace_access_check(struct task_struct *child, | |||
| 1811 | if (rc) | 1810 | if (rc) |
| 1812 | return rc; | 1811 | return rc; |
| 1813 | 1812 | ||
| 1814 | if (mode == PTRACE_MODE_READ) { | 1813 | if (mode & PTRACE_MODE_READ) { |
| 1815 | u32 sid = current_sid(); | 1814 | u32 sid = current_sid(); |
| 1816 | u32 csid = task_sid(child); | 1815 | u32 csid = task_sid(child); |
| 1817 | return avc_has_perm(sid, csid, SECCLASS_FILE, FILE__READ, NULL); | 1816 | return avc_has_perm(sid, csid, SECCLASS_FILE, FILE__READ, NULL); |
| @@ -1868,16 +1867,16 @@ static int selinux_capset(struct cred *new, const struct cred *old, | |||
| 1868 | * the CAP_SETUID and CAP_SETGID capabilities using the capable hook. | 1867 | * the CAP_SETUID and CAP_SETGID capabilities using the capable hook. |
| 1869 | */ | 1868 | */ |
| 1870 | 1869 | ||
| 1871 | static int selinux_capable(struct task_struct *tsk, const struct cred *cred, | 1870 | static int selinux_capable(const struct cred *cred, struct user_namespace *ns, |
| 1872 | struct user_namespace *ns, int cap, int audit) | 1871 | int cap, int audit) |
| 1873 | { | 1872 | { |
| 1874 | int rc; | 1873 | int rc; |
| 1875 | 1874 | ||
| 1876 | rc = cap_capable(tsk, cred, ns, cap, audit); | 1875 | rc = cap_capable(cred, ns, cap, audit); |
| 1877 | if (rc) | 1876 | if (rc) |
| 1878 | return rc; | 1877 | return rc; |
| 1879 | 1878 | ||
| 1880 | return task_has_capability(tsk, cred, cap, audit); | 1879 | return cred_has_capability(cred, cap, audit); |
| 1881 | } | 1880 | } |
| 1882 | 1881 | ||
| 1883 | static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb) | 1882 | static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb) |
| @@ -1954,8 +1953,7 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages) | |||
| 1954 | { | 1953 | { |
| 1955 | int rc, cap_sys_admin = 0; | 1954 | int rc, cap_sys_admin = 0; |
| 1956 | 1955 | ||
| 1957 | rc = selinux_capable(current, current_cred(), | 1956 | rc = selinux_capable(current_cred(), &init_user_ns, CAP_SYS_ADMIN, |
| 1958 | &init_user_ns, CAP_SYS_ADMIN, | ||
| 1959 | SECURITY_CAP_NOAUDIT); | 1957 | SECURITY_CAP_NOAUDIT); |
| 1960 | if (rc == 0) | 1958 | if (rc == 0) |
| 1961 | cap_sys_admin = 1; | 1959 | cap_sys_admin = 1; |
| @@ -2859,8 +2857,7 @@ static int selinux_inode_getsecurity(const struct inode *inode, const char *name | |||
| 2859 | * and lack of permission just means that we fall back to the | 2857 | * and lack of permission just means that we fall back to the |
| 2860 | * in-core context value, not a denial. | 2858 | * in-core context value, not a denial. |
| 2861 | */ | 2859 | */ |
| 2862 | error = selinux_capable(current, current_cred(), | 2860 | error = selinux_capable(current_cred(), &init_user_ns, CAP_MAC_ADMIN, |
| 2863 | &init_user_ns, CAP_MAC_ADMIN, | ||
| 2864 | SECURITY_CAP_NOAUDIT); | 2861 | SECURITY_CAP_NOAUDIT); |
| 2865 | if (!error) | 2862 | if (!error) |
| 2866 | error = security_sid_to_context_force(isec->sid, &context, | 2863 | error = security_sid_to_context_force(isec->sid, &context, |
| @@ -2993,8 +2990,8 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd, | |||
| 2993 | 2990 | ||
| 2994 | case KDSKBENT: | 2991 | case KDSKBENT: |
| 2995 | case KDSKBSENT: | 2992 | case KDSKBSENT: |
| 2996 | error = task_has_capability(current, cred, CAP_SYS_TTY_CONFIG, | 2993 | error = cred_has_capability(cred, CAP_SYS_TTY_CONFIG, |
| 2997 | SECURITY_CAP_AUDIT); | 2994 | SECURITY_CAP_AUDIT); |
| 2998 | break; | 2995 | break; |
| 2999 | 2996 | ||
| 3000 | /* default case assumes that the command will go | 2997 | /* default case assumes that the command will go |
| @@ -4718,24 +4715,6 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) | |||
| 4718 | return selinux_nlmsg_perm(sk, skb); | 4715 | return selinux_nlmsg_perm(sk, skb); |
| 4719 | } | 4716 | } |
| 4720 | 4717 | ||
| 4721 | static int selinux_netlink_recv(struct sk_buff *skb, int capability) | ||
| 4722 | { | ||
| 4723 | int err; | ||
| 4724 | struct common_audit_data ad; | ||
| 4725 | u32 sid; | ||
| 4726 | |||
| 4727 | err = cap_netlink_recv(skb, capability); | ||
| 4728 | if (err) | ||
| 4729 | return err; | ||
| 4730 | |||
| 4731 | COMMON_AUDIT_DATA_INIT(&ad, CAP); | ||
| 4732 | ad.u.cap = capability; | ||
| 4733 | |||
| 4734 | security_task_getsecid(current, &sid); | ||
| 4735 | return avc_has_perm(sid, sid, SECCLASS_CAPABILITY, | ||
| 4736 | CAP_TO_MASK(capability), &ad); | ||
| 4737 | } | ||
| 4738 | |||
| 4739 | static int ipc_alloc_security(struct task_struct *task, | 4718 | static int ipc_alloc_security(struct task_struct *task, |
| 4740 | struct kern_ipc_perm *perm, | 4719 | struct kern_ipc_perm *perm, |
| 4741 | u16 sclass) | 4720 | u16 sclass) |
| @@ -5464,7 +5443,6 @@ static struct security_operations selinux_ops = { | |||
| 5464 | .vm_enough_memory = selinux_vm_enough_memory, | 5443 | .vm_enough_memory = selinux_vm_enough_memory, |
| 5465 | 5444 | ||
| 5466 | .netlink_send = selinux_netlink_send, | 5445 | .netlink_send = selinux_netlink_send, |
| 5467 | .netlink_recv = selinux_netlink_recv, | ||
| 5468 | 5446 | ||
| 5469 | .bprm_set_creds = selinux_bprm_set_creds, | 5447 | .bprm_set_creds = selinux_bprm_set_creds, |
| 5470 | .bprm_committing_creds = selinux_bprm_committing_creds, | 5448 | .bprm_committing_creds = selinux_bprm_committing_creds, |
