aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c165
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
326static match_table_t tokens = { 324static 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 */
1623static 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. */
1622static inline u32 file_to_av(struct file *file) 1649static 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
1646static int selinux_ptrace(struct task_struct *parent, struct task_struct *child) 1673static 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
1663static int selinux_capget(struct task_struct *target, kernel_cap_t *effective, 1684static 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 */
1912static 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
1884static int selinux_bprm_alloc_security(struct linux_binprm *bprm) 1921static 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
2240static inline int selinux_option(char *option, int len) 2289static 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
2248static inline void take_option(char **to, char *from, int *first, int len) 2297static 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
2542static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) 2591static 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
4145static void selinux_sk_getsecid(struct sock *sk, u32 *secid) 4185static 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