diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 185 |
1 files changed, 135 insertions, 50 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 794c3ca49eac..6625699f497c 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -53,6 +53,7 @@ | |||
53 | #include <net/ip.h> /* for local_port_range[] */ | 53 | #include <net/ip.h> /* for local_port_range[] */ |
54 | #include <net/sock.h> | 54 | #include <net/sock.h> |
55 | #include <net/tcp.h> /* struct or_callable used in sock_rcv_skb */ | 55 | #include <net/tcp.h> /* struct or_callable used in sock_rcv_skb */ |
56 | #include <net/inet_connection_sock.h> | ||
56 | #include <net/net_namespace.h> | 57 | #include <net/net_namespace.h> |
57 | #include <net/netlabel.h> | 58 | #include <net/netlabel.h> |
58 | #include <linux/uaccess.h> | 59 | #include <linux/uaccess.h> |
@@ -95,10 +96,6 @@ | |||
95 | #include "audit.h" | 96 | #include "audit.h" |
96 | #include "avc_ss.h" | 97 | #include "avc_ss.h" |
97 | 98 | ||
98 | #define SB_TYPE_FMT "%s%s%s" | ||
99 | #define SB_SUBTYPE(sb) (sb->s_subtype && sb->s_subtype[0]) | ||
100 | #define SB_TYPE_ARGS(sb) sb->s_type->name, SB_SUBTYPE(sb) ? "." : "", SB_SUBTYPE(sb) ? sb->s_subtype : "" | ||
101 | |||
102 | extern struct security_operations *security_ops; | 99 | extern struct security_operations *security_ops; |
103 | 100 | ||
104 | /* SECMARK reference count */ | 101 | /* SECMARK reference count */ |
@@ -413,8 +410,8 @@ static int sb_finish_set_opts(struct super_block *sb) | |||
413 | the first boot of the SELinux kernel before we have | 410 | the first boot of the SELinux kernel before we have |
414 | assigned xattr values to the filesystem. */ | 411 | assigned xattr values to the filesystem. */ |
415 | if (!root_inode->i_op->getxattr) { | 412 | if (!root_inode->i_op->getxattr) { |
416 | printk(KERN_WARNING "SELinux: (dev %s, type "SB_TYPE_FMT") has no " | 413 | printk(KERN_WARNING "SELinux: (dev %s, type %s) has no " |
417 | "xattr support\n", sb->s_id, SB_TYPE_ARGS(sb)); | 414 | "xattr support\n", sb->s_id, sb->s_type->name); |
418 | rc = -EOPNOTSUPP; | 415 | rc = -EOPNOTSUPP; |
419 | goto out; | 416 | goto out; |
420 | } | 417 | } |
@@ -422,22 +419,22 @@ static int sb_finish_set_opts(struct super_block *sb) | |||
422 | if (rc < 0 && rc != -ENODATA) { | 419 | if (rc < 0 && rc != -ENODATA) { |
423 | if (rc == -EOPNOTSUPP) | 420 | if (rc == -EOPNOTSUPP) |
424 | printk(KERN_WARNING "SELinux: (dev %s, type " | 421 | printk(KERN_WARNING "SELinux: (dev %s, type " |
425 | SB_TYPE_FMT") has no security xattr handler\n", | 422 | "%s) has no security xattr handler\n", |
426 | sb->s_id, SB_TYPE_ARGS(sb)); | 423 | sb->s_id, sb->s_type->name); |
427 | else | 424 | else |
428 | printk(KERN_WARNING "SELinux: (dev %s, type " | 425 | printk(KERN_WARNING "SELinux: (dev %s, type " |
429 | SB_TYPE_FMT") getxattr errno %d\n", sb->s_id, | 426 | "%s) getxattr errno %d\n", sb->s_id, |
430 | SB_TYPE_ARGS(sb), -rc); | 427 | sb->s_type->name, -rc); |
431 | goto out; | 428 | goto out; |
432 | } | 429 | } |
433 | } | 430 | } |
434 | 431 | ||
435 | if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors)) | 432 | if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors)) |
436 | printk(KERN_ERR "SELinux: initialized (dev %s, type "SB_TYPE_FMT"), unknown behavior\n", | 433 | printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n", |
437 | sb->s_id, SB_TYPE_ARGS(sb)); | 434 | sb->s_id, sb->s_type->name); |
438 | else | 435 | else |
439 | printk(KERN_DEBUG "SELinux: initialized (dev %s, type "SB_TYPE_FMT"), %s\n", | 436 | printk(KERN_DEBUG "SELinux: initialized (dev %s, type %s), %s\n", |
440 | sb->s_id, SB_TYPE_ARGS(sb), | 437 | sb->s_id, sb->s_type->name, |
441 | labeling_behaviors[sbsec->behavior-1]); | 438 | labeling_behaviors[sbsec->behavior-1]); |
442 | 439 | ||
443 | sbsec->flags |= SE_SBINITIALIZED; | 440 | sbsec->flags |= SE_SBINITIALIZED; |
@@ -600,6 +597,7 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
600 | const struct cred *cred = current_cred(); | 597 | const struct cred *cred = current_cred(); |
601 | int rc = 0, i; | 598 | int rc = 0, i; |
602 | struct superblock_security_struct *sbsec = sb->s_security; | 599 | struct superblock_security_struct *sbsec = sb->s_security; |
600 | const char *name = sb->s_type->name; | ||
603 | struct inode *inode = sbsec->sb->s_root->d_inode; | 601 | struct inode *inode = sbsec->sb->s_root->d_inode; |
604 | struct inode_security_struct *root_isec = inode->i_security; | 602 | struct inode_security_struct *root_isec = inode->i_security; |
605 | u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; | 603 | u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; |
@@ -658,8 +656,8 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
658 | strlen(mount_options[i]), &sid); | 656 | strlen(mount_options[i]), &sid); |
659 | if (rc) { | 657 | if (rc) { |
660 | printk(KERN_WARNING "SELinux: security_context_to_sid" | 658 | printk(KERN_WARNING "SELinux: security_context_to_sid" |
661 | "(%s) failed for (dev %s, type "SB_TYPE_FMT") errno=%d\n", | 659 | "(%s) failed for (dev %s, type %s) errno=%d\n", |
662 | mount_options[i], sb->s_id, SB_TYPE_ARGS(sb), rc); | 660 | mount_options[i], sb->s_id, name, rc); |
663 | goto out; | 661 | goto out; |
664 | } | 662 | } |
665 | switch (flags[i]) { | 663 | switch (flags[i]) { |
@@ -806,8 +804,7 @@ out: | |||
806 | out_double_mount: | 804 | out_double_mount: |
807 | rc = -EINVAL; | 805 | rc = -EINVAL; |
808 | printk(KERN_WARNING "SELinux: mount invalid. Same superblock, different " | 806 | printk(KERN_WARNING "SELinux: mount invalid. Same superblock, different " |
809 | "security settings for (dev %s, type "SB_TYPE_FMT")\n", sb->s_id, | 807 | "security settings for (dev %s, type %s)\n", sb->s_id, name); |
810 | SB_TYPE_ARGS(sb)); | ||
811 | goto out; | 808 | goto out; |
812 | } | 809 | } |
813 | 810 | ||
@@ -2480,8 +2477,8 @@ static int selinux_sb_remount(struct super_block *sb, void *data) | |||
2480 | rc = security_context_to_sid(mount_options[i], len, &sid); | 2477 | rc = security_context_to_sid(mount_options[i], len, &sid); |
2481 | if (rc) { | 2478 | if (rc) { |
2482 | printk(KERN_WARNING "SELinux: security_context_to_sid" | 2479 | printk(KERN_WARNING "SELinux: security_context_to_sid" |
2483 | "(%s) failed for (dev %s, type "SB_TYPE_FMT") errno=%d\n", | 2480 | "(%s) failed for (dev %s, type %s) errno=%d\n", |
2484 | mount_options[i], sb->s_id, SB_TYPE_ARGS(sb), rc); | 2481 | mount_options[i], sb->s_id, sb->s_type->name, rc); |
2485 | goto out_free_opts; | 2482 | goto out_free_opts; |
2486 | } | 2483 | } |
2487 | rc = -EINVAL; | 2484 | rc = -EINVAL; |
@@ -2519,8 +2516,8 @@ out_free_secdata: | |||
2519 | return rc; | 2516 | return rc; |
2520 | out_bad_option: | 2517 | out_bad_option: |
2521 | printk(KERN_WARNING "SELinux: unable to change security options " | 2518 | printk(KERN_WARNING "SELinux: unable to change security options " |
2522 | "during remount (dev %s, type "SB_TYPE_FMT")\n", sb->s_id, | 2519 | "during remount (dev %s, type=%s)\n", sb->s_id, |
2523 | SB_TYPE_ARGS(sb)); | 2520 | sb->s_type->name); |
2524 | goto out_free_opts; | 2521 | goto out_free_opts; |
2525 | } | 2522 | } |
2526 | 2523 | ||
@@ -3828,7 +3825,7 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid) | |||
3828 | u32 nlbl_sid; | 3825 | u32 nlbl_sid; |
3829 | u32 nlbl_type; | 3826 | u32 nlbl_type; |
3830 | 3827 | ||
3831 | err = selinux_skb_xfrm_sid(skb, &xfrm_sid); | 3828 | err = selinux_xfrm_skb_sid(skb, &xfrm_sid); |
3832 | if (unlikely(err)) | 3829 | if (unlikely(err)) |
3833 | return -EACCES; | 3830 | return -EACCES; |
3834 | err = selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid); | 3831 | err = selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid); |
@@ -3846,6 +3843,30 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid) | |||
3846 | return 0; | 3843 | return 0; |
3847 | } | 3844 | } |
3848 | 3845 | ||
3846 | /** | ||
3847 | * selinux_conn_sid - Determine the child socket label for a connection | ||
3848 | * @sk_sid: the parent socket's SID | ||
3849 | * @skb_sid: the packet's SID | ||
3850 | * @conn_sid: the resulting connection SID | ||
3851 | * | ||
3852 | * If @skb_sid is valid then the user:role:type information from @sk_sid is | ||
3853 | * combined with the MLS information from @skb_sid in order to create | ||
3854 | * @conn_sid. If @skb_sid is not valid then then @conn_sid is simply a copy | ||
3855 | * of @sk_sid. Returns zero on success, negative values on failure. | ||
3856 | * | ||
3857 | */ | ||
3858 | static int selinux_conn_sid(u32 sk_sid, u32 skb_sid, u32 *conn_sid) | ||
3859 | { | ||
3860 | int err = 0; | ||
3861 | |||
3862 | if (skb_sid != SECSID_NULL) | ||
3863 | err = security_sid_mls_copy(sk_sid, skb_sid, conn_sid); | ||
3864 | else | ||
3865 | *conn_sid = sk_sid; | ||
3866 | |||
3867 | return err; | ||
3868 | } | ||
3869 | |||
3849 | /* socket security operations */ | 3870 | /* socket security operations */ |
3850 | 3871 | ||
3851 | static int socket_sockcreate_sid(const struct task_security_struct *tsec, | 3872 | static int socket_sockcreate_sid(const struct task_security_struct *tsec, |
@@ -4313,8 +4334,10 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
4313 | } | 4334 | } |
4314 | err = avc_has_perm(sk_sid, peer_sid, SECCLASS_PEER, | 4335 | err = avc_has_perm(sk_sid, peer_sid, SECCLASS_PEER, |
4315 | PEER__RECV, &ad); | 4336 | PEER__RECV, &ad); |
4316 | if (err) | 4337 | if (err) { |
4317 | selinux_netlbl_err(skb, err, 0); | 4338 | selinux_netlbl_err(skb, err, 0); |
4339 | return err; | ||
4340 | } | ||
4318 | } | 4341 | } |
4319 | 4342 | ||
4320 | if (secmark_active) { | 4343 | if (secmark_active) { |
@@ -4452,7 +4475,7 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb, | |||
4452 | struct sk_security_struct *sksec = sk->sk_security; | 4475 | struct sk_security_struct *sksec = sk->sk_security; |
4453 | int err; | 4476 | int err; |
4454 | u16 family = sk->sk_family; | 4477 | u16 family = sk->sk_family; |
4455 | u32 newsid; | 4478 | u32 connsid; |
4456 | u32 peersid; | 4479 | u32 peersid; |
4457 | 4480 | ||
4458 | /* handle mapped IPv4 packets arriving via IPv6 sockets */ | 4481 | /* handle mapped IPv4 packets arriving via IPv6 sockets */ |
@@ -4462,16 +4485,11 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb, | |||
4462 | err = selinux_skb_peerlbl_sid(skb, family, &peersid); | 4485 | err = selinux_skb_peerlbl_sid(skb, family, &peersid); |
4463 | if (err) | 4486 | if (err) |
4464 | return err; | 4487 | return err; |
4465 | if (peersid == SECSID_NULL) { | 4488 | err = selinux_conn_sid(sksec->sid, peersid, &connsid); |
4466 | req->secid = sksec->sid; | 4489 | if (err) |
4467 | req->peer_secid = SECSID_NULL; | 4490 | return err; |
4468 | } else { | 4491 | req->secid = connsid; |
4469 | err = security_sid_mls_copy(sksec->sid, peersid, &newsid); | 4492 | req->peer_secid = peersid; |
4470 | if (err) | ||
4471 | return err; | ||
4472 | req->secid = newsid; | ||
4473 | req->peer_secid = peersid; | ||
4474 | } | ||
4475 | 4493 | ||
4476 | return selinux_netlbl_inet_conn_request(req, family); | 4494 | return selinux_netlbl_inet_conn_request(req, family); |
4477 | } | 4495 | } |
@@ -4731,6 +4749,7 @@ static unsigned int selinux_ipv6_forward(const struct nf_hook_ops *ops, | |||
4731 | static unsigned int selinux_ip_output(struct sk_buff *skb, | 4749 | static unsigned int selinux_ip_output(struct sk_buff *skb, |
4732 | u16 family) | 4750 | u16 family) |
4733 | { | 4751 | { |
4752 | struct sock *sk; | ||
4734 | u32 sid; | 4753 | u32 sid; |
4735 | 4754 | ||
4736 | if (!netlbl_enabled()) | 4755 | if (!netlbl_enabled()) |
@@ -4739,8 +4758,27 @@ static unsigned int selinux_ip_output(struct sk_buff *skb, | |||
4739 | /* we do this in the LOCAL_OUT path and not the POST_ROUTING path | 4758 | /* we do this in the LOCAL_OUT path and not the POST_ROUTING path |
4740 | * because we want to make sure we apply the necessary labeling | 4759 | * because we want to make sure we apply the necessary labeling |
4741 | * before IPsec is applied so we can leverage AH protection */ | 4760 | * before IPsec is applied so we can leverage AH protection */ |
4742 | if (skb->sk) { | 4761 | sk = skb->sk; |
4743 | struct sk_security_struct *sksec = skb->sk->sk_security; | 4762 | if (sk) { |
4763 | struct sk_security_struct *sksec; | ||
4764 | |||
4765 | if (sk->sk_state == TCP_LISTEN) | ||
4766 | /* if the socket is the listening state then this | ||
4767 | * packet is a SYN-ACK packet which means it needs to | ||
4768 | * be labeled based on the connection/request_sock and | ||
4769 | * not the parent socket. unfortunately, we can't | ||
4770 | * lookup the request_sock yet as it isn't queued on | ||
4771 | * the parent socket until after the SYN-ACK is sent. | ||
4772 | * the "solution" is to simply pass the packet as-is | ||
4773 | * as any IP option based labeling should be copied | ||
4774 | * from the initial connection request (in the IP | ||
4775 | * layer). it is far from ideal, but until we get a | ||
4776 | * security label in the packet itself this is the | ||
4777 | * best we can do. */ | ||
4778 | return NF_ACCEPT; | ||
4779 | |||
4780 | /* standard practice, label using the parent socket */ | ||
4781 | sksec = sk->sk_security; | ||
4744 | sid = sksec->sid; | 4782 | sid = sksec->sid; |
4745 | } else | 4783 | } else |
4746 | sid = SECINITSID_KERNEL; | 4784 | sid = SECINITSID_KERNEL; |
@@ -4810,27 +4848,36 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, | |||
4810 | * as fast and as clean as possible. */ | 4848 | * as fast and as clean as possible. */ |
4811 | if (!selinux_policycap_netpeer) | 4849 | if (!selinux_policycap_netpeer) |
4812 | return selinux_ip_postroute_compat(skb, ifindex, family); | 4850 | return selinux_ip_postroute_compat(skb, ifindex, family); |
4851 | |||
4852 | secmark_active = selinux_secmark_enabled(); | ||
4853 | peerlbl_active = selinux_peerlbl_enabled(); | ||
4854 | if (!secmark_active && !peerlbl_active) | ||
4855 | return NF_ACCEPT; | ||
4856 | |||
4857 | sk = skb->sk; | ||
4858 | |||
4813 | #ifdef CONFIG_XFRM | 4859 | #ifdef CONFIG_XFRM |
4814 | /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec | 4860 | /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec |
4815 | * packet transformation so allow the packet to pass without any checks | 4861 | * packet transformation so allow the packet to pass without any checks |
4816 | * since we'll have another chance to perform access control checks | 4862 | * since we'll have another chance to perform access control checks |
4817 | * when the packet is on it's final way out. | 4863 | * when the packet is on it's final way out. |
4818 | * NOTE: there appear to be some IPv6 multicast cases where skb->dst | 4864 | * NOTE: there appear to be some IPv6 multicast cases where skb->dst |
4819 | * is NULL, in this case go ahead and apply access control. */ | 4865 | * is NULL, in this case go ahead and apply access control. |
4820 | if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL) | 4866 | * NOTE: if this is a local socket (skb->sk != NULL) that is in the |
4867 | * TCP listening state we cannot wait until the XFRM processing | ||
4868 | * is done as we will miss out on the SA label if we do; | ||
4869 | * unfortunately, this means more work, but it is only once per | ||
4870 | * connection. */ | ||
4871 | if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL && | ||
4872 | !(sk != NULL && sk->sk_state == TCP_LISTEN)) | ||
4821 | return NF_ACCEPT; | 4873 | return NF_ACCEPT; |
4822 | #endif | 4874 | #endif |
4823 | secmark_active = selinux_secmark_enabled(); | ||
4824 | peerlbl_active = selinux_peerlbl_enabled(); | ||
4825 | if (!secmark_active && !peerlbl_active) | ||
4826 | return NF_ACCEPT; | ||
4827 | 4875 | ||
4828 | /* if the packet is being forwarded then get the peer label from the | ||
4829 | * packet itself; otherwise check to see if it is from a local | ||
4830 | * application or the kernel, if from an application get the peer label | ||
4831 | * from the sending socket, otherwise use the kernel's sid */ | ||
4832 | sk = skb->sk; | ||
4833 | if (sk == NULL) { | 4876 | if (sk == NULL) { |
4877 | /* Without an associated socket the packet is either coming | ||
4878 | * from the kernel or it is being forwarded; check the packet | ||
4879 | * to determine which and if the packet is being forwarded | ||
4880 | * query the packet directly to determine the security label. */ | ||
4834 | if (skb->skb_iif) { | 4881 | if (skb->skb_iif) { |
4835 | secmark_perm = PACKET__FORWARD_OUT; | 4882 | secmark_perm = PACKET__FORWARD_OUT; |
4836 | if (selinux_skb_peerlbl_sid(skb, family, &peer_sid)) | 4883 | if (selinux_skb_peerlbl_sid(skb, family, &peer_sid)) |
@@ -4839,7 +4886,45 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, | |||
4839 | secmark_perm = PACKET__SEND; | 4886 | secmark_perm = PACKET__SEND; |
4840 | peer_sid = SECINITSID_KERNEL; | 4887 | peer_sid = SECINITSID_KERNEL; |
4841 | } | 4888 | } |
4889 | } else if (sk->sk_state == TCP_LISTEN) { | ||
4890 | /* Locally generated packet but the associated socket is in the | ||
4891 | * listening state which means this is a SYN-ACK packet. In | ||
4892 | * this particular case the correct security label is assigned | ||
4893 | * to the connection/request_sock but unfortunately we can't | ||
4894 | * query the request_sock as it isn't queued on the parent | ||
4895 | * socket until after the SYN-ACK packet is sent; the only | ||
4896 | * viable choice is to regenerate the label like we do in | ||
4897 | * selinux_inet_conn_request(). See also selinux_ip_output() | ||
4898 | * for similar problems. */ | ||
4899 | u32 skb_sid; | ||
4900 | struct sk_security_struct *sksec = sk->sk_security; | ||
4901 | if (selinux_skb_peerlbl_sid(skb, family, &skb_sid)) | ||
4902 | return NF_DROP; | ||
4903 | /* At this point, if the returned skb peerlbl is SECSID_NULL | ||
4904 | * and the packet has been through at least one XFRM | ||
4905 | * transformation then we must be dealing with the "final" | ||
4906 | * form of labeled IPsec packet; since we've already applied | ||
4907 | * all of our access controls on this packet we can safely | ||
4908 | * pass the packet. */ | ||
4909 | if (skb_sid == SECSID_NULL) { | ||
4910 | switch (family) { | ||
4911 | case PF_INET: | ||
4912 | if (IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) | ||
4913 | return NF_ACCEPT; | ||
4914 | break; | ||
4915 | case PF_INET6: | ||
4916 | if (IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) | ||
4917 | return NF_ACCEPT; | ||
4918 | default: | ||
4919 | return NF_DROP_ERR(-ECONNREFUSED); | ||
4920 | } | ||
4921 | } | ||
4922 | if (selinux_conn_sid(sksec->sid, skb_sid, &peer_sid)) | ||
4923 | return NF_DROP; | ||
4924 | secmark_perm = PACKET__SEND; | ||
4842 | } else { | 4925 | } else { |
4926 | /* Locally generated packet, fetch the security label from the | ||
4927 | * associated socket. */ | ||
4843 | struct sk_security_struct *sksec = sk->sk_security; | 4928 | struct sk_security_struct *sksec = sk->sk_security; |
4844 | peer_sid = sksec->sid; | 4929 | peer_sid = sksec->sid; |
4845 | secmark_perm = PACKET__SEND; | 4930 | secmark_perm = PACKET__SEND; |
@@ -5503,11 +5588,11 @@ static int selinux_setprocattr(struct task_struct *p, | |||
5503 | /* Check for ptracing, and update the task SID if ok. | 5588 | /* Check for ptracing, and update the task SID if ok. |
5504 | Otherwise, leave SID unchanged and fail. */ | 5589 | Otherwise, leave SID unchanged and fail. */ |
5505 | ptsid = 0; | 5590 | ptsid = 0; |
5506 | task_lock(p); | 5591 | rcu_read_lock(); |
5507 | tracer = ptrace_parent(p); | 5592 | tracer = ptrace_parent(p); |
5508 | if (tracer) | 5593 | if (tracer) |
5509 | ptsid = task_sid(tracer); | 5594 | ptsid = task_sid(tracer); |
5510 | task_unlock(p); | 5595 | rcu_read_unlock(); |
5511 | 5596 | ||
5512 | if (tracer) { | 5597 | if (tracer) { |
5513 | error = avc_has_perm(ptsid, sid, SECCLASS_PROCESS, | 5598 | error = avc_has_perm(ptsid, sid, SECCLASS_PROCESS, |