diff options
Diffstat (limited to 'security/selinux/hooks.c')
| -rw-r--r-- | security/selinux/hooks.c | 50 | 
1 files changed, 39 insertions, 11 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 61a53367d029..ef26e9611ffb 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -4399,6 +4399,24 @@ static void selinux_req_classify_flow(const struct request_sock *req,  	fl->flowi_secid = req->secid;  } +static int selinux_tun_dev_alloc_security(void **security) +{ +	struct tun_security_struct *tunsec; + +	tunsec = kzalloc(sizeof(*tunsec), GFP_KERNEL); +	if (!tunsec) +		return -ENOMEM; +	tunsec->sid = current_sid(); + +	*security = tunsec; +	return 0; +} + +static void selinux_tun_dev_free_security(void *security) +{ +	kfree(security); +} +  static int selinux_tun_dev_create(void)  {  	u32 sid = current_sid(); @@ -4414,8 +4432,17 @@ static int selinux_tun_dev_create(void)  			    NULL);  } -static void selinux_tun_dev_post_create(struct sock *sk) +static int selinux_tun_dev_attach_queue(void *security)  { +	struct tun_security_struct *tunsec = security; + +	return avc_has_perm(current_sid(), tunsec->sid, SECCLASS_TUN_SOCKET, +			    TUN_SOCKET__ATTACH_QUEUE, NULL); +} + +static int selinux_tun_dev_attach(struct sock *sk, void *security) +{ +	struct tun_security_struct *tunsec = security;  	struct sk_security_struct *sksec = sk->sk_security;  	/* we don't currently perform any NetLabel based labeling here and it @@ -4425,20 +4452,19 @@ static void selinux_tun_dev_post_create(struct sock *sk)  	 * cause confusion to the TUN user that had no idea network labeling  	 * protocols were being used */ -	/* see the comments in selinux_tun_dev_create() about why we don't use -	 * the sockcreate SID here */ - -	sksec->sid = current_sid(); +	sksec->sid = tunsec->sid;  	sksec->sclass = SECCLASS_TUN_SOCKET; + +	return 0;  } -static int selinux_tun_dev_attach(struct sock *sk) +static int selinux_tun_dev_open(void *security)  { -	struct sk_security_struct *sksec = sk->sk_security; +	struct tun_security_struct *tunsec = security;  	u32 sid = current_sid();  	int err; -	err = avc_has_perm(sid, sksec->sid, SECCLASS_TUN_SOCKET, +	err = avc_has_perm(sid, tunsec->sid, SECCLASS_TUN_SOCKET,  			   TUN_SOCKET__RELABELFROM, NULL);  	if (err)  		return err; @@ -4446,8 +4472,7 @@ static int selinux_tun_dev_attach(struct sock *sk)  			   TUN_SOCKET__RELABELTO, NULL);  	if (err)  		return err; - -	sksec->sid = sid; +	tunsec->sid = sid;  	return 0;  } @@ -5642,9 +5667,12 @@ static struct security_operations selinux_ops = {  	.secmark_refcount_inc =		selinux_secmark_refcount_inc,  	.secmark_refcount_dec =		selinux_secmark_refcount_dec,  	.req_classify_flow =		selinux_req_classify_flow, +	.tun_dev_alloc_security =	selinux_tun_dev_alloc_security, +	.tun_dev_free_security =	selinux_tun_dev_free_security,  	.tun_dev_create =		selinux_tun_dev_create, -	.tun_dev_post_create = 		selinux_tun_dev_post_create, +	.tun_dev_attach_queue =		selinux_tun_dev_attach_queue,  	.tun_dev_attach =		selinux_tun_dev_attach, +	.tun_dev_open =			selinux_tun_dev_open,  #ifdef CONFIG_SECURITY_NETWORK_XFRM  	.xfrm_policy_alloc_security =	selinux_xfrm_policy_alloc,  | 
