diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-14 21:36:33 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-14 21:36:33 -0500 |
commit | c49c41a4134679cecb77362e7f6b59acb6320aa7 (patch) | |
tree | 45e690c036ca5846a48c8be67945d1d841b2d96d | |
parent | 892d208bcf79e4e1058707786a7b6d486697cd78 (diff) | |
parent | f423e5ba76e7e4a6fcb4836b4f072d1fdebba8b5 (diff) |
Merge branch 'for-linus' of git://selinuxproject.org/~jmorris/linux-security
* 'for-linus' of git://selinuxproject.org/~jmorris/linux-security:
capabilities: remove __cap_full_set definition
security: remove the security_netlink_recv hook as it is equivalent to capable()
ptrace: do not audit capability check when outputing /proc/pid/stat
capabilities: remove task_ns_* functions
capabitlies: ns_capable can use the cap helpers rather than lsm call
capabilities: style only - move capable below ns_capable
capabilites: introduce new has_ns_capabilities_noaudit
capabilities: call has_ns_capability from has_capability
capabilities: remove all _real_ interfaces
capabilities: introduce security_capable_noaudit
capabilities: reverse arguments to security_capable
capabilities: remove the task from capable LSM hook entirely
selinux: sparse fix: fix several warnings in the security server cod
selinux: sparse fix: fix warnings in netlink code
selinux: sparse fix: eliminate warnings for selinuxfs
selinux: sparse fix: declare selinux_disable() in security.h
selinux: sparse fix: move selinux_complete_init
selinux: sparse fix: make selinux_secmark_refcount static
SELinux: Fix RCU deref check warning in sel_netport_insert()
Manually fix up a semantic mis-merge wrt security_netlink_recv():
- the interface was removed in commit fd7784615248 ("security: remove
the security_netlink_recv hook as it is equivalent to capable()")
- a new user of it appeared in commit a38f7907b926 ("crypto: Add
userspace configuration API")
causing no automatic merge conflict, but Eric Paris pointed out the
issue.
-rw-r--r-- | crypto/crypto_user.c | 2 | ||||
-rw-r--r-- | drivers/pci/pci-sysfs.c | 2 | ||||
-rw-r--r-- | drivers/scsi/scsi_netlink.c | 2 | ||||
-rw-r--r-- | fs/proc/array.c | 2 | ||||
-rw-r--r-- | include/linux/capability.h | 4 | ||||
-rw-r--r-- | include/linux/cred.h | 6 | ||||
-rw-r--r-- | include/linux/ptrace.h | 5 | ||||
-rw-r--r-- | include/linux/security.h | 60 | ||||
-rw-r--r-- | kernel/audit.c | 4 | ||||
-rw-r--r-- | kernel/capability.c | 80 | ||||
-rw-r--r-- | kernel/ptrace.c | 14 | ||||
-rw-r--r-- | kernel/sched/core.c | 2 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 2 | ||||
-rw-r--r-- | net/decnet/netfilter/dn_rtmsg.c | 2 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_queue.c | 2 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6_queue.c | 2 | ||||
-rw-r--r-- | net/netfilter/nfnetlink.c | 2 | ||||
-rw-r--r-- | net/netlink/genetlink.c | 2 | ||||
-rw-r--r-- | net/xfrm/xfrm_user.c | 2 | ||||
-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 |
24 files changed, 120 insertions, 189 deletions
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c index 3ba6ef508869..16f8693cc147 100644 --- a/crypto/crypto_user.c +++ b/crypto/crypto_user.c | |||
@@ -382,7 +382,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
382 | type -= CRYPTO_MSG_BASE; | 382 | type -= CRYPTO_MSG_BASE; |
383 | link = &crypto_dispatch[type]; | 383 | link = &crypto_dispatch[type]; |
384 | 384 | ||
385 | if (security_netlink_recv(skb, CAP_NET_ADMIN)) | 385 | if (!capable(CAP_NET_ADMIN)) |
386 | return -EPERM; | 386 | return -EPERM; |
387 | 387 | ||
388 | if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) && | 388 | if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) && |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 106be0d08f81..a3cd8cad532a 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -432,7 +432,7 @@ pci_read_config(struct file *filp, struct kobject *kobj, | |||
432 | u8 *data = (u8*) buf; | 432 | u8 *data = (u8*) buf; |
433 | 433 | ||
434 | /* Several chips lock up trying to read undefined config space */ | 434 | /* Several chips lock up trying to read undefined config space */ |
435 | if (security_capable(&init_user_ns, filp->f_cred, CAP_SYS_ADMIN) == 0) { | 435 | if (security_capable(filp->f_cred, &init_user_ns, CAP_SYS_ADMIN) == 0) { |
436 | size = dev->cfg_size; | 436 | size = dev->cfg_size; |
437 | } else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { | 437 | } else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { |
438 | size = 128; | 438 | size = 128; |
diff --git a/drivers/scsi/scsi_netlink.c b/drivers/scsi/scsi_netlink.c index 44f76e8b58af..c77628afbf9f 100644 --- a/drivers/scsi/scsi_netlink.c +++ b/drivers/scsi/scsi_netlink.c | |||
@@ -112,7 +112,7 @@ scsi_nl_rcv_msg(struct sk_buff *skb) | |||
112 | goto next_msg; | 112 | goto next_msg; |
113 | } | 113 | } |
114 | 114 | ||
115 | if (security_netlink_recv(skb, CAP_SYS_ADMIN)) { | 115 | if (!capable(CAP_SYS_ADMIN)) { |
116 | err = -EPERM; | 116 | err = -EPERM; |
117 | goto next_msg; | 117 | goto next_msg; |
118 | } | 118 | } |
diff --git a/fs/proc/array.c b/fs/proc/array.c index 9252ee3b71e3..c602b8d20f06 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c | |||
@@ -380,7 +380,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, | |||
380 | 380 | ||
381 | state = *get_task_state(task); | 381 | state = *get_task_state(task); |
382 | vsize = eip = esp = 0; | 382 | vsize = eip = esp = 0; |
383 | permitted = ptrace_may_access(task, PTRACE_MODE_READ); | 383 | permitted = ptrace_may_access(task, PTRACE_MODE_READ | PTRACE_MODE_NOAUDIT); |
384 | mm = get_task_mm(task); | 384 | mm = get_task_mm(task); |
385 | if (mm) { | 385 | if (mm) { |
386 | vsize = task_vsize(mm); | 386 | vsize = task_vsize(mm); |
diff --git a/include/linux/capability.h b/include/linux/capability.h index a63d13d84ad8..12d52dedb229 100644 --- a/include/linux/capability.h +++ b/include/linux/capability.h | |||
@@ -380,7 +380,6 @@ struct user_namespace; | |||
380 | struct user_namespace *current_user_ns(void); | 380 | struct user_namespace *current_user_ns(void); |
381 | 381 | ||
382 | extern const kernel_cap_t __cap_empty_set; | 382 | extern const kernel_cap_t __cap_empty_set; |
383 | extern const kernel_cap_t __cap_full_set; | ||
384 | extern const kernel_cap_t __cap_init_eff_set; | 383 | extern const kernel_cap_t __cap_init_eff_set; |
385 | 384 | ||
386 | /* | 385 | /* |
@@ -544,9 +543,10 @@ extern bool has_capability(struct task_struct *t, int cap); | |||
544 | extern bool has_ns_capability(struct task_struct *t, | 543 | extern bool has_ns_capability(struct task_struct *t, |
545 | struct user_namespace *ns, int cap); | 544 | struct user_namespace *ns, int cap); |
546 | extern bool has_capability_noaudit(struct task_struct *t, int cap); | 545 | extern bool has_capability_noaudit(struct task_struct *t, int cap); |
546 | extern bool has_ns_capability_noaudit(struct task_struct *t, | ||
547 | struct user_namespace *ns, int cap); | ||
547 | extern bool capable(int cap); | 548 | extern bool capable(int cap); |
548 | extern bool ns_capable(struct user_namespace *ns, int cap); | 549 | extern bool ns_capable(struct user_namespace *ns, int cap); |
549 | extern bool task_ns_capable(struct task_struct *t, int cap); | ||
550 | extern bool nsown_capable(int cap); | 550 | extern bool nsown_capable(int cap); |
551 | 551 | ||
552 | /* audit system wants to get cap info from files as well */ | 552 | /* audit system wants to get cap info from files as well */ |
diff --git a/include/linux/cred.h b/include/linux/cred.h index 40308969ed00..adadf71a7327 100644 --- a/include/linux/cred.h +++ b/include/linux/cred.h | |||
@@ -358,10 +358,12 @@ static inline void put_cred(const struct cred *_cred) | |||
358 | #define current_security() (current_cred_xxx(security)) | 358 | #define current_security() (current_cred_xxx(security)) |
359 | 359 | ||
360 | #ifdef CONFIG_USER_NS | 360 | #ifdef CONFIG_USER_NS |
361 | #define current_user_ns() (current_cred_xxx(user_ns)) | 361 | #define current_user_ns() (current_cred_xxx(user_ns)) |
362 | #define task_user_ns(task) (task_cred_xxx((task), user_ns)) | ||
362 | #else | 363 | #else |
363 | extern struct user_namespace init_user_ns; | 364 | extern struct user_namespace init_user_ns; |
364 | #define current_user_ns() (&init_user_ns) | 365 | #define current_user_ns() (&init_user_ns) |
366 | #define task_user_ns(task) (&init_user_ns) | ||
365 | #endif | 367 | #endif |
366 | 368 | ||
367 | 369 | ||
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index 800f113bea66..a27e56ca41a4 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h | |||
@@ -127,8 +127,9 @@ extern void __ptrace_link(struct task_struct *child, | |||
127 | struct task_struct *new_parent); | 127 | struct task_struct *new_parent); |
128 | extern void __ptrace_unlink(struct task_struct *child); | 128 | extern void __ptrace_unlink(struct task_struct *child); |
129 | extern void exit_ptrace(struct task_struct *tracer); | 129 | extern void exit_ptrace(struct task_struct *tracer); |
130 | #define PTRACE_MODE_READ 1 | 130 | #define PTRACE_MODE_READ 0x01 |
131 | #define PTRACE_MODE_ATTACH 2 | 131 | #define PTRACE_MODE_ATTACH 0x02 |
132 | #define PTRACE_MODE_NOAUDIT 0x04 | ||
132 | /* Returns 0 on success, -errno on denial. */ | 133 | /* Returns 0 on success, -errno on denial. */ |
133 | extern int __ptrace_may_access(struct task_struct *task, unsigned int mode); | 134 | extern int __ptrace_may_access(struct task_struct *task, unsigned int mode); |
134 | /* Returns true on success, false on denial. */ | 135 | /* Returns true on success, false on denial. */ |
diff --git a/include/linux/security.h b/include/linux/security.h index 0ccceb9b1046..83c18e8c846d 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
@@ -54,8 +54,8 @@ struct user_namespace; | |||
54 | * These functions are in security/capability.c and are used | 54 | * These functions are in security/capability.c and are used |
55 | * as the default capabilities functions | 55 | * as the default capabilities functions |
56 | */ | 56 | */ |
57 | extern int cap_capable(struct task_struct *tsk, const struct cred *cred, | 57 | extern int cap_capable(const struct cred *cred, struct user_namespace *ns, |
58 | struct user_namespace *ns, int cap, int audit); | 58 | int cap, int audit); |
59 | extern int cap_settime(const struct timespec *ts, const struct timezone *tz); | 59 | extern int cap_settime(const struct timespec *ts, const struct timezone *tz); |
60 | extern int cap_ptrace_access_check(struct task_struct *child, unsigned int mode); | 60 | extern int cap_ptrace_access_check(struct task_struct *child, unsigned int mode); |
61 | extern int cap_ptrace_traceme(struct task_struct *parent); | 61 | extern int cap_ptrace_traceme(struct task_struct *parent); |
@@ -96,7 +96,6 @@ struct xfrm_user_sec_ctx; | |||
96 | struct seq_file; | 96 | struct seq_file; |
97 | 97 | ||
98 | extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb); | 98 | extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb); |
99 | extern int cap_netlink_recv(struct sk_buff *skb, int cap); | ||
100 | 99 | ||
101 | void reset_security_ops(void); | 100 | void reset_security_ops(void); |
102 | 101 | ||
@@ -799,12 +798,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) | |||
799 | * @skb contains the sk_buff structure for the netlink message. | 798 | * @skb contains the sk_buff structure for the netlink message. |
800 | * Return 0 if the information was successfully saved and message | 799 | * Return 0 if the information was successfully saved and message |
801 | * is allowed to be transmitted. | 800 | * is allowed to be transmitted. |
802 | * @netlink_recv: | ||
803 | * Check permission before processing the received netlink message in | ||
804 | * @skb. | ||
805 | * @skb contains the sk_buff structure for the netlink message. | ||
806 | * @cap indicates the capability required | ||
807 | * Return 0 if permission is granted. | ||
808 | * | 801 | * |
809 | * Security hooks for Unix domain networking. | 802 | * Security hooks for Unix domain networking. |
810 | * | 803 | * |
@@ -1268,7 +1261,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) | |||
1268 | * @capable: | 1261 | * @capable: |
1269 | * 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 |
1270 | * credentials. | 1263 | * credentials. |
1271 | * @tsk contains the task_struct for the process. | ||
1272 | * @cred contains the credentials to use. | 1264 | * @cred contains the credentials to use. |
1273 | * @ns contains the user namespace we want the capability in | 1265 | * @ns contains the user namespace we want the capability in |
1274 | * @cap contains the capability <include/linux/capability.h>. | 1266 | * @cap contains the capability <include/linux/capability.h>. |
@@ -1392,8 +1384,8 @@ struct security_operations { | |||
1392 | const kernel_cap_t *effective, | 1384 | const kernel_cap_t *effective, |
1393 | const kernel_cap_t *inheritable, | 1385 | const kernel_cap_t *inheritable, |
1394 | const kernel_cap_t *permitted); | 1386 | const kernel_cap_t *permitted); |
1395 | int (*capable) (struct task_struct *tsk, const struct cred *cred, | 1387 | int (*capable) (const struct cred *cred, struct user_namespace *ns, |
1396 | struct user_namespace *ns, int cap, int audit); | 1388 | int cap, int audit); |
1397 | 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); |
1398 | int (*quota_on) (struct dentry *dentry); | 1390 | int (*quota_on) (struct dentry *dentry); |
1399 | int (*syslog) (int type); | 1391 | int (*syslog) (int type); |
@@ -1563,7 +1555,6 @@ struct security_operations { | |||
1563 | struct sembuf *sops, unsigned nsops, int alter); | 1555 | struct sembuf *sops, unsigned nsops, int alter); |
1564 | 1556 | ||
1565 | int (*netlink_send) (struct sock *sk, struct sk_buff *skb); | 1557 | int (*netlink_send) (struct sock *sk, struct sk_buff *skb); |
1566 | int (*netlink_recv) (struct sk_buff *skb, int cap); | ||
1567 | 1558 | ||
1568 | void (*d_instantiate) (struct dentry *dentry, struct inode *inode); | 1559 | void (*d_instantiate) (struct dentry *dentry, struct inode *inode); |
1569 | 1560 | ||
@@ -1675,12 +1666,10 @@ int security_capset(struct cred *new, const struct cred *old, | |||
1675 | const kernel_cap_t *effective, | 1666 | const kernel_cap_t *effective, |
1676 | const kernel_cap_t *inheritable, | 1667 | const kernel_cap_t *inheritable, |
1677 | const kernel_cap_t *permitted); | 1668 | const kernel_cap_t *permitted); |
1678 | int security_capable(struct user_namespace *ns, const struct cred *cred, | 1669 | int security_capable(const struct cred *cred, struct user_namespace *ns, |
1679 | int cap); | ||
1680 | int security_real_capable(struct task_struct *tsk, struct user_namespace *ns, | ||
1681 | int cap); | 1670 | int cap); |
1682 | int security_real_capable_noaudit(struct task_struct *tsk, | 1671 | int security_capable_noaudit(const struct cred *cred, struct user_namespace *ns, |
1683 | struct user_namespace *ns, int cap); | 1672 | int cap); |
1684 | int security_quotactl(int cmds, int type, int id, struct super_block *sb); | 1673 | int security_quotactl(int cmds, int type, int id, struct super_block *sb); |
1685 | int security_quota_on(struct dentry *dentry); | 1674 | int security_quota_on(struct dentry *dentry); |
1686 | int security_syslog(int type); | 1675 | int security_syslog(int type); |
@@ -1817,7 +1806,6 @@ void security_d_instantiate(struct dentry *dentry, struct inode *inode); | |||
1817 | int security_getprocattr(struct task_struct *p, char *name, char **value); | 1806 | int security_getprocattr(struct task_struct *p, char *name, char **value); |
1818 | int security_setprocattr(struct task_struct *p, char *name, void *value, size_t size); | 1807 | int security_setprocattr(struct task_struct *p, char *name, void *value, size_t size); |
1819 | int security_netlink_send(struct sock *sk, struct sk_buff *skb); | 1808 | int security_netlink_send(struct sock *sk, struct sk_buff *skb); |
1820 | int security_netlink_recv(struct sk_buff *skb, int cap); | ||
1821 | int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen); | 1809 | int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen); |
1822 | int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid); | 1810 | int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid); |
1823 | void security_release_secctx(char *secdata, u32 seclen); | 1811 | void security_release_secctx(char *secdata, u32 seclen); |
@@ -1875,32 +1863,15 @@ static inline int security_capset(struct cred *new, | |||
1875 | return cap_capset(new, old, effective, inheritable, permitted); | 1863 | return cap_capset(new, old, effective, inheritable, permitted); |
1876 | } | 1864 | } |
1877 | 1865 | ||
1878 | static inline int security_capable(struct user_namespace *ns, | 1866 | static inline int security_capable(const struct cred *cred, |
1879 | const struct cred *cred, int cap) | 1867 | struct user_namespace *ns, int cap) |
1880 | { | ||
1881 | return cap_capable(current, cred, ns, cap, SECURITY_CAP_AUDIT); | ||
1882 | } | ||
1883 | |||
1884 | static inline int security_real_capable(struct task_struct *tsk, struct user_namespace *ns, int cap) | ||
1885 | { | 1868 | { |
1886 | int ret; | 1869 | return cap_capable(cred, ns, cap, SECURITY_CAP_AUDIT); |
1887 | |||
1888 | rcu_read_lock(); | ||
1889 | ret = cap_capable(tsk, __task_cred(tsk), ns, cap, SECURITY_CAP_AUDIT); | ||
1890 | rcu_read_unlock(); | ||
1891 | return ret; | ||
1892 | } | 1870 | } |
1893 | 1871 | ||
1894 | static inline | 1872 | static inline int security_capable_noaudit(const struct cred *cred, |
1895 | int security_real_capable_noaudit(struct task_struct *tsk, struct user_namespace *ns, int cap) | 1873 | struct user_namespace *ns, int cap) { |
1896 | { | 1874 | return cap_capable(cred, ns, cap, SECURITY_CAP_NOAUDIT); |
1897 | int ret; | ||
1898 | |||
1899 | rcu_read_lock(); | ||
1900 | ret = cap_capable(tsk, __task_cred(tsk), ns, cap, | ||
1901 | SECURITY_CAP_NOAUDIT); | ||
1902 | rcu_read_unlock(); | ||
1903 | return ret; | ||
1904 | } | 1875 | } |
1905 | 1876 | ||
1906 | static inline int security_quotactl(int cmds, int type, int id, | 1877 | static inline int security_quotactl(int cmds, int type, int id, |
@@ -2517,11 +2488,6 @@ static inline int security_netlink_send(struct sock *sk, struct sk_buff *skb) | |||
2517 | return cap_netlink_send(sk, skb); | 2488 | return cap_netlink_send(sk, skb); |
2518 | } | 2489 | } |
2519 | 2490 | ||
2520 | static inline int security_netlink_recv(struct sk_buff *skb, int cap) | ||
2521 | { | ||
2522 | return cap_netlink_recv(skb, cap); | ||
2523 | } | ||
2524 | |||
2525 | static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) | 2491 | static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) |
2526 | { | 2492 | { |
2527 | return -EOPNOTSUPP; | 2493 | return -EOPNOTSUPP; |
diff --git a/kernel/audit.c b/kernel/audit.c index 2c1d6ab7106e..57e3f5107937 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
@@ -601,13 +601,13 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type) | |||
601 | case AUDIT_TTY_SET: | 601 | case AUDIT_TTY_SET: |
602 | case AUDIT_TRIM: | 602 | case AUDIT_TRIM: |
603 | case AUDIT_MAKE_EQUIV: | 603 | case AUDIT_MAKE_EQUIV: |
604 | if (security_netlink_recv(skb, CAP_AUDIT_CONTROL)) | 604 | if (!capable(CAP_AUDIT_CONTROL)) |
605 | err = -EPERM; | 605 | err = -EPERM; |
606 | break; | 606 | break; |
607 | case AUDIT_USER: | 607 | case AUDIT_USER: |
608 | case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG: | 608 | case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG: |
609 | case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2: | 609 | case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2: |
610 | if (security_netlink_recv(skb, CAP_AUDIT_WRITE)) | 610 | if (!capable(CAP_AUDIT_WRITE)) |
611 | err = -EPERM; | 611 | err = -EPERM; |
612 | break; | 612 | break; |
613 | default: /* bad msg */ | 613 | default: /* bad msg */ |
diff --git a/kernel/capability.c b/kernel/capability.c index b463871a4e69..0fcf1c14a297 100644 --- a/kernel/capability.c +++ b/kernel/capability.c | |||
@@ -287,74 +287,84 @@ error: | |||
287 | } | 287 | } |
288 | 288 | ||
289 | /** | 289 | /** |
290 | * has_capability - Does a task have a capability in init_user_ns | 290 | * has_ns_capability - Does a task have a capability in a specific user ns |
291 | * @t: The task in question | 291 | * @t: The task in question |
292 | * @ns: target user namespace | ||
292 | * @cap: The capability to be tested for | 293 | * @cap: The capability to be tested for |
293 | * | 294 | * |
294 | * Return true if the specified task has the given superior capability | 295 | * Return true if the specified task has the given superior capability |
295 | * currently in effect to the initial user namespace, false if not. | 296 | * currently in effect to the specified user namespace, false if not. |
296 | * | 297 | * |
297 | * Note that this does not set PF_SUPERPRIV on the task. | 298 | * Note that this does not set PF_SUPERPRIV on the task. |
298 | */ | 299 | */ |
299 | bool has_capability(struct task_struct *t, int cap) | 300 | bool has_ns_capability(struct task_struct *t, |
301 | struct user_namespace *ns, int cap) | ||
300 | { | 302 | { |
301 | int ret = security_real_capable(t, &init_user_ns, cap); | 303 | int ret; |
304 | |||
305 | rcu_read_lock(); | ||
306 | ret = security_capable(__task_cred(t), ns, cap); | ||
307 | rcu_read_unlock(); | ||
302 | 308 | ||
303 | return (ret == 0); | 309 | return (ret == 0); |
304 | } | 310 | } |
305 | 311 | ||
306 | /** | 312 | /** |
307 | * has_capability - Does a task have a capability in a specific user ns | 313 | * has_capability - Does a task have a capability in init_user_ns |
308 | * @t: The task in question | 314 | * @t: The task in question |
309 | * @ns: target user namespace | ||
310 | * @cap: The capability to be tested for | 315 | * @cap: The capability to be tested for |
311 | * | 316 | * |
312 | * Return true if the specified task has the given superior capability | 317 | * Return true if the specified task has the given superior capability |
313 | * currently in effect to the specified user namespace, false if not. | 318 | * currently in effect to the initial user namespace, false if not. |
314 | * | 319 | * |
315 | * Note that this does not set PF_SUPERPRIV on the task. | 320 | * Note that this does not set PF_SUPERPRIV on the task. |
316 | */ | 321 | */ |
317 | bool has_ns_capability(struct task_struct *t, | 322 | bool has_capability(struct task_struct *t, int cap) |
318 | struct user_namespace *ns, int cap) | ||
319 | { | 323 | { |
320 | int ret = security_real_capable(t, ns, cap); | 324 | return has_ns_capability(t, &init_user_ns, cap); |
321 | |||
322 | return (ret == 0); | ||
323 | } | 325 | } |
324 | 326 | ||
325 | /** | 327 | /** |
326 | * has_capability_noaudit - Does a task have a capability (unaudited) | 328 | * has_ns_capability_noaudit - Does a task have a capability (unaudited) |
329 | * in a specific user ns. | ||
327 | * @t: The task in question | 330 | * @t: The task in question |
331 | * @ns: target user namespace | ||
328 | * @cap: The capability to be tested for | 332 | * @cap: The capability to be tested for |
329 | * | 333 | * |
330 | * Return true if the specified task has the given superior capability | 334 | * Return true if the specified task has the given superior capability |
331 | * currently in effect to init_user_ns, false if not. Don't write an | 335 | * currently in effect to the specified user namespace, false if not. |
332 | * audit message for the check. | 336 | * Do not write an audit message for the check. |
333 | * | 337 | * |
334 | * Note that this does not set PF_SUPERPRIV on the task. | 338 | * Note that this does not set PF_SUPERPRIV on the task. |
335 | */ | 339 | */ |
336 | bool has_capability_noaudit(struct task_struct *t, int cap) | 340 | bool has_ns_capability_noaudit(struct task_struct *t, |
341 | struct user_namespace *ns, int cap) | ||
337 | { | 342 | { |
338 | int ret = security_real_capable_noaudit(t, &init_user_ns, cap); | 343 | int ret; |
344 | |||
345 | rcu_read_lock(); | ||
346 | ret = security_capable_noaudit(__task_cred(t), ns, cap); | ||
347 | rcu_read_unlock(); | ||
339 | 348 | ||
340 | return (ret == 0); | 349 | return (ret == 0); |
341 | } | 350 | } |
342 | 351 | ||
343 | /** | 352 | /** |
344 | * capable - Determine if the current task has a superior capability in effect | 353 | * has_capability_noaudit - Does a task have a capability (unaudited) in the |
354 | * initial user ns | ||
355 | * @t: The task in question | ||
345 | * @cap: The capability to be tested for | 356 | * @cap: The capability to be tested for |
346 | * | 357 | * |
347 | * Return true if the current task has the given superior capability currently | 358 | * Return true if the specified task has the given superior capability |
348 | * available for use, false if not. | 359 | * currently in effect to init_user_ns, false if not. Don't write an |
360 | * audit message for the check. | ||
349 | * | 361 | * |
350 | * This sets PF_SUPERPRIV on the task if the capability is available on the | 362 | * Note that this does not set PF_SUPERPRIV on the task. |
351 | * assumption that it's about to be used. | ||
352 | */ | 363 | */ |
353 | bool capable(int cap) | 364 | bool has_capability_noaudit(struct task_struct *t, int cap) |
354 | { | 365 | { |
355 | return ns_capable(&init_user_ns, cap); | 366 | return has_ns_capability_noaudit(t, &init_user_ns, cap); |
356 | } | 367 | } |
357 | EXPORT_SYMBOL(capable); | ||
358 | 368 | ||
359 | /** | 369 | /** |
360 | * ns_capable - Determine if the current task has a superior capability in effect | 370 | * ns_capable - Determine if the current task has a superior capability in effect |
@@ -374,7 +384,7 @@ bool ns_capable(struct user_namespace *ns, int cap) | |||
374 | BUG(); | 384 | BUG(); |
375 | } | 385 | } |
376 | 386 | ||
377 | if (security_capable(ns, current_cred(), cap) == 0) { | 387 | if (has_ns_capability(current, ns, cap)) { |
378 | current->flags |= PF_SUPERPRIV; | 388 | current->flags |= PF_SUPERPRIV; |
379 | return true; | 389 | return true; |
380 | } | 390 | } |
@@ -383,18 +393,20 @@ bool ns_capable(struct user_namespace *ns, int cap) | |||
383 | EXPORT_SYMBOL(ns_capable); | 393 | EXPORT_SYMBOL(ns_capable); |
384 | 394 | ||
385 | /** | 395 | /** |
386 | * task_ns_capable - Determine whether current task has a superior | 396 | * capable - Determine if the current task has a superior capability in effect |
387 | * capability targeted at a specific task's user namespace. | 397 | * @cap: The capability to be tested for |
388 | * @t: The task whose user namespace is targeted. | 398 | * |
389 | * @cap: The capability in question. | 399 | * Return true if the current task has the given superior capability currently |
400 | * available for use, false if not. | ||
390 | * | 401 | * |
391 | * Return true if it does, false otherwise. | 402 | * This sets PF_SUPERPRIV on the task if the capability is available on the |
403 | * assumption that it's about to be used. | ||
392 | */ | 404 | */ |
393 | bool task_ns_capable(struct task_struct *t, int cap) | 405 | bool capable(int cap) |
394 | { | 406 | { |
395 | return ns_capable(task_cred_xxx(t, user)->user_ns, cap); | 407 | return ns_capable(&init_user_ns, cap); |
396 | } | 408 | } |
397 | EXPORT_SYMBOL(task_ns_capable); | 409 | EXPORT_SYMBOL(capable); |
398 | 410 | ||
399 | /** | 411 | /** |
400 | * nsown_capable - Check superior capability to one's own user_ns | 412 | * nsown_capable - Check superior capability to one's own user_ns |
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 78ab24a7b0e4..00ab2ca5ed11 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
@@ -172,6 +172,14 @@ int ptrace_check_attach(struct task_struct *child, bool ignore_state) | |||
172 | return ret; | 172 | return ret; |
173 | } | 173 | } |
174 | 174 | ||
175 | static int ptrace_has_cap(struct user_namespace *ns, unsigned int mode) | ||
176 | { | ||
177 | if (mode & PTRACE_MODE_NOAUDIT) | ||
178 | return has_ns_capability_noaudit(current, ns, CAP_SYS_PTRACE); | ||
179 | else | ||
180 | return has_ns_capability(current, ns, CAP_SYS_PTRACE); | ||
181 | } | ||
182 | |||
175 | int __ptrace_may_access(struct task_struct *task, unsigned int mode) | 183 | int __ptrace_may_access(struct task_struct *task, unsigned int mode) |
176 | { | 184 | { |
177 | const struct cred *cred = current_cred(), *tcred; | 185 | const struct cred *cred = current_cred(), *tcred; |
@@ -198,7 +206,7 @@ int __ptrace_may_access(struct task_struct *task, unsigned int mode) | |||
198 | cred->gid == tcred->sgid && | 206 | cred->gid == tcred->sgid && |
199 | cred->gid == tcred->gid)) | 207 | cred->gid == tcred->gid)) |
200 | goto ok; | 208 | goto ok; |
201 | if (ns_capable(tcred->user->user_ns, CAP_SYS_PTRACE)) | 209 | if (ptrace_has_cap(tcred->user->user_ns, mode)) |
202 | goto ok; | 210 | goto ok; |
203 | rcu_read_unlock(); | 211 | rcu_read_unlock(); |
204 | return -EPERM; | 212 | return -EPERM; |
@@ -207,7 +215,7 @@ ok: | |||
207 | smp_rmb(); | 215 | smp_rmb(); |
208 | if (task->mm) | 216 | if (task->mm) |
209 | dumpable = get_dumpable(task->mm); | 217 | dumpable = get_dumpable(task->mm); |
210 | if (!dumpable && !task_ns_capable(task, CAP_SYS_PTRACE)) | 218 | if (!dumpable && !ptrace_has_cap(task_user_ns(task), mode)) |
211 | return -EPERM; | 219 | return -EPERM; |
212 | 220 | ||
213 | return security_ptrace_access_check(task, mode); | 221 | return security_ptrace_access_check(task, mode); |
@@ -277,7 +285,7 @@ static int ptrace_attach(struct task_struct *task, long request, | |||
277 | task->ptrace = PT_PTRACED; | 285 | task->ptrace = PT_PTRACED; |
278 | if (seize) | 286 | if (seize) |
279 | task->ptrace |= PT_SEIZED; | 287 | task->ptrace |= PT_SEIZED; |
280 | if (task_ns_capable(task, CAP_SYS_PTRACE)) | 288 | if (ns_capable(task_user_ns(task), CAP_SYS_PTRACE)) |
281 | task->ptrace |= PT_PTRACE_CAP; | 289 | task->ptrace |= PT_PTRACE_CAP; |
282 | 290 | ||
283 | __ptrace_link(task, current); | 291 | __ptrace_link(task, current); |
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index fd7b25e90079..df00cb09263e 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
@@ -4330,7 +4330,7 @@ long sched_setaffinity(pid_t pid, const struct cpumask *in_mask) | |||
4330 | goto out_free_cpus_allowed; | 4330 | goto out_free_cpus_allowed; |
4331 | } | 4331 | } |
4332 | retval = -EPERM; | 4332 | retval = -EPERM; |
4333 | if (!check_same_owner(p) && !task_ns_capable(p, CAP_SYS_NICE)) | 4333 | if (!check_same_owner(p) && !ns_capable(task_user_ns(p), CAP_SYS_NICE)) |
4334 | goto out_unlock; | 4334 | goto out_unlock; |
4335 | 4335 | ||
4336 | retval = security_task_setscheduler(p); | 4336 | retval = security_task_setscheduler(p); |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index dbf2ddafd52d..f16444bc6cbb 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -1960,7 +1960,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
1960 | sz_idx = type>>2; | 1960 | sz_idx = type>>2; |
1961 | kind = type&3; | 1961 | kind = type&3; |
1962 | 1962 | ||
1963 | if (kind != 2 && security_netlink_recv(skb, CAP_NET_ADMIN)) | 1963 | if (kind != 2 && !capable(CAP_NET_ADMIN)) |
1964 | return -EPERM; | 1964 | return -EPERM; |
1965 | 1965 | ||
1966 | if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { | 1966 | if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { |
diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c index 69975e0bcdea..1531135130db 100644 --- a/net/decnet/netfilter/dn_rtmsg.c +++ b/net/decnet/netfilter/dn_rtmsg.c | |||
@@ -108,7 +108,7 @@ static inline void dnrmg_receive_user_skb(struct sk_buff *skb) | |||
108 | if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) | 108 | if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) |
109 | return; | 109 | return; |
110 | 110 | ||
111 | if (security_netlink_recv(skb, CAP_NET_ADMIN)) | 111 | if (!capable(CAP_NET_ADMIN)) |
112 | RCV_SKB_FAIL(-EPERM); | 112 | RCV_SKB_FAIL(-EPERM); |
113 | 113 | ||
114 | /* Eventually we might send routing messages too */ | 114 | /* Eventually we might send routing messages too */ |
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index a057fe64debd..94d45e1f8882 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c | |||
@@ -431,7 +431,7 @@ __ipq_rcv_skb(struct sk_buff *skb) | |||
431 | if (type <= IPQM_BASE) | 431 | if (type <= IPQM_BASE) |
432 | return; | 432 | return; |
433 | 433 | ||
434 | if (security_netlink_recv(skb, CAP_NET_ADMIN)) | 434 | if (!capable(CAP_NET_ADMIN)) |
435 | RCV_SKB_FAIL(-EPERM); | 435 | RCV_SKB_FAIL(-EPERM); |
436 | 436 | ||
437 | spin_lock_bh(&queue_lock); | 437 | spin_lock_bh(&queue_lock); |
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index fb80a23c6640..a34c9e4c792c 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c | |||
@@ -432,7 +432,7 @@ __ipq_rcv_skb(struct sk_buff *skb) | |||
432 | if (type <= IPQM_BASE) | 432 | if (type <= IPQM_BASE) |
433 | return; | 433 | return; |
434 | 434 | ||
435 | if (security_netlink_recv(skb, CAP_NET_ADMIN)) | 435 | if (!capable(CAP_NET_ADMIN)) |
436 | RCV_SKB_FAIL(-EPERM); | 436 | RCV_SKB_FAIL(-EPERM); |
437 | 437 | ||
438 | spin_lock_bh(&queue_lock); | 438 | spin_lock_bh(&queue_lock); |
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index b4f8d849480c..4d70785b953d 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c | |||
@@ -130,7 +130,7 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
130 | const struct nfnetlink_subsystem *ss; | 130 | const struct nfnetlink_subsystem *ss; |
131 | int type, err; | 131 | int type, err; |
132 | 132 | ||
133 | if (security_netlink_recv(skb, CAP_NET_ADMIN)) | 133 | if (!capable(CAP_NET_ADMIN)) |
134 | return -EPERM; | 134 | return -EPERM; |
135 | 135 | ||
136 | /* All the messages must at least contain nfgenmsg */ | 136 | /* All the messages must at least contain nfgenmsg */ |
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index a403b618faa5..c29d2568c9e0 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c | |||
@@ -524,7 +524,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
524 | return -EOPNOTSUPP; | 524 | return -EOPNOTSUPP; |
525 | 525 | ||
526 | if ((ops->flags & GENL_ADMIN_PERM) && | 526 | if ((ops->flags & GENL_ADMIN_PERM) && |
527 | security_netlink_recv(skb, CAP_NET_ADMIN)) | 527 | !capable(CAP_NET_ADMIN)) |
528 | return -EPERM; | 528 | return -EPERM; |
529 | 529 | ||
530 | if (nlh->nlmsg_flags & NLM_F_DUMP) { | 530 | if (nlh->nlmsg_flags & NLM_F_DUMP) { |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 637f11a1e4df..66b84fbf2746 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -2290,7 +2290,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
2290 | link = &xfrm_dispatch[type]; | 2290 | link = &xfrm_dispatch[type]; |
2291 | 2291 | ||
2292 | /* All operations require privileges, even GET */ | 2292 | /* All operations require privileges, even GET */ |
2293 | if (security_netlink_recv(skb, CAP_NET_ADMIN)) | 2293 | if (!capable(CAP_NET_ADMIN)) |
2294 | return -EPERM; | 2294 | return -EPERM; |
2295 | 2295 | ||
2296 | if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) || | 2296 | if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) || |
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, |