diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-14 18:36:33 -0800 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-14 18:36:33 -0800 | 
| 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)  	type -= CRYPTO_MSG_BASE;  	link = &crypto_dispatch[type]; -	if (security_netlink_recv(skb, CAP_NET_ADMIN)) +	if (!capable(CAP_NET_ADMIN))  		return -EPERM;  	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,  	u8 *data = (u8*) buf;  	/* Several chips lock up trying to read undefined config space */ -	if (security_capable(&init_user_ns, filp->f_cred, CAP_SYS_ADMIN) == 0) { +	if (security_capable(filp->f_cred, &init_user_ns, CAP_SYS_ADMIN) == 0) {  		size = dev->cfg_size;  	} else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {  		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)  			goto next_msg;  		} -		if (security_netlink_recv(skb, CAP_SYS_ADMIN)) { +		if (!capable(CAP_SYS_ADMIN)) {  			err = -EPERM;  			goto next_msg;  		} 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,  	state = *get_task_state(task);  	vsize = eip = esp = 0; -	permitted = ptrace_may_access(task, PTRACE_MODE_READ); +	permitted = ptrace_may_access(task, PTRACE_MODE_READ | PTRACE_MODE_NOAUDIT);  	mm = get_task_mm(task);  	if (mm) {  		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;  struct user_namespace *current_user_ns(void);  extern const kernel_cap_t __cap_empty_set; -extern const kernel_cap_t __cap_full_set;  extern const kernel_cap_t __cap_init_eff_set;  /* @@ -544,9 +543,10 @@ extern bool has_capability(struct task_struct *t, int cap);  extern bool has_ns_capability(struct task_struct *t,  			      struct user_namespace *ns, int cap);  extern bool has_capability_noaudit(struct task_struct *t, int cap); +extern bool has_ns_capability_noaudit(struct task_struct *t, +				      struct user_namespace *ns, int cap);  extern bool capable(int cap);  extern bool ns_capable(struct user_namespace *ns, int cap); -extern bool task_ns_capable(struct task_struct *t, int cap);  extern bool nsown_capable(int cap);  /* 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)  #define current_security()	(current_cred_xxx(security))  #ifdef CONFIG_USER_NS -#define current_user_ns() (current_cred_xxx(user_ns)) +#define current_user_ns()	(current_cred_xxx(user_ns)) +#define task_user_ns(task)	(task_cred_xxx((task), user_ns))  #else  extern struct user_namespace init_user_ns; -#define current_user_ns() (&init_user_ns) +#define current_user_ns()	(&init_user_ns) +#define task_user_ns(task)	(&init_user_ns)  #endif 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,  			  struct task_struct *new_parent);  extern void __ptrace_unlink(struct task_struct *child);  extern void exit_ptrace(struct task_struct *tracer); -#define PTRACE_MODE_READ   1 -#define PTRACE_MODE_ATTACH 2 +#define PTRACE_MODE_READ	0x01 +#define PTRACE_MODE_ATTACH	0x02 +#define PTRACE_MODE_NOAUDIT	0x04  /* Returns 0 on success, -errno on denial. */  extern int __ptrace_may_access(struct task_struct *task, unsigned int mode);  /* 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;   * These functions are in security/capability.c and are used   * as the default capabilities functions   */ -extern int cap_capable(struct task_struct *tsk, const struct cred *cred, -		       struct user_namespace *ns, int cap, int audit); +extern int cap_capable(const struct cred *cred, struct user_namespace *ns, +		       int cap, int audit);  extern int cap_settime(const struct timespec *ts, const struct timezone *tz);  extern int cap_ptrace_access_check(struct task_struct *child, unsigned int mode);  extern int cap_ptrace_traceme(struct task_struct *parent); @@ -96,7 +96,6 @@ struct xfrm_user_sec_ctx;  struct seq_file;  extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb); -extern int cap_netlink_recv(struct sk_buff *skb, int cap);  void reset_security_ops(void); @@ -799,12 +798,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)   *	@skb contains the sk_buff structure for the netlink message.   *	Return 0 if the information was successfully saved and message   *	is allowed to be transmitted. - * @netlink_recv: - *	Check permission before processing the received netlink message in - *	@skb. - *	@skb contains the sk_buff structure for the netlink message. - *	@cap indicates the capability required - *	Return 0 if permission is granted.   *   * Security hooks for Unix domain networking.   * @@ -1268,7 +1261,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)   * @capable:   *	Check whether the @tsk process has the @cap capability in the indicated   *	credentials. - *	@tsk contains the task_struct for the process.   *	@cred contains the credentials to use.   *	@ns contains the user namespace we want the capability in   *	@cap contains the capability <include/linux/capability.h>. @@ -1392,8 +1384,8 @@ struct security_operations {  		       const kernel_cap_t *effective,  		       const kernel_cap_t *inheritable,  		       const kernel_cap_t *permitted); -	int (*capable) (struct task_struct *tsk, const struct cred *cred, -			struct user_namespace *ns, int cap, int audit); +	int (*capable) (const struct cred *cred, struct user_namespace *ns, +			int cap, int audit);  	int (*quotactl) (int cmds, int type, int id, struct super_block *sb);  	int (*quota_on) (struct dentry *dentry);  	int (*syslog) (int type); @@ -1563,7 +1555,6 @@ struct security_operations {  			  struct sembuf *sops, unsigned nsops, int alter);  	int (*netlink_send) (struct sock *sk, struct sk_buff *skb); -	int (*netlink_recv) (struct sk_buff *skb, int cap);  	void (*d_instantiate) (struct dentry *dentry, struct inode *inode); @@ -1675,12 +1666,10 @@ int security_capset(struct cred *new, const struct cred *old,  		    const kernel_cap_t *effective,  		    const kernel_cap_t *inheritable,  		    const kernel_cap_t *permitted); -int security_capable(struct user_namespace *ns, const struct cred *cred, -			int cap); -int security_real_capable(struct task_struct *tsk, struct user_namespace *ns, +int security_capable(const struct cred *cred, struct user_namespace *ns,  			int cap); -int security_real_capable_noaudit(struct task_struct *tsk, -			struct user_namespace *ns, int cap); +int security_capable_noaudit(const struct cred *cred, struct user_namespace *ns, +			     int cap);  int security_quotactl(int cmds, int type, int id, struct super_block *sb);  int security_quota_on(struct dentry *dentry);  int security_syslog(int type); @@ -1817,7 +1806,6 @@ void security_d_instantiate(struct dentry *dentry, struct inode *inode);  int security_getprocattr(struct task_struct *p, char *name, char **value);  int security_setprocattr(struct task_struct *p, char *name, void *value, size_t size);  int security_netlink_send(struct sock *sk, struct sk_buff *skb); -int security_netlink_recv(struct sk_buff *skb, int cap);  int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);  int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);  void security_release_secctx(char *secdata, u32 seclen); @@ -1875,32 +1863,15 @@ static inline int security_capset(struct cred *new,  	return cap_capset(new, old, effective, inheritable, permitted);  } -static inline int security_capable(struct user_namespace *ns, -				   const struct cred *cred, int cap) -{ -	return cap_capable(current, cred, ns, cap, SECURITY_CAP_AUDIT); -} - -static inline int security_real_capable(struct task_struct *tsk, struct user_namespace *ns, int cap) +static inline int security_capable(const struct cred *cred, +				   struct user_namespace *ns, int cap)  { -	int ret; - -	rcu_read_lock(); -	ret = cap_capable(tsk, __task_cred(tsk), ns, cap, SECURITY_CAP_AUDIT); -	rcu_read_unlock(); -	return ret; +	return cap_capable(cred, ns, cap, SECURITY_CAP_AUDIT);  } -static inline -int security_real_capable_noaudit(struct task_struct *tsk, struct user_namespace *ns, int cap) -{ -	int ret; - -	rcu_read_lock(); -	ret = cap_capable(tsk, __task_cred(tsk), ns, cap, -			       SECURITY_CAP_NOAUDIT); -	rcu_read_unlock(); -	return ret; +static inline int security_capable_noaudit(const struct cred *cred, +					   struct user_namespace *ns, int cap) { +	return cap_capable(cred, ns, cap, SECURITY_CAP_NOAUDIT);  }  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)  	return cap_netlink_send(sk, skb);  } -static inline int security_netlink_recv(struct sk_buff *skb, int cap) -{ -	return cap_netlink_recv(skb, cap); -} -  static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)  {  	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)  	case AUDIT_TTY_SET:  	case AUDIT_TRIM:  	case AUDIT_MAKE_EQUIV: -		if (security_netlink_recv(skb, CAP_AUDIT_CONTROL)) +		if (!capable(CAP_AUDIT_CONTROL))  			err = -EPERM;  		break;  	case AUDIT_USER:  	case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:  	case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2: -		if (security_netlink_recv(skb, CAP_AUDIT_WRITE)) +		if (!capable(CAP_AUDIT_WRITE))  			err = -EPERM;  		break;  	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:  }  /** - * has_capability - Does a task have a capability in init_user_ns + * has_ns_capability - Does a task have a capability in a specific user ns   * @t: The task in question + * @ns: target user namespace   * @cap: The capability to be tested for   *   * Return true if the specified task has the given superior capability - * currently in effect to the initial user namespace, false if not. + * currently in effect to the specified user namespace, false if not.   *   * Note that this does not set PF_SUPERPRIV on the task.   */ -bool has_capability(struct task_struct *t, int cap) +bool has_ns_capability(struct task_struct *t, +		       struct user_namespace *ns, int cap)  { -	int ret = security_real_capable(t, &init_user_ns, cap); +	int ret; + +	rcu_read_lock(); +	ret = security_capable(__task_cred(t), ns, cap); +	rcu_read_unlock();  	return (ret == 0);  }  /** - * has_capability - Does a task have a capability in a specific user ns + * has_capability - Does a task have a capability in init_user_ns   * @t: The task in question - * @ns: target user namespace   * @cap: The capability to be tested for   *   * Return true if the specified task has the given superior capability - * currently in effect to the specified user namespace, false if not. + * currently in effect to the initial user namespace, false if not.   *   * Note that this does not set PF_SUPERPRIV on the task.   */ -bool has_ns_capability(struct task_struct *t, -		       struct user_namespace *ns, int cap) +bool has_capability(struct task_struct *t, int cap)  { -	int ret = security_real_capable(t, ns, cap); - -	return (ret == 0); +	return has_ns_capability(t, &init_user_ns, cap);  }  /** - * has_capability_noaudit - Does a task have a capability (unaudited) + * has_ns_capability_noaudit - Does a task have a capability (unaudited) + * in a specific user ns.   * @t: The task in question + * @ns: target user namespace   * @cap: The capability to be tested for   *   * Return true if the specified task has the given superior capability - * currently in effect to init_user_ns, false if not.  Don't write an - * audit message for the check. + * currently in effect to the specified user namespace, false if not. + * Do not write an audit message for the check.   *   * Note that this does not set PF_SUPERPRIV on the task.   */ -bool has_capability_noaudit(struct task_struct *t, int cap) +bool has_ns_capability_noaudit(struct task_struct *t, +			       struct user_namespace *ns, int cap)  { -	int ret = security_real_capable_noaudit(t, &init_user_ns, cap); +	int ret; + +	rcu_read_lock(); +	ret = security_capable_noaudit(__task_cred(t), ns, cap); +	rcu_read_unlock();  	return (ret == 0);  }  /** - * capable - Determine if the current task has a superior capability in effect + * has_capability_noaudit - Does a task have a capability (unaudited) in the + * initial user ns + * @t: The task in question   * @cap: The capability to be tested for   * - * Return true if the current task has the given superior capability currently - * available for use, false if not. + * Return true if the specified task has the given superior capability + * currently in effect to init_user_ns, false if not.  Don't write an + * audit message for the check.   * - * This sets PF_SUPERPRIV on the task if the capability is available on the - * assumption that it's about to be used. + * Note that this does not set PF_SUPERPRIV on the task.   */ -bool capable(int cap) +bool has_capability_noaudit(struct task_struct *t, int cap)  { -	return ns_capable(&init_user_ns, cap); +	return has_ns_capability_noaudit(t, &init_user_ns, cap);  } -EXPORT_SYMBOL(capable);  /**   * 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)  		BUG();  	} -	if (security_capable(ns, current_cred(), cap) == 0) { +	if (has_ns_capability(current, ns, cap)) {  		current->flags |= PF_SUPERPRIV;  		return true;  	} @@ -383,18 +393,20 @@ bool ns_capable(struct user_namespace *ns, int cap)  EXPORT_SYMBOL(ns_capable);  /** - * task_ns_capable - Determine whether current task has a superior - * capability targeted at a specific task's user namespace. - * @t: The task whose user namespace is targeted. - * @cap: The capability in question. + * capable - Determine if the current task has a superior capability in effect + * @cap: The capability to be tested for + * + * Return true if the current task has the given superior capability currently + * available for use, false if not.   * - *  Return true if it does, false otherwise. + * This sets PF_SUPERPRIV on the task if the capability is available on the + * assumption that it's about to be used.   */ -bool task_ns_capable(struct task_struct *t, int cap) +bool capable(int cap)  { -	return ns_capable(task_cred_xxx(t, user)->user_ns, cap); +	return ns_capable(&init_user_ns, cap);  } -EXPORT_SYMBOL(task_ns_capable); +EXPORT_SYMBOL(capable);  /**   * 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)  	return ret;  } +static int ptrace_has_cap(struct user_namespace *ns, unsigned int mode) +{ +	if (mode & PTRACE_MODE_NOAUDIT) +		return has_ns_capability_noaudit(current, ns, CAP_SYS_PTRACE); +	else +		return has_ns_capability(current, ns, CAP_SYS_PTRACE); +} +  int __ptrace_may_access(struct task_struct *task, unsigned int mode)  {  	const struct cred *cred = current_cred(), *tcred; @@ -198,7 +206,7 @@ int __ptrace_may_access(struct task_struct *task, unsigned int mode)  	     cred->gid == tcred->sgid &&  	     cred->gid == tcred->gid))  		goto ok; -	if (ns_capable(tcred->user->user_ns, CAP_SYS_PTRACE)) +	if (ptrace_has_cap(tcred->user->user_ns, mode))  		goto ok;  	rcu_read_unlock();  	return -EPERM; @@ -207,7 +215,7 @@ ok:  	smp_rmb();  	if (task->mm)  		dumpable = get_dumpable(task->mm); -	if (!dumpable && !task_ns_capable(task, CAP_SYS_PTRACE)) +	if (!dumpable  && !ptrace_has_cap(task_user_ns(task), mode))  		return -EPERM;  	return security_ptrace_access_check(task, mode); @@ -277,7 +285,7 @@ static int ptrace_attach(struct task_struct *task, long request,  	task->ptrace = PT_PTRACED;  	if (seize)  		task->ptrace |= PT_SEIZED; -	if (task_ns_capable(task, CAP_SYS_PTRACE)) +	if (ns_capable(task_user_ns(task), CAP_SYS_PTRACE))  		task->ptrace |= PT_PTRACE_CAP;  	__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)  		goto out_free_cpus_allowed;  	}  	retval = -EPERM; -	if (!check_same_owner(p) && !task_ns_capable(p, CAP_SYS_NICE)) +	if (!check_same_owner(p) && !ns_capable(task_user_ns(p), CAP_SYS_NICE))  		goto out_unlock;  	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)  	sz_idx = type>>2;  	kind = type&3; -	if (kind != 2 && security_netlink_recv(skb, CAP_NET_ADMIN)) +	if (kind != 2 && !capable(CAP_NET_ADMIN))  		return -EPERM;  	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)  	if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)  		return; -	if (security_netlink_recv(skb, CAP_NET_ADMIN)) +	if (!capable(CAP_NET_ADMIN))  		RCV_SKB_FAIL(-EPERM);  	/* 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)  	if (type <= IPQM_BASE)  		return; -	if (security_netlink_recv(skb, CAP_NET_ADMIN)) +	if (!capable(CAP_NET_ADMIN))  		RCV_SKB_FAIL(-EPERM);  	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)  	if (type <= IPQM_BASE)  		return; -	if (security_netlink_recv(skb, CAP_NET_ADMIN)) +	if (!capable(CAP_NET_ADMIN))  		RCV_SKB_FAIL(-EPERM);  	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)  	const struct nfnetlink_subsystem *ss;  	int type, err; -	if (security_netlink_recv(skb, CAP_NET_ADMIN)) +	if (!capable(CAP_NET_ADMIN))  		return -EPERM;  	/* 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)  		return -EOPNOTSUPP;  	if ((ops->flags & GENL_ADMIN_PERM) && -	    security_netlink_recv(skb, CAP_NET_ADMIN)) +	    !capable(CAP_NET_ADMIN))  		return -EPERM;  	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)  	link = &xfrm_dispatch[type];  	/* All operations require privileges, even GET */ -	if (security_netlink_recv(skb, CAP_NET_ADMIN)) +	if (!capable(CAP_NET_ADMIN))  		return -EPERM;  	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,  	return 0;  } -static int apparmor_capable(struct task_struct *task, const struct cred *cred, -			    struct user_namespace *ns, int cap, int audit) +static int apparmor_capable(const struct cred *cred, struct user_namespace *ns, +			    int cap, int audit)  {  	struct aa_profile *profile;  	/* cap_capable returns 0 on success, else -EPERM */ -	int error = cap_capable(task, cred, ns, cap, audit); +	int error = cap_capable(cred, ns, cap, audit);  	if (!error) {  		profile = aa_cred_profile(cred);  		if (!unconfined(profile)) -			error = aa_capable(task, profile, cap, audit); +			error = aa_capable(current, profile, cap, audit);  	}  	return error;  } 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)  	set_to_cap_if_null(ops, sem_semctl);  	set_to_cap_if_null(ops, sem_semop);  	set_to_cap_if_null(ops, netlink_send); -	set_to_cap_if_null(ops, netlink_recv);  	set_to_cap_if_null(ops, d_instantiate);  	set_to_cap_if_null(ops, getprocattr);  	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)  	return 0;  } -int cap_netlink_recv(struct sk_buff *skb, int cap) -{ -	if (!cap_raised(current_cap(), cap)) -		return -EPERM; -	return 0; -} -EXPORT_SYMBOL(cap_netlink_recv); -  /**   * cap_capable - Determine whether a task has a particular effective capability - * @tsk: The task to query   * @cred: The credentials to use   * @ns:  The user namespace in which we need the capability   * @cap: The capability to check for @@ -80,8 +71,8 @@ EXPORT_SYMBOL(cap_netlink_recv);   * cap_has_capability() returns 0 when a task has a capability, but the   * kernel's capable() and has_capability() returns 1 for this case.   */ -int cap_capable(struct task_struct *tsk, const struct cred *cred, -		struct user_namespace *targ_ns, int cap, int audit) +int cap_capable(const struct cred *cred, struct user_namespace *targ_ns, +		int cap, int audit)  {  	for (;;) {  		/* The creator of the user namespace has all caps. */ @@ -222,9 +213,8 @@ static inline int cap_inh_is_capped(void)  	/* they are so limited unless the current task has the CAP_SETPCAP  	 * capability  	 */ -	if (cap_capable(current, current_cred(), -			current_cred()->user->user_ns, CAP_SETPCAP, -			SECURITY_CAP_AUDIT) == 0) +	if (cap_capable(current_cred(), current_cred()->user->user_ns, +			CAP_SETPCAP, SECURITY_CAP_AUDIT) == 0)  		return 0;  	return 1;  } @@ -874,7 +864,7 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,  		     & (new->securebits ^ arg2))			/*[1]*/  		    || ((new->securebits & SECURE_ALL_LOCKS & ~arg2))	/*[2]*/  		    || (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS))	/*[3]*/ -		    || (cap_capable(current, current_cred(), +		    || (cap_capable(current_cred(),  				    current_cred()->user->user_ns, CAP_SETPCAP,  				    SECURITY_CAP_AUDIT) != 0)		/*[4]*/  			/* @@ -940,7 +930,7 @@ int cap_vm_enough_memory(struct mm_struct *mm, long pages)  {  	int cap_sys_admin = 0; -	if (cap_capable(current, current_cred(), &init_user_ns, CAP_SYS_ADMIN, +	if (cap_capable(current_cred(), &init_user_ns, CAP_SYS_ADMIN,  			SECURITY_CAP_NOAUDIT) == 0)  		cap_sys_admin = 1;  	return __vm_enough_memory(mm, pages, cap_sys_admin); @@ -967,7 +957,7 @@ int cap_file_mmap(struct file *file, unsigned long reqprot,  	int ret = 0;  	if (addr < dac_mmap_min_addr) { -		ret = cap_capable(current, current_cred(), &init_user_ns, CAP_SYS_RAWIO, +		ret = cap_capable(current_cred(), &init_user_ns, CAP_SYS_RAWIO,  				  SECURITY_CAP_AUDIT);  		/* set PF_SUPERPRIV if it turns out we allow the low mmap */  		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,  				    effective, inheritable, permitted);  } -int security_capable(struct user_namespace *ns, const struct cred *cred, +int security_capable(const struct cred *cred, struct user_namespace *ns,  		     int cap)  { -	return security_ops->capable(current, cred, ns, cap, -				     SECURITY_CAP_AUDIT); +	return security_ops->capable(cred, ns, cap, SECURITY_CAP_AUDIT);  } -int security_real_capable(struct task_struct *tsk, struct user_namespace *ns, -			  int cap) +int security_capable_noaudit(const struct cred *cred, struct user_namespace *ns, +			     int cap)  { -	const struct cred *cred; -	int ret; - -	cred = get_task_cred(tsk); -	ret = security_ops->capable(tsk, cred, ns, cap, SECURITY_CAP_AUDIT); -	put_cred(cred); -	return ret; -} - -int security_real_capable_noaudit(struct task_struct *tsk, -				  struct user_namespace *ns, int cap) -{ -	const struct cred *cred; -	int ret; - -	cred = get_task_cred(tsk); -	ret = security_ops->capable(tsk, cred, ns, cap, SECURITY_CAP_NOAUDIT); -	put_cred(cred); -	return ret; +	return security_ops->capable(cred, ns, cap, SECURITY_CAP_NOAUDIT);  }  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)  	return security_ops->netlink_send(sk, skb);  } -int security_netlink_recv(struct sk_buff *skb, int cap) -{ -	return security_ops->netlink_recv(skb, cap); -} -EXPORT_SYMBOL(security_netlink_recv); -  int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)  {  	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,  #endif  /* Check whether a task is allowed to use a capability. */ -static int task_has_capability(struct task_struct *tsk, -			       const struct cred *cred, +static int cred_has_capability(const struct cred *cred,  			       int cap, int audit)  {  	struct common_audit_data ad; @@ -1427,7 +1426,7 @@ static int task_has_capability(struct task_struct *tsk,  	int rc;  	COMMON_AUDIT_DATA_INIT(&ad, CAP); -	ad.tsk = tsk; +	ad.tsk = current;  	ad.u.cap = cap;  	switch (CAP_TO_INDEX(cap)) { @@ -1811,7 +1810,7 @@ static int selinux_ptrace_access_check(struct task_struct *child,  	if (rc)  		return rc; -	if (mode == PTRACE_MODE_READ) { +	if (mode & PTRACE_MODE_READ) {  		u32 sid = current_sid();  		u32 csid = task_sid(child);  		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,   * the CAP_SETUID and CAP_SETGID capabilities using the capable hook.   */ -static int selinux_capable(struct task_struct *tsk, const struct cred *cred, -			   struct user_namespace *ns, int cap, int audit) +static int selinux_capable(const struct cred *cred, struct user_namespace *ns, +			   int cap, int audit)  {  	int rc; -	rc = cap_capable(tsk, cred, ns, cap, audit); +	rc = cap_capable(cred, ns, cap, audit);  	if (rc)  		return rc; -	return task_has_capability(tsk, cred, cap, audit); +	return cred_has_capability(cred, cap, audit);  }  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)  {  	int rc, cap_sys_admin = 0; -	rc = selinux_capable(current, current_cred(), -			     &init_user_ns, CAP_SYS_ADMIN, +	rc = selinux_capable(current_cred(), &init_user_ns, CAP_SYS_ADMIN,  			     SECURITY_CAP_NOAUDIT);  	if (rc == 0)  		cap_sys_admin = 1; @@ -2859,8 +2857,7 @@ static int selinux_inode_getsecurity(const struct inode *inode, const char *name  	 * and lack of permission just means that we fall back to the  	 * in-core context value, not a denial.  	 */ -	error = selinux_capable(current, current_cred(), -				&init_user_ns, CAP_MAC_ADMIN, +	error = selinux_capable(current_cred(), &init_user_ns, CAP_MAC_ADMIN,  				SECURITY_CAP_NOAUDIT);  	if (!error)  		error = security_sid_to_context_force(isec->sid, &context, @@ -2993,8 +2990,8 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd,  	case KDSKBENT:  	case KDSKBSENT: -		error = task_has_capability(current, cred, CAP_SYS_TTY_CONFIG, -					SECURITY_CAP_AUDIT); +		error = cred_has_capability(cred, CAP_SYS_TTY_CONFIG, +					    SECURITY_CAP_AUDIT);  		break;  	/* default case assumes that the command will go @@ -4718,24 +4715,6 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)  	return selinux_nlmsg_perm(sk, skb);  } -static int selinux_netlink_recv(struct sk_buff *skb, int capability) -{ -	int err; -	struct common_audit_data ad; -	u32 sid; - -	err = cap_netlink_recv(skb, capability); -	if (err) -		return err; - -	COMMON_AUDIT_DATA_INIT(&ad, CAP); -	ad.u.cap = capability; - -	security_task_getsecid(current, &sid); -	return avc_has_perm(sid, sid, SECCLASS_CAPABILITY, -			    CAP_TO_MASK(capability), &ad); -} -  static int ipc_alloc_security(struct task_struct *task,  			      struct kern_ipc_perm *perm,  			      u16 sclass) @@ -5464,7 +5443,6 @@ static struct security_operations selinux_ops = {  	.vm_enough_memory =		selinux_vm_enough_memory,  	.netlink_send =			selinux_netlink_send, -	.netlink_recv =			selinux_netlink_recv,  	.bprm_set_creds =		selinux_bprm_set_creds,  	.bprm_committing_creds =	selinux_bprm_committing_creds, | 
