diff options
-rw-r--r-- | include/linux/security.h | 16 | ||||
-rw-r--r-- | security/apparmor/lsm.c | 8 | ||||
-rw-r--r-- | security/commoncap.c | 16 | ||||
-rw-r--r-- | security/security.c | 7 | ||||
-rw-r--r-- | security/selinux/hooks.c | 23 |
5 files changed, 31 insertions, 39 deletions
diff --git a/include/linux/security.h b/include/linux/security.h index ebd2a53a3d07..4921163b2752 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
@@ -53,8 +53,8 @@ struct user_namespace; | |||
53 | * These functions are in security/capability.c and are used | 53 | * These functions are in security/capability.c and are used |
54 | * as the default capabilities functions | 54 | * as the default capabilities functions |
55 | */ | 55 | */ |
56 | extern int cap_capable(struct task_struct *tsk, const struct cred *cred, | 56 | extern int cap_capable(const struct cred *cred, struct user_namespace *ns, |
57 | struct user_namespace *ns, int cap, int audit); | 57 | int cap, int audit); |
58 | extern int cap_settime(const struct timespec *ts, const struct timezone *tz); | 58 | extern int cap_settime(const struct timespec *ts, const struct timezone *tz); |
59 | extern int cap_ptrace_access_check(struct task_struct *child, unsigned int mode); | 59 | extern int cap_ptrace_access_check(struct task_struct *child, unsigned int mode); |
60 | extern int cap_ptrace_traceme(struct task_struct *parent); | 60 | extern int cap_ptrace_traceme(struct task_struct *parent); |
@@ -1261,7 +1261,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) | |||
1261 | * @capable: | 1261 | * @capable: |
1262 | * Check whether the @tsk process has the @cap capability in the indicated | 1262 | * Check whether the @tsk process has the @cap capability in the indicated |
1263 | * credentials. | 1263 | * credentials. |
1264 | * @tsk contains the task_struct for the process. | ||
1265 | * @cred contains the credentials to use. | 1264 | * @cred contains the credentials to use. |
1266 | * @ns contains the user namespace we want the capability in | 1265 | * @ns contains the user namespace we want the capability in |
1267 | * @cap contains the capability <include/linux/capability.h>. | 1266 | * @cap contains the capability <include/linux/capability.h>. |
@@ -1385,8 +1384,8 @@ struct security_operations { | |||
1385 | const kernel_cap_t *effective, | 1384 | const kernel_cap_t *effective, |
1386 | const kernel_cap_t *inheritable, | 1385 | const kernel_cap_t *inheritable, |
1387 | const kernel_cap_t *permitted); | 1386 | const kernel_cap_t *permitted); |
1388 | int (*capable) (struct task_struct *tsk, const struct cred *cred, | 1387 | int (*capable) (const struct cred *cred, struct user_namespace *ns, |
1389 | struct user_namespace *ns, int cap, int audit); | 1388 | int cap, int audit); |
1390 | int (*quotactl) (int cmds, int type, int id, struct super_block *sb); | 1389 | int (*quotactl) (int cmds, int type, int id, struct super_block *sb); |
1391 | int (*quota_on) (struct dentry *dentry); | 1390 | int (*quota_on) (struct dentry *dentry); |
1392 | int (*syslog) (int type); | 1391 | int (*syslog) (int type); |
@@ -1867,7 +1866,7 @@ static inline int security_capset(struct cred *new, | |||
1867 | static inline int security_capable(struct user_namespace *ns, | 1866 | static inline int security_capable(struct user_namespace *ns, |
1868 | const struct cred *cred, int cap) | 1867 | const struct cred *cred, int cap) |
1869 | { | 1868 | { |
1870 | return cap_capable(current, cred, ns, cap, SECURITY_CAP_AUDIT); | 1869 | return cap_capable(cred, ns, cap, SECURITY_CAP_AUDIT); |
1871 | } | 1870 | } |
1872 | 1871 | ||
1873 | static inline int security_real_capable(struct task_struct *tsk, struct user_namespace *ns, int cap) | 1872 | static inline int security_real_capable(struct task_struct *tsk, struct user_namespace *ns, int cap) |
@@ -1875,7 +1874,7 @@ static inline int security_real_capable(struct task_struct *tsk, struct user_nam | |||
1875 | int ret; | 1874 | int ret; |
1876 | 1875 | ||
1877 | rcu_read_lock(); | 1876 | rcu_read_lock(); |
1878 | ret = cap_capable(tsk, __task_cred(tsk), ns, cap, SECURITY_CAP_AUDIT); | 1877 | ret = cap_capable(__task_cred(tsk), ns, cap, SECURITY_CAP_AUDIT); |
1879 | rcu_read_unlock(); | 1878 | rcu_read_unlock(); |
1880 | return ret; | 1879 | return ret; |
1881 | } | 1880 | } |
@@ -1886,8 +1885,7 @@ int security_real_capable_noaudit(struct task_struct *tsk, struct user_namespace | |||
1886 | int ret; | 1885 | int ret; |
1887 | 1886 | ||
1888 | rcu_read_lock(); | 1887 | rcu_read_lock(); |
1889 | ret = cap_capable(tsk, __task_cred(tsk), ns, cap, | 1888 | ret = cap_capable(__task_cred(tsk), ns, cap, SECURITY_CAP_NOAUDIT); |
1890 | SECURITY_CAP_NOAUDIT); | ||
1891 | rcu_read_unlock(); | 1889 | rcu_read_unlock(); |
1892 | return ret; | 1890 | return ret; |
1893 | } | 1891 | } |
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 37832026e58a..ef4e2a8a33a5 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/commoncap.c b/security/commoncap.c index a93b3b733079..89f02ff66af9 100644 --- a/security/commoncap.c +++ b/security/commoncap.c | |||
@@ -66,7 +66,6 @@ EXPORT_SYMBOL(cap_netlink_recv); | |||
66 | 66 | ||
67 | /** | 67 | /** |
68 | * cap_capable - Determine whether a task has a particular effective capability | 68 | * cap_capable - Determine whether a task has a particular effective capability |
69 | * @tsk: The task to query | ||
70 | * @cred: The credentials to use | 69 | * @cred: The credentials to use |
71 | * @ns: The user namespace in which we need the capability | 70 | * @ns: The user namespace in which we need the capability |
72 | * @cap: The capability to check for | 71 | * @cap: The capability to check for |
@@ -80,8 +79,8 @@ EXPORT_SYMBOL(cap_netlink_recv); | |||
80 | * cap_has_capability() returns 0 when a task has a capability, but the | 79 | * 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. | 80 | * kernel's capable() and has_capability() returns 1 for this case. |
82 | */ | 81 | */ |
83 | int cap_capable(struct task_struct *tsk, const struct cred *cred, | 82 | int cap_capable(const struct cred *cred, struct user_namespace *targ_ns, |
84 | struct user_namespace *targ_ns, int cap, int audit) | 83 | int cap, int audit) |
85 | { | 84 | { |
86 | for (;;) { | 85 | for (;;) { |
87 | /* The creator of the user namespace has all caps. */ | 86 | /* The creator of the user namespace has all caps. */ |
@@ -222,9 +221,8 @@ static inline int cap_inh_is_capped(void) | |||
222 | /* they are so limited unless the current task has the CAP_SETPCAP | 221 | /* they are so limited unless the current task has the CAP_SETPCAP |
223 | * capability | 222 | * capability |
224 | */ | 223 | */ |
225 | if (cap_capable(current, current_cred(), | 224 | if (cap_capable(current_cred(), current_cred()->user->user_ns, |
226 | current_cred()->user->user_ns, CAP_SETPCAP, | 225 | CAP_SETPCAP, SECURITY_CAP_AUDIT) == 0) |
227 | SECURITY_CAP_AUDIT) == 0) | ||
228 | return 0; | 226 | return 0; |
229 | return 1; | 227 | return 1; |
230 | } | 228 | } |
@@ -870,7 +868,7 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, | |||
870 | & (new->securebits ^ arg2)) /*[1]*/ | 868 | & (new->securebits ^ arg2)) /*[1]*/ |
871 | || ((new->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/ | 869 | || ((new->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/ |
872 | || (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/ | 870 | || (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/ |
873 | || (cap_capable(current, current_cred(), | 871 | || (cap_capable(current_cred(), |
874 | current_cred()->user->user_ns, CAP_SETPCAP, | 872 | current_cred()->user->user_ns, CAP_SETPCAP, |
875 | SECURITY_CAP_AUDIT) != 0) /*[4]*/ | 873 | SECURITY_CAP_AUDIT) != 0) /*[4]*/ |
876 | /* | 874 | /* |
@@ -936,7 +934,7 @@ int cap_vm_enough_memory(struct mm_struct *mm, long pages) | |||
936 | { | 934 | { |
937 | int cap_sys_admin = 0; | 935 | int cap_sys_admin = 0; |
938 | 936 | ||
939 | if (cap_capable(current, current_cred(), &init_user_ns, CAP_SYS_ADMIN, | 937 | if (cap_capable(current_cred(), &init_user_ns, CAP_SYS_ADMIN, |
940 | SECURITY_CAP_NOAUDIT) == 0) | 938 | SECURITY_CAP_NOAUDIT) == 0) |
941 | cap_sys_admin = 1; | 939 | cap_sys_admin = 1; |
942 | return __vm_enough_memory(mm, pages, cap_sys_admin); | 940 | return __vm_enough_memory(mm, pages, cap_sys_admin); |
@@ -963,7 +961,7 @@ int cap_file_mmap(struct file *file, unsigned long reqprot, | |||
963 | int ret = 0; | 961 | int ret = 0; |
964 | 962 | ||
965 | if (addr < dac_mmap_min_addr) { | 963 | if (addr < dac_mmap_min_addr) { |
966 | ret = cap_capable(current, current_cred(), &init_user_ns, CAP_SYS_RAWIO, | 964 | ret = cap_capable(current_cred(), &init_user_ns, CAP_SYS_RAWIO, |
967 | SECURITY_CAP_AUDIT); | 965 | SECURITY_CAP_AUDIT); |
968 | /* set PF_SUPERPRIV if it turns out we allow the low mmap */ | 966 | /* set PF_SUPERPRIV if it turns out we allow the low mmap */ |
969 | if (ret == 0) | 967 | if (ret == 0) |
diff --git a/security/security.c b/security/security.c index d9e153390926..9ae68c64455e 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -157,8 +157,7 @@ int security_capset(struct cred *new, const struct cred *old, | |||
157 | int security_capable(struct user_namespace *ns, const struct cred *cred, | 157 | int security_capable(struct user_namespace *ns, const struct cred *cred, |
158 | int cap) | 158 | int cap) |
159 | { | 159 | { |
160 | return security_ops->capable(current, cred, ns, cap, | 160 | return security_ops->capable(cred, ns, cap, SECURITY_CAP_AUDIT); |
161 | SECURITY_CAP_AUDIT); | ||
162 | } | 161 | } |
163 | 162 | ||
164 | int security_real_capable(struct task_struct *tsk, struct user_namespace *ns, | 163 | int security_real_capable(struct task_struct *tsk, struct user_namespace *ns, |
@@ -168,7 +167,7 @@ int security_real_capable(struct task_struct *tsk, struct user_namespace *ns, | |||
168 | int ret; | 167 | int ret; |
169 | 168 | ||
170 | cred = get_task_cred(tsk); | 169 | cred = get_task_cred(tsk); |
171 | ret = security_ops->capable(tsk, cred, ns, cap, SECURITY_CAP_AUDIT); | 170 | ret = security_ops->capable(cred, ns, cap, SECURITY_CAP_AUDIT); |
172 | put_cred(cred); | 171 | put_cred(cred); |
173 | return ret; | 172 | return ret; |
174 | } | 173 | } |
@@ -180,7 +179,7 @@ int security_real_capable_noaudit(struct task_struct *tsk, | |||
180 | int ret; | 179 | int ret; |
181 | 180 | ||
182 | cred = get_task_cred(tsk); | 181 | cred = get_task_cred(tsk); |
183 | ret = security_ops->capable(tsk, cred, ns, cap, SECURITY_CAP_NOAUDIT); | 182 | ret = security_ops->capable(cred, ns, cap, SECURITY_CAP_NOAUDIT); |
184 | put_cred(cred); | 183 | put_cred(cred); |
185 | return ret; | 184 | return ret; |
186 | } | 185 | } |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index e545b9f67072..c9605c4a2e08 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -1414,8 +1414,7 @@ static int current_has_perm(const struct task_struct *tsk, | |||
1414 | #endif | 1414 | #endif |
1415 | 1415 | ||
1416 | /* Check whether a task is allowed to use a capability. */ | 1416 | /* Check whether a task is allowed to use a capability. */ |
1417 | static int task_has_capability(struct task_struct *tsk, | 1417 | static int cred_has_capability(const struct cred *cred, |
1418 | const struct cred *cred, | ||
1419 | int cap, int audit) | 1418 | int cap, int audit) |
1420 | { | 1419 | { |
1421 | struct common_audit_data ad; | 1420 | struct common_audit_data ad; |
@@ -1426,7 +1425,7 @@ static int task_has_capability(struct task_struct *tsk, | |||
1426 | int rc; | 1425 | int rc; |
1427 | 1426 | ||
1428 | COMMON_AUDIT_DATA_INIT(&ad, CAP); | 1427 | COMMON_AUDIT_DATA_INIT(&ad, CAP); |
1429 | ad.tsk = tsk; | 1428 | ad.tsk = current; |
1430 | ad.u.cap = cap; | 1429 | ad.u.cap = cap; |
1431 | 1430 | ||
1432 | switch (CAP_TO_INDEX(cap)) { | 1431 | switch (CAP_TO_INDEX(cap)) { |
@@ -1867,16 +1866,16 @@ static int selinux_capset(struct cred *new, const struct cred *old, | |||
1867 | * the CAP_SETUID and CAP_SETGID capabilities using the capable hook. | 1866 | * the CAP_SETUID and CAP_SETGID capabilities using the capable hook. |
1868 | */ | 1867 | */ |
1869 | 1868 | ||
1870 | static int selinux_capable(struct task_struct *tsk, const struct cred *cred, | 1869 | static int selinux_capable(const struct cred *cred, struct user_namespace *ns, |
1871 | struct user_namespace *ns, int cap, int audit) | 1870 | int cap, int audit) |
1872 | { | 1871 | { |
1873 | int rc; | 1872 | int rc; |
1874 | 1873 | ||
1875 | rc = cap_capable(tsk, cred, ns, cap, audit); | 1874 | rc = cap_capable(cred, ns, cap, audit); |
1876 | if (rc) | 1875 | if (rc) |
1877 | return rc; | 1876 | return rc; |
1878 | 1877 | ||
1879 | return task_has_capability(tsk, cred, cap, audit); | 1878 | return cred_has_capability(cred, cap, audit); |
1880 | } | 1879 | } |
1881 | 1880 | ||
1882 | static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb) | 1881 | static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb) |
@@ -1953,8 +1952,7 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages) | |||
1953 | { | 1952 | { |
1954 | int rc, cap_sys_admin = 0; | 1953 | int rc, cap_sys_admin = 0; |
1955 | 1954 | ||
1956 | rc = selinux_capable(current, current_cred(), | 1955 | rc = selinux_capable(current_cred(), &init_user_ns, CAP_SYS_ADMIN, |
1957 | &init_user_ns, CAP_SYS_ADMIN, | ||
1958 | SECURITY_CAP_NOAUDIT); | 1956 | SECURITY_CAP_NOAUDIT); |
1959 | if (rc == 0) | 1957 | if (rc == 0) |
1960 | cap_sys_admin = 1; | 1958 | cap_sys_admin = 1; |
@@ -2858,8 +2856,7 @@ static int selinux_inode_getsecurity(const struct inode *inode, const char *name | |||
2858 | * and lack of permission just means that we fall back to the | 2856 | * and lack of permission just means that we fall back to the |
2859 | * in-core context value, not a denial. | 2857 | * in-core context value, not a denial. |
2860 | */ | 2858 | */ |
2861 | error = selinux_capable(current, current_cred(), | 2859 | error = selinux_capable(current_cred(), &init_user_ns, CAP_MAC_ADMIN, |
2862 | &init_user_ns, CAP_MAC_ADMIN, | ||
2863 | SECURITY_CAP_NOAUDIT); | 2860 | SECURITY_CAP_NOAUDIT); |
2864 | if (!error) | 2861 | if (!error) |
2865 | error = security_sid_to_context_force(isec->sid, &context, | 2862 | error = security_sid_to_context_force(isec->sid, &context, |
@@ -2992,8 +2989,8 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd, | |||
2992 | 2989 | ||
2993 | case KDSKBENT: | 2990 | case KDSKBENT: |
2994 | case KDSKBSENT: | 2991 | case KDSKBSENT: |
2995 | error = task_has_capability(current, cred, CAP_SYS_TTY_CONFIG, | 2992 | error = cred_has_capability(cred, CAP_SYS_TTY_CONFIG, |
2996 | SECURITY_CAP_AUDIT); | 2993 | SECURITY_CAP_AUDIT); |
2997 | break; | 2994 | break; |
2998 | 2995 | ||
2999 | /* default case assumes that the command will go | 2996 | /* default case assumes that the command will go |