diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 60 |
1 files changed, 44 insertions, 16 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 61a53367d029..84b591711eec 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -1528,7 +1528,7 @@ static int file_has_perm(const struct cred *cred, | |||
1528 | u32 av) | 1528 | u32 av) |
1529 | { | 1529 | { |
1530 | struct file_security_struct *fsec = file->f_security; | 1530 | struct file_security_struct *fsec = file->f_security; |
1531 | struct inode *inode = file->f_path.dentry->d_inode; | 1531 | struct inode *inode = file_inode(file); |
1532 | struct common_audit_data ad; | 1532 | struct common_audit_data ad; |
1533 | u32 sid = cred_sid(cred); | 1533 | u32 sid = cred_sid(cred); |
1534 | int rc; | 1534 | int rc; |
@@ -1957,7 +1957,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) | |||
1957 | struct task_security_struct *new_tsec; | 1957 | struct task_security_struct *new_tsec; |
1958 | struct inode_security_struct *isec; | 1958 | struct inode_security_struct *isec; |
1959 | struct common_audit_data ad; | 1959 | struct common_audit_data ad; |
1960 | struct inode *inode = bprm->file->f_path.dentry->d_inode; | 1960 | struct inode *inode = file_inode(bprm->file); |
1961 | int rc; | 1961 | int rc; |
1962 | 1962 | ||
1963 | rc = cap_bprm_set_creds(bprm); | 1963 | rc = cap_bprm_set_creds(bprm); |
@@ -2929,7 +2929,7 @@ static void selinux_inode_getsecid(const struct inode *inode, u32 *secid) | |||
2929 | static int selinux_revalidate_file_permission(struct file *file, int mask) | 2929 | static int selinux_revalidate_file_permission(struct file *file, int mask) |
2930 | { | 2930 | { |
2931 | const struct cred *cred = current_cred(); | 2931 | const struct cred *cred = current_cred(); |
2932 | struct inode *inode = file->f_path.dentry->d_inode; | 2932 | struct inode *inode = file_inode(file); |
2933 | 2933 | ||
2934 | /* file_mask_to_av won't add FILE__WRITE if MAY_APPEND is set */ | 2934 | /* file_mask_to_av won't add FILE__WRITE if MAY_APPEND is set */ |
2935 | if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE)) | 2935 | if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE)) |
@@ -2941,7 +2941,7 @@ static int selinux_revalidate_file_permission(struct file *file, int mask) | |||
2941 | 2941 | ||
2942 | static int selinux_file_permission(struct file *file, int mask) | 2942 | static int selinux_file_permission(struct file *file, int mask) |
2943 | { | 2943 | { |
2944 | struct inode *inode = file->f_path.dentry->d_inode; | 2944 | struct inode *inode = file_inode(file); |
2945 | struct file_security_struct *fsec = file->f_security; | 2945 | struct file_security_struct *fsec = file->f_security; |
2946 | struct inode_security_struct *isec = inode->i_security; | 2946 | struct inode_security_struct *isec = inode->i_security; |
2947 | u32 sid = current_sid(); | 2947 | u32 sid = current_sid(); |
@@ -3218,7 +3218,7 @@ static int selinux_file_open(struct file *file, const struct cred *cred) | |||
3218 | struct inode_security_struct *isec; | 3218 | struct inode_security_struct *isec; |
3219 | 3219 | ||
3220 | fsec = file->f_security; | 3220 | fsec = file->f_security; |
3221 | isec = file->f_path.dentry->d_inode->i_security; | 3221 | isec = file_inode(file)->i_security; |
3222 | /* | 3222 | /* |
3223 | * Save inode label and policy sequence number | 3223 | * Save inode label and policy sequence number |
3224 | * at open-time so that selinux_file_permission | 3224 | * at open-time so that selinux_file_permission |
@@ -4399,6 +4399,24 @@ static void selinux_req_classify_flow(const struct request_sock *req, | |||
4399 | fl->flowi_secid = req->secid; | 4399 | fl->flowi_secid = req->secid; |
4400 | } | 4400 | } |
4401 | 4401 | ||
4402 | static int selinux_tun_dev_alloc_security(void **security) | ||
4403 | { | ||
4404 | struct tun_security_struct *tunsec; | ||
4405 | |||
4406 | tunsec = kzalloc(sizeof(*tunsec), GFP_KERNEL); | ||
4407 | if (!tunsec) | ||
4408 | return -ENOMEM; | ||
4409 | tunsec->sid = current_sid(); | ||
4410 | |||
4411 | *security = tunsec; | ||
4412 | return 0; | ||
4413 | } | ||
4414 | |||
4415 | static void selinux_tun_dev_free_security(void *security) | ||
4416 | { | ||
4417 | kfree(security); | ||
4418 | } | ||
4419 | |||
4402 | static int selinux_tun_dev_create(void) | 4420 | static int selinux_tun_dev_create(void) |
4403 | { | 4421 | { |
4404 | u32 sid = current_sid(); | 4422 | u32 sid = current_sid(); |
@@ -4414,8 +4432,17 @@ static int selinux_tun_dev_create(void) | |||
4414 | NULL); | 4432 | NULL); |
4415 | } | 4433 | } |
4416 | 4434 | ||
4417 | static void selinux_tun_dev_post_create(struct sock *sk) | 4435 | static int selinux_tun_dev_attach_queue(void *security) |
4418 | { | 4436 | { |
4437 | struct tun_security_struct *tunsec = security; | ||
4438 | |||
4439 | return avc_has_perm(current_sid(), tunsec->sid, SECCLASS_TUN_SOCKET, | ||
4440 | TUN_SOCKET__ATTACH_QUEUE, NULL); | ||
4441 | } | ||
4442 | |||
4443 | static int selinux_tun_dev_attach(struct sock *sk, void *security) | ||
4444 | { | ||
4445 | struct tun_security_struct *tunsec = security; | ||
4419 | struct sk_security_struct *sksec = sk->sk_security; | 4446 | struct sk_security_struct *sksec = sk->sk_security; |
4420 | 4447 | ||
4421 | /* we don't currently perform any NetLabel based labeling here and it | 4448 | /* 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) | |||
4425 | * cause confusion to the TUN user that had no idea network labeling | 4452 | * cause confusion to the TUN user that had no idea network labeling |
4426 | * protocols were being used */ | 4453 | * protocols were being used */ |
4427 | 4454 | ||
4428 | /* see the comments in selinux_tun_dev_create() about why we don't use | 4455 | sksec->sid = tunsec->sid; |
4429 | * the sockcreate SID here */ | ||
4430 | |||
4431 | sksec->sid = current_sid(); | ||
4432 | sksec->sclass = SECCLASS_TUN_SOCKET; | 4456 | sksec->sclass = SECCLASS_TUN_SOCKET; |
4457 | |||
4458 | return 0; | ||
4433 | } | 4459 | } |
4434 | 4460 | ||
4435 | static int selinux_tun_dev_attach(struct sock *sk) | 4461 | static int selinux_tun_dev_open(void *security) |
4436 | { | 4462 | { |
4437 | struct sk_security_struct *sksec = sk->sk_security; | 4463 | struct tun_security_struct *tunsec = security; |
4438 | u32 sid = current_sid(); | 4464 | u32 sid = current_sid(); |
4439 | int err; | 4465 | int err; |
4440 | 4466 | ||
4441 | err = avc_has_perm(sid, sksec->sid, SECCLASS_TUN_SOCKET, | 4467 | err = avc_has_perm(sid, tunsec->sid, SECCLASS_TUN_SOCKET, |
4442 | TUN_SOCKET__RELABELFROM, NULL); | 4468 | TUN_SOCKET__RELABELFROM, NULL); |
4443 | if (err) | 4469 | if (err) |
4444 | return err; | 4470 | return err; |
@@ -4446,8 +4472,7 @@ static int selinux_tun_dev_attach(struct sock *sk) | |||
4446 | TUN_SOCKET__RELABELTO, NULL); | 4472 | TUN_SOCKET__RELABELTO, NULL); |
4447 | if (err) | 4473 | if (err) |
4448 | return err; | 4474 | return err; |
4449 | 4475 | tunsec->sid = sid; | |
4450 | sksec->sid = sid; | ||
4451 | 4476 | ||
4452 | return 0; | 4477 | return 0; |
4453 | } | 4478 | } |
@@ -5642,9 +5667,12 @@ static struct security_operations selinux_ops = { | |||
5642 | .secmark_refcount_inc = selinux_secmark_refcount_inc, | 5667 | .secmark_refcount_inc = selinux_secmark_refcount_inc, |
5643 | .secmark_refcount_dec = selinux_secmark_refcount_dec, | 5668 | .secmark_refcount_dec = selinux_secmark_refcount_dec, |
5644 | .req_classify_flow = selinux_req_classify_flow, | 5669 | .req_classify_flow = selinux_req_classify_flow, |
5670 | .tun_dev_alloc_security = selinux_tun_dev_alloc_security, | ||
5671 | .tun_dev_free_security = selinux_tun_dev_free_security, | ||
5645 | .tun_dev_create = selinux_tun_dev_create, | 5672 | .tun_dev_create = selinux_tun_dev_create, |
5646 | .tun_dev_post_create = selinux_tun_dev_post_create, | 5673 | .tun_dev_attach_queue = selinux_tun_dev_attach_queue, |
5647 | .tun_dev_attach = selinux_tun_dev_attach, | 5674 | .tun_dev_attach = selinux_tun_dev_attach, |
5675 | .tun_dev_open = selinux_tun_dev_open, | ||
5648 | 5676 | ||
5649 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 5677 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
5650 | .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, | 5678 | .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, |