diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 165 |
1 files changed, 103 insertions, 62 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index d39b59cf8a08..34f2d46c7984 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -80,6 +80,7 @@ | |||
80 | #include "objsec.h" | 80 | #include "objsec.h" |
81 | #include "netif.h" | 81 | #include "netif.h" |
82 | #include "netnode.h" | 82 | #include "netnode.h" |
83 | #include "netport.h" | ||
83 | #include "xfrm.h" | 84 | #include "xfrm.h" |
84 | #include "netlabel.h" | 85 | #include "netlabel.h" |
85 | 86 | ||
@@ -161,8 +162,7 @@ static int task_alloc_security(struct task_struct *task) | |||
161 | if (!tsec) | 162 | if (!tsec) |
162 | return -ENOMEM; | 163 | return -ENOMEM; |
163 | 164 | ||
164 | tsec->task = task; | 165 | tsec->osid = tsec->sid = SECINITSID_UNLABELED; |
165 | tsec->osid = tsec->sid = tsec->ptrace_sid = SECINITSID_UNLABELED; | ||
166 | task->security = tsec; | 166 | task->security = tsec; |
167 | 167 | ||
168 | return 0; | 168 | return 0; |
@@ -218,7 +218,6 @@ static int file_alloc_security(struct file *file) | |||
218 | if (!fsec) | 218 | if (!fsec) |
219 | return -ENOMEM; | 219 | return -ENOMEM; |
220 | 220 | ||
221 | fsec->file = file; | ||
222 | fsec->sid = tsec->sid; | 221 | fsec->sid = tsec->sid; |
223 | fsec->fown_sid = tsec->sid; | 222 | fsec->fown_sid = tsec->sid; |
224 | file->f_security = fsec; | 223 | file->f_security = fsec; |
@@ -275,12 +274,11 @@ static int sk_alloc_security(struct sock *sk, int family, gfp_t priority) | |||
275 | if (!ssec) | 274 | if (!ssec) |
276 | return -ENOMEM; | 275 | return -ENOMEM; |
277 | 276 | ||
278 | ssec->sk = sk; | ||
279 | ssec->peer_sid = SECINITSID_UNLABELED; | 277 | ssec->peer_sid = SECINITSID_UNLABELED; |
280 | ssec->sid = SECINITSID_UNLABELED; | 278 | ssec->sid = SECINITSID_UNLABELED; |
281 | sk->sk_security = ssec; | 279 | sk->sk_security = ssec; |
282 | 280 | ||
283 | selinux_netlbl_sk_security_init(ssec, family); | 281 | selinux_netlbl_sk_security_reset(ssec, family); |
284 | 282 | ||
285 | return 0; | 283 | return 0; |
286 | } | 284 | } |
@@ -324,10 +322,10 @@ enum { | |||
324 | }; | 322 | }; |
325 | 323 | ||
326 | static match_table_t tokens = { | 324 | static match_table_t tokens = { |
327 | {Opt_context, "context=%s"}, | 325 | {Opt_context, CONTEXT_STR "%s"}, |
328 | {Opt_fscontext, "fscontext=%s"}, | 326 | {Opt_fscontext, FSCONTEXT_STR "%s"}, |
329 | {Opt_defcontext, "defcontext=%s"}, | 327 | {Opt_defcontext, DEFCONTEXT_STR "%s"}, |
330 | {Opt_rootcontext, "rootcontext=%s"}, | 328 | {Opt_rootcontext, ROOTCONTEXT_STR "%s"}, |
331 | {Opt_error, NULL}, | 329 | {Opt_error, NULL}, |
332 | }; | 330 | }; |
333 | 331 | ||
@@ -671,7 +669,7 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
671 | rc = security_fs_use(sb->s_type->name, &sbsec->behavior, &sbsec->sid); | 669 | rc = security_fs_use(sb->s_type->name, &sbsec->behavior, &sbsec->sid); |
672 | if (rc) { | 670 | if (rc) { |
673 | printk(KERN_WARNING "%s: security_fs_use(%s) returned %d\n", | 671 | printk(KERN_WARNING "%s: security_fs_use(%s) returned %d\n", |
674 | __FUNCTION__, sb->s_type->name, rc); | 672 | __func__, sb->s_type->name, rc); |
675 | goto out; | 673 | goto out; |
676 | } | 674 | } |
677 | 675 | ||
@@ -1137,7 +1135,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
1137 | } | 1135 | } |
1138 | if (!dentry) { | 1136 | if (!dentry) { |
1139 | printk(KERN_WARNING "%s: no dentry for dev=%s " | 1137 | printk(KERN_WARNING "%s: no dentry for dev=%s " |
1140 | "ino=%ld\n", __FUNCTION__, inode->i_sb->s_id, | 1138 | "ino=%ld\n", __func__, inode->i_sb->s_id, |
1141 | inode->i_ino); | 1139 | inode->i_ino); |
1142 | goto out_unlock; | 1140 | goto out_unlock; |
1143 | } | 1141 | } |
@@ -1175,7 +1173,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
1175 | if (rc < 0) { | 1173 | if (rc < 0) { |
1176 | if (rc != -ENODATA) { | 1174 | if (rc != -ENODATA) { |
1177 | printk(KERN_WARNING "%s: getxattr returned " | 1175 | printk(KERN_WARNING "%s: getxattr returned " |
1178 | "%d for dev=%s ino=%ld\n", __FUNCTION__, | 1176 | "%d for dev=%s ino=%ld\n", __func__, |
1179 | -rc, inode->i_sb->s_id, inode->i_ino); | 1177 | -rc, inode->i_sb->s_id, inode->i_ino); |
1180 | kfree(context); | 1178 | kfree(context); |
1181 | goto out_unlock; | 1179 | goto out_unlock; |
@@ -1190,7 +1188,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
1190 | if (rc) { | 1188 | if (rc) { |
1191 | printk(KERN_WARNING "%s: context_to_sid(%s) " | 1189 | printk(KERN_WARNING "%s: context_to_sid(%s) " |
1192 | "returned %d for dev=%s ino=%ld\n", | 1190 | "returned %d for dev=%s ino=%ld\n", |
1193 | __FUNCTION__, context, -rc, | 1191 | __func__, context, -rc, |
1194 | inode->i_sb->s_id, inode->i_ino); | 1192 | inode->i_sb->s_id, inode->i_ino); |
1195 | kfree(context); | 1193 | kfree(context); |
1196 | /* Leave with the unlabeled SID */ | 1194 | /* Leave with the unlabeled SID */ |
@@ -1618,6 +1616,35 @@ static inline u32 file_mask_to_av(int mode, int mask) | |||
1618 | return av; | 1616 | return av; |
1619 | } | 1617 | } |
1620 | 1618 | ||
1619 | /* | ||
1620 | * Convert a file mask to an access vector and include the correct open | ||
1621 | * open permission. | ||
1622 | */ | ||
1623 | static inline u32 open_file_mask_to_av(int mode, int mask) | ||
1624 | { | ||
1625 | u32 av = file_mask_to_av(mode, mask); | ||
1626 | |||
1627 | if (selinux_policycap_openperm) { | ||
1628 | /* | ||
1629 | * lnk files and socks do not really have an 'open' | ||
1630 | */ | ||
1631 | if (S_ISREG(mode)) | ||
1632 | av |= FILE__OPEN; | ||
1633 | else if (S_ISCHR(mode)) | ||
1634 | av |= CHR_FILE__OPEN; | ||
1635 | else if (S_ISBLK(mode)) | ||
1636 | av |= BLK_FILE__OPEN; | ||
1637 | else if (S_ISFIFO(mode)) | ||
1638 | av |= FIFO_FILE__OPEN; | ||
1639 | else if (S_ISDIR(mode)) | ||
1640 | av |= DIR__OPEN; | ||
1641 | else | ||
1642 | printk(KERN_ERR "SELinux: WARNING: inside open_file_to_av " | ||
1643 | "with unknown mode:%x\n", mode); | ||
1644 | } | ||
1645 | return av; | ||
1646 | } | ||
1647 | |||
1621 | /* Convert a Linux file to an access vector. */ | 1648 | /* Convert a Linux file to an access vector. */ |
1622 | static inline u32 file_to_av(struct file *file) | 1649 | static inline u32 file_to_av(struct file *file) |
1623 | { | 1650 | { |
@@ -1645,19 +1672,13 @@ static inline u32 file_to_av(struct file *file) | |||
1645 | 1672 | ||
1646 | static int selinux_ptrace(struct task_struct *parent, struct task_struct *child) | 1673 | static int selinux_ptrace(struct task_struct *parent, struct task_struct *child) |
1647 | { | 1674 | { |
1648 | struct task_security_struct *psec = parent->security; | ||
1649 | struct task_security_struct *csec = child->security; | ||
1650 | int rc; | 1675 | int rc; |
1651 | 1676 | ||
1652 | rc = secondary_ops->ptrace(parent,child); | 1677 | rc = secondary_ops->ptrace(parent,child); |
1653 | if (rc) | 1678 | if (rc) |
1654 | return rc; | 1679 | return rc; |
1655 | 1680 | ||
1656 | rc = task_has_perm(parent, child, PROCESS__PTRACE); | 1681 | return task_has_perm(parent, child, PROCESS__PTRACE); |
1657 | /* Save the SID of the tracing process for later use in apply_creds. */ | ||
1658 | if (!(child->ptrace & PT_PTRACED) && !rc) | ||
1659 | csec->ptrace_sid = psec->sid; | ||
1660 | return rc; | ||
1661 | } | 1682 | } |
1662 | 1683 | ||
1663 | static int selinux_capget(struct task_struct *target, kernel_cap_t *effective, | 1684 | static int selinux_capget(struct task_struct *target, kernel_cap_t *effective, |
@@ -1879,6 +1900,22 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages) | |||
1879 | return __vm_enough_memory(mm, pages, cap_sys_admin); | 1900 | return __vm_enough_memory(mm, pages, cap_sys_admin); |
1880 | } | 1901 | } |
1881 | 1902 | ||
1903 | /** | ||
1904 | * task_tracer_task - return the task that is tracing the given task | ||
1905 | * @task: task to consider | ||
1906 | * | ||
1907 | * Returns NULL if noone is tracing @task, or the &struct task_struct | ||
1908 | * pointer to its tracer. | ||
1909 | * | ||
1910 | * Must be called under rcu_read_lock(). | ||
1911 | */ | ||
1912 | static struct task_struct *task_tracer_task(struct task_struct *task) | ||
1913 | { | ||
1914 | if (task->ptrace & PT_PTRACED) | ||
1915 | return rcu_dereference(task->parent); | ||
1916 | return NULL; | ||
1917 | } | ||
1918 | |||
1882 | /* binprm security operations */ | 1919 | /* binprm security operations */ |
1883 | 1920 | ||
1884 | static int selinux_bprm_alloc_security(struct linux_binprm *bprm) | 1921 | static int selinux_bprm_alloc_security(struct linux_binprm *bprm) |
@@ -1889,7 +1926,6 @@ static int selinux_bprm_alloc_security(struct linux_binprm *bprm) | |||
1889 | if (!bsec) | 1926 | if (!bsec) |
1890 | return -ENOMEM; | 1927 | return -ENOMEM; |
1891 | 1928 | ||
1892 | bsec->bprm = bprm; | ||
1893 | bsec->sid = SECINITSID_UNLABELED; | 1929 | bsec->sid = SECINITSID_UNLABELED; |
1894 | bsec->set = 0; | 1930 | bsec->set = 0; |
1895 | 1931 | ||
@@ -2126,12 +2162,25 @@ static void selinux_bprm_apply_creds(struct linux_binprm *bprm, int unsafe) | |||
2126 | /* Check for ptracing, and update the task SID if ok. | 2162 | /* Check for ptracing, and update the task SID if ok. |
2127 | Otherwise, leave SID unchanged and kill. */ | 2163 | Otherwise, leave SID unchanged and kill. */ |
2128 | if (unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) { | 2164 | if (unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) { |
2129 | rc = avc_has_perm(tsec->ptrace_sid, sid, | 2165 | struct task_struct *tracer; |
2130 | SECCLASS_PROCESS, PROCESS__PTRACE, | 2166 | struct task_security_struct *sec; |
2131 | NULL); | 2167 | u32 ptsid = 0; |
2132 | if (rc) { | 2168 | |
2133 | bsec->unsafe = 1; | 2169 | rcu_read_lock(); |
2134 | return; | 2170 | tracer = task_tracer_task(current); |
2171 | if (likely(tracer != NULL)) { | ||
2172 | sec = tracer->security; | ||
2173 | ptsid = sec->sid; | ||
2174 | } | ||
2175 | rcu_read_unlock(); | ||
2176 | |||
2177 | if (ptsid != 0) { | ||
2178 | rc = avc_has_perm(ptsid, sid, SECCLASS_PROCESS, | ||
2179 | PROCESS__PTRACE, NULL); | ||
2180 | if (rc) { | ||
2181 | bsec->unsafe = 1; | ||
2182 | return; | ||
2183 | } | ||
2135 | } | 2184 | } |
2136 | } | 2185 | } |
2137 | tsec->sid = sid; | 2186 | tsec->sid = sid; |
@@ -2239,10 +2288,10 @@ static inline int match_prefix(char *prefix, int plen, char *option, int olen) | |||
2239 | 2288 | ||
2240 | static inline int selinux_option(char *option, int len) | 2289 | static inline int selinux_option(char *option, int len) |
2241 | { | 2290 | { |
2242 | return (match_prefix("context=", sizeof("context=")-1, option, len) || | 2291 | return (match_prefix(CONTEXT_STR, sizeof(CONTEXT_STR)-1, option, len) || |
2243 | match_prefix("fscontext=", sizeof("fscontext=")-1, option, len) || | 2292 | match_prefix(FSCONTEXT_STR, sizeof(FSCONTEXT_STR)-1, option, len) || |
2244 | match_prefix("defcontext=", sizeof("defcontext=")-1, option, len) || | 2293 | match_prefix(DEFCONTEXT_STR, sizeof(DEFCONTEXT_STR)-1, option, len) || |
2245 | match_prefix("rootcontext=", sizeof("rootcontext=")-1, option, len)); | 2294 | match_prefix(ROOTCONTEXT_STR, sizeof(ROOTCONTEXT_STR)-1, option, len)); |
2246 | } | 2295 | } |
2247 | 2296 | ||
2248 | static inline void take_option(char **to, char *from, int *first, int len) | 2297 | static inline void take_option(char **to, char *from, int *first, int len) |
@@ -2412,7 +2461,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, | |||
2412 | printk(KERN_WARNING "%s: " | 2461 | printk(KERN_WARNING "%s: " |
2413 | "security_transition_sid failed, rc=%d (dev=%s " | 2462 | "security_transition_sid failed, rc=%d (dev=%s " |
2414 | "ino=%ld)\n", | 2463 | "ino=%ld)\n", |
2415 | __FUNCTION__, | 2464 | __func__, |
2416 | -rc, inode->i_sb->s_id, inode->i_ino); | 2465 | -rc, inode->i_sb->s_id, inode->i_ino); |
2417 | return rc; | 2466 | return rc; |
2418 | } | 2467 | } |
@@ -2536,7 +2585,7 @@ static int selinux_inode_permission(struct inode *inode, int mask, | |||
2536 | } | 2585 | } |
2537 | 2586 | ||
2538 | return inode_has_perm(current, inode, | 2587 | return inode_has_perm(current, inode, |
2539 | file_mask_to_av(inode->i_mode, mask), NULL); | 2588 | open_file_mask_to_av(inode->i_mode, mask), NULL); |
2540 | } | 2589 | } |
2541 | 2590 | ||
2542 | static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) | 2591 | static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) |
@@ -2646,7 +2695,7 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, char *name, | |||
2646 | rc = security_context_to_sid(value, size, &newsid); | 2695 | rc = security_context_to_sid(value, size, &newsid); |
2647 | if (rc) { | 2696 | if (rc) { |
2648 | printk(KERN_WARNING "%s: unable to obtain SID for context " | 2697 | printk(KERN_WARNING "%s: unable to obtain SID for context " |
2649 | "%s, rc=%d\n", __FUNCTION__, (char*)value, -rc); | 2698 | "%s, rc=%d\n", __func__, (char *)value, -rc); |
2650 | return; | 2699 | return; |
2651 | } | 2700 | } |
2652 | 2701 | ||
@@ -3087,11 +3136,6 @@ static int selinux_task_alloc_security(struct task_struct *tsk) | |||
3087 | tsec2->keycreate_sid = tsec1->keycreate_sid; | 3136 | tsec2->keycreate_sid = tsec1->keycreate_sid; |
3088 | tsec2->sockcreate_sid = tsec1->sockcreate_sid; | 3137 | tsec2->sockcreate_sid = tsec1->sockcreate_sid; |
3089 | 3138 | ||
3090 | /* Retain ptracer SID across fork, if any. | ||
3091 | This will be reset by the ptrace hook upon any | ||
3092 | subsequent ptrace_attach operations. */ | ||
3093 | tsec2->ptrace_sid = tsec1->ptrace_sid; | ||
3094 | |||
3095 | return 0; | 3139 | return 0; |
3096 | } | 3140 | } |
3097 | 3141 | ||
@@ -3627,10 +3671,8 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
3627 | inet_get_local_port_range(&low, &high); | 3671 | inet_get_local_port_range(&low, &high); |
3628 | 3672 | ||
3629 | if (snum < max(PROT_SOCK, low) || snum > high) { | 3673 | if (snum < max(PROT_SOCK, low) || snum > high) { |
3630 | err = security_port_sid(sk->sk_family, | 3674 | err = sel_netport_sid(sk->sk_protocol, |
3631 | sk->sk_type, | 3675 | snum, &sid); |
3632 | sk->sk_protocol, snum, | ||
3633 | &sid); | ||
3634 | if (err) | 3676 | if (err) |
3635 | goto out; | 3677 | goto out; |
3636 | AVC_AUDIT_DATA_INIT(&ad,NET); | 3678 | AVC_AUDIT_DATA_INIT(&ad,NET); |
@@ -3718,8 +3760,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, | |||
3718 | snum = ntohs(addr6->sin6_port); | 3760 | snum = ntohs(addr6->sin6_port); |
3719 | } | 3761 | } |
3720 | 3762 | ||
3721 | err = security_port_sid(sk->sk_family, sk->sk_type, | 3763 | err = sel_netport_sid(sk->sk_protocol, snum, &sid); |
3722 | sk->sk_protocol, snum, &sid); | ||
3723 | if (err) | 3764 | if (err) |
3724 | goto out; | 3765 | goto out; |
3725 | 3766 | ||
@@ -3950,9 +3991,8 @@ static int selinux_sock_rcv_skb_iptables_compat(struct sock *sk, | |||
3950 | 3991 | ||
3951 | if (!recv_perm) | 3992 | if (!recv_perm) |
3952 | return 0; | 3993 | return 0; |
3953 | err = security_port_sid(sk->sk_family, sk->sk_type, | 3994 | err = sel_netport_sid(sk->sk_protocol, |
3954 | sk->sk_protocol, ntohs(ad->u.net.sport), | 3995 | ntohs(ad->u.net.sport), &port_sid); |
3955 | &port_sid); | ||
3956 | if (unlikely(err)) { | 3996 | if (unlikely(err)) { |
3957 | printk(KERN_WARNING | 3997 | printk(KERN_WARNING |
3958 | "SELinux: failure in" | 3998 | "SELinux: failure in" |
@@ -4139,7 +4179,7 @@ static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk) | |||
4139 | newssec->peer_sid = ssec->peer_sid; | 4179 | newssec->peer_sid = ssec->peer_sid; |
4140 | newssec->sclass = ssec->sclass; | 4180 | newssec->sclass = ssec->sclass; |
4141 | 4181 | ||
4142 | selinux_netlbl_sk_security_clone(ssec, newssec); | 4182 | selinux_netlbl_sk_security_reset(newssec, newsk->sk_family); |
4143 | } | 4183 | } |
4144 | 4184 | ||
4145 | static void selinux_sk_getsecid(struct sock *sk, u32 *secid) | 4185 | static void selinux_sk_getsecid(struct sock *sk, u32 *secid) |
@@ -4373,9 +4413,8 @@ static int selinux_ip_postroute_iptables_compat(struct sock *sk, | |||
4373 | if (send_perm != 0) | 4413 | if (send_perm != 0) |
4374 | return 0; | 4414 | return 0; |
4375 | 4415 | ||
4376 | err = security_port_sid(sk->sk_family, sk->sk_type, | 4416 | err = sel_netport_sid(sk->sk_protocol, |
4377 | sk->sk_protocol, ntohs(ad->u.net.dport), | 4417 | ntohs(ad->u.net.dport), &port_sid); |
4378 | &port_sid); | ||
4379 | if (unlikely(err)) { | 4418 | if (unlikely(err)) { |
4380 | printk(KERN_WARNING | 4419 | printk(KERN_WARNING |
4381 | "SELinux: failure in" | 4420 | "SELinux: failure in" |
@@ -4561,7 +4600,6 @@ static int ipc_alloc_security(struct task_struct *task, | |||
4561 | return -ENOMEM; | 4600 | return -ENOMEM; |
4562 | 4601 | ||
4563 | isec->sclass = sclass; | 4602 | isec->sclass = sclass; |
4564 | isec->ipc_perm = perm; | ||
4565 | isec->sid = tsec->sid; | 4603 | isec->sid = tsec->sid; |
4566 | perm->security = isec; | 4604 | perm->security = isec; |
4567 | 4605 | ||
@@ -4583,7 +4621,6 @@ static int msg_msg_alloc_security(struct msg_msg *msg) | |||
4583 | if (!msec) | 4621 | if (!msec) |
4584 | return -ENOMEM; | 4622 | return -ENOMEM; |
4585 | 4623 | ||
4586 | msec->msg = msg; | ||
4587 | msec->sid = SECINITSID_UNLABELED; | 4624 | msec->sid = SECINITSID_UNLABELED; |
4588 | msg->security = msec; | 4625 | msg->security = msec; |
4589 | 4626 | ||
@@ -4994,14 +5031,14 @@ static int selinux_register_security (const char *name, struct security_operatio | |||
4994 | { | 5031 | { |
4995 | if (secondary_ops != original_ops) { | 5032 | if (secondary_ops != original_ops) { |
4996 | printk(KERN_ERR "%s: There is already a secondary security " | 5033 | printk(KERN_ERR "%s: There is already a secondary security " |
4997 | "module registered.\n", __FUNCTION__); | 5034 | "module registered.\n", __func__); |
4998 | return -EINVAL; | 5035 | return -EINVAL; |
4999 | } | 5036 | } |
5000 | 5037 | ||
5001 | secondary_ops = ops; | 5038 | secondary_ops = ops; |
5002 | 5039 | ||
5003 | printk(KERN_INFO "%s: Registering secondary module %s\n", | 5040 | printk(KERN_INFO "%s: Registering secondary module %s\n", |
5004 | __FUNCTION__, | 5041 | __func__, |
5005 | name); | 5042 | name); |
5006 | 5043 | ||
5007 | return 0; | 5044 | return 0; |
@@ -5057,6 +5094,7 @@ static int selinux_setprocattr(struct task_struct *p, | |||
5057 | char *name, void *value, size_t size) | 5094 | char *name, void *value, size_t size) |
5058 | { | 5095 | { |
5059 | struct task_security_struct *tsec; | 5096 | struct task_security_struct *tsec; |
5097 | struct task_struct *tracer; | ||
5060 | u32 sid = 0; | 5098 | u32 sid = 0; |
5061 | int error; | 5099 | int error; |
5062 | char *str = value; | 5100 | char *str = value; |
@@ -5145,18 +5183,24 @@ static int selinux_setprocattr(struct task_struct *p, | |||
5145 | /* Check for ptracing, and update the task SID if ok. | 5183 | /* Check for ptracing, and update the task SID if ok. |
5146 | Otherwise, leave SID unchanged and fail. */ | 5184 | Otherwise, leave SID unchanged and fail. */ |
5147 | task_lock(p); | 5185 | task_lock(p); |
5148 | if (p->ptrace & PT_PTRACED) { | 5186 | rcu_read_lock(); |
5149 | error = avc_has_perm_noaudit(tsec->ptrace_sid, sid, | 5187 | tracer = task_tracer_task(p); |
5188 | if (tracer != NULL) { | ||
5189 | struct task_security_struct *ptsec = tracer->security; | ||
5190 | u32 ptsid = ptsec->sid; | ||
5191 | rcu_read_unlock(); | ||
5192 | error = avc_has_perm_noaudit(ptsid, sid, | ||
5150 | SECCLASS_PROCESS, | 5193 | SECCLASS_PROCESS, |
5151 | PROCESS__PTRACE, 0, &avd); | 5194 | PROCESS__PTRACE, 0, &avd); |
5152 | if (!error) | 5195 | if (!error) |
5153 | tsec->sid = sid; | 5196 | tsec->sid = sid; |
5154 | task_unlock(p); | 5197 | task_unlock(p); |
5155 | avc_audit(tsec->ptrace_sid, sid, SECCLASS_PROCESS, | 5198 | avc_audit(ptsid, sid, SECCLASS_PROCESS, |
5156 | PROCESS__PTRACE, &avd, error, NULL); | 5199 | PROCESS__PTRACE, &avd, error, NULL); |
5157 | if (error) | 5200 | if (error) |
5158 | return error; | 5201 | return error; |
5159 | } else { | 5202 | } else { |
5203 | rcu_read_unlock(); | ||
5160 | tsec->sid = sid; | 5204 | tsec->sid = sid; |
5161 | task_unlock(p); | 5205 | task_unlock(p); |
5162 | } | 5206 | } |
@@ -5194,7 +5238,6 @@ static int selinux_key_alloc(struct key *k, struct task_struct *tsk, | |||
5194 | if (!ksec) | 5238 | if (!ksec) |
5195 | return -ENOMEM; | 5239 | return -ENOMEM; |
5196 | 5240 | ||
5197 | ksec->obj = k; | ||
5198 | if (tsec->keycreate_sid) | 5241 | if (tsec->keycreate_sid) |
5199 | ksec->sid = tsec->keycreate_sid; | 5242 | ksec->sid = tsec->keycreate_sid; |
5200 | else | 5243 | else |
@@ -5631,5 +5674,3 @@ int selinux_disable(void) | |||
5631 | return 0; | 5674 | return 0; |
5632 | } | 5675 | } |
5633 | #endif | 5676 | #endif |
5634 | |||
5635 | |||