diff options
| author | Ingo Molnar <mingo@elte.hu> | 2008-10-12 06:43:21 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2008-10-12 06:43:21 -0400 |
| commit | acbaa41a780490c791492c41144c774c04875af1 (patch) | |
| tree | 31f1f046875eb071e2aed031e5d9d1584742314f /security/selinux/hooks.c | |
| parent | 8d89adf44cf750e49691ba5b744b2ad77a05e997 (diff) | |
| parent | fd048088306656824958e7783ffcee27e241b361 (diff) | |
Merge branch 'linus' into x86/quirks
Conflicts:
arch/x86/kernel/early-quirks.c
Diffstat (limited to 'security/selinux/hooks.c')
| -rw-r--r-- | security/selinux/hooks.c | 62 |
1 files changed, 39 insertions, 23 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 03fc6a81ae32..4a7374c12d9c 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -957,7 +957,8 @@ out_err: | |||
| 957 | return rc; | 957 | return rc; |
| 958 | } | 958 | } |
| 959 | 959 | ||
| 960 | void selinux_write_opts(struct seq_file *m, struct security_mnt_opts *opts) | 960 | static void selinux_write_opts(struct seq_file *m, |
| 961 | struct security_mnt_opts *opts) | ||
| 961 | { | 962 | { |
| 962 | int i; | 963 | int i; |
| 963 | char *prefix; | 964 | char *prefix; |
| @@ -1290,7 +1291,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
| 1290 | /* Default to the fs superblock SID. */ | 1291 | /* Default to the fs superblock SID. */ |
| 1291 | isec->sid = sbsec->sid; | 1292 | isec->sid = sbsec->sid; |
| 1292 | 1293 | ||
| 1293 | if (sbsec->proc) { | 1294 | if (sbsec->proc && !S_ISLNK(inode->i_mode)) { |
| 1294 | struct proc_inode *proci = PROC_I(inode); | 1295 | struct proc_inode *proci = PROC_I(inode); |
| 1295 | if (proci->pde) { | 1296 | if (proci->pde) { |
| 1296 | isec->sclass = inode_mode_to_security_class(inode->i_mode); | 1297 | isec->sclass = inode_mode_to_security_class(inode->i_mode); |
| @@ -3548,38 +3549,44 @@ out: | |||
| 3548 | #endif /* IPV6 */ | 3549 | #endif /* IPV6 */ |
| 3549 | 3550 | ||
| 3550 | static int selinux_parse_skb(struct sk_buff *skb, struct avc_audit_data *ad, | 3551 | static int selinux_parse_skb(struct sk_buff *skb, struct avc_audit_data *ad, |
| 3551 | char **addrp, int src, u8 *proto) | 3552 | char **_addrp, int src, u8 *proto) |
| 3552 | { | 3553 | { |
| 3553 | int ret = 0; | 3554 | char *addrp; |
| 3555 | int ret; | ||
| 3554 | 3556 | ||
| 3555 | switch (ad->u.net.family) { | 3557 | switch (ad->u.net.family) { |
| 3556 | case PF_INET: | 3558 | case PF_INET: |
| 3557 | ret = selinux_parse_skb_ipv4(skb, ad, proto); | 3559 | ret = selinux_parse_skb_ipv4(skb, ad, proto); |
| 3558 | if (ret || !addrp) | 3560 | if (ret) |
| 3559 | break; | 3561 | goto parse_error; |
| 3560 | *addrp = (char *)(src ? &ad->u.net.v4info.saddr : | 3562 | addrp = (char *)(src ? &ad->u.net.v4info.saddr : |
| 3561 | &ad->u.net.v4info.daddr); | 3563 | &ad->u.net.v4info.daddr); |
| 3562 | break; | 3564 | goto okay; |
| 3563 | 3565 | ||
| 3564 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 3566 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
| 3565 | case PF_INET6: | 3567 | case PF_INET6: |
| 3566 | ret = selinux_parse_skb_ipv6(skb, ad, proto); | 3568 | ret = selinux_parse_skb_ipv6(skb, ad, proto); |
| 3567 | if (ret || !addrp) | 3569 | if (ret) |
| 3568 | break; | 3570 | goto parse_error; |
| 3569 | *addrp = (char *)(src ? &ad->u.net.v6info.saddr : | 3571 | addrp = (char *)(src ? &ad->u.net.v6info.saddr : |
| 3570 | &ad->u.net.v6info.daddr); | 3572 | &ad->u.net.v6info.daddr); |
| 3571 | break; | 3573 | goto okay; |
| 3572 | #endif /* IPV6 */ | 3574 | #endif /* IPV6 */ |
| 3573 | default: | 3575 | default: |
| 3574 | break; | 3576 | addrp = NULL; |
| 3577 | goto okay; | ||
| 3575 | } | 3578 | } |
| 3576 | 3579 | ||
| 3577 | if (unlikely(ret)) | 3580 | parse_error: |
| 3578 | printk(KERN_WARNING | 3581 | printk(KERN_WARNING |
| 3579 | "SELinux: failure in selinux_parse_skb()," | 3582 | "SELinux: failure in selinux_parse_skb()," |
| 3580 | " unable to parse packet\n"); | 3583 | " unable to parse packet\n"); |
| 3581 | |||
| 3582 | return ret; | 3584 | return ret; |
| 3585 | |||
| 3586 | okay: | ||
| 3587 | if (_addrp) | ||
| 3588 | *_addrp = addrp; | ||
| 3589 | return 0; | ||
| 3583 | } | 3590 | } |
| 3584 | 3591 | ||
| 3585 | /** | 3592 | /** |
| @@ -5219,8 +5226,12 @@ static int selinux_setprocattr(struct task_struct *p, | |||
| 5219 | 5226 | ||
| 5220 | if (sid == 0) | 5227 | if (sid == 0) |
| 5221 | return -EINVAL; | 5228 | return -EINVAL; |
| 5222 | 5229 | /* | |
| 5223 | /* Only allow single threaded processes to change context */ | 5230 | * SELinux allows to change context in the following case only. |
| 5231 | * - Single threaded processes. | ||
| 5232 | * - Multi threaded processes intend to change its context into | ||
| 5233 | * more restricted domain (defined by TYPEBOUNDS statement). | ||
| 5234 | */ | ||
| 5224 | if (atomic_read(&p->mm->mm_users) != 1) { | 5235 | if (atomic_read(&p->mm->mm_users) != 1) { |
| 5225 | struct task_struct *g, *t; | 5236 | struct task_struct *g, *t; |
| 5226 | struct mm_struct *mm = p->mm; | 5237 | struct mm_struct *mm = p->mm; |
| @@ -5228,11 +5239,16 @@ static int selinux_setprocattr(struct task_struct *p, | |||
| 5228 | do_each_thread(g, t) { | 5239 | do_each_thread(g, t) { |
| 5229 | if (t->mm == mm && t != p) { | 5240 | if (t->mm == mm && t != p) { |
| 5230 | read_unlock(&tasklist_lock); | 5241 | read_unlock(&tasklist_lock); |
| 5231 | return -EPERM; | 5242 | error = security_bounded_transition(tsec->sid, sid); |
| 5243 | if (!error) | ||
| 5244 | goto boundary_ok; | ||
| 5245 | |||
| 5246 | return error; | ||
| 5232 | } | 5247 | } |
| 5233 | } while_each_thread(g, t); | 5248 | } while_each_thread(g, t); |
| 5234 | read_unlock(&tasklist_lock); | 5249 | read_unlock(&tasklist_lock); |
| 5235 | } | 5250 | } |
| 5251 | boundary_ok: | ||
| 5236 | 5252 | ||
| 5237 | /* Check permissions for the transition. */ | 5253 | /* Check permissions for the transition. */ |
| 5238 | error = avc_has_perm(tsec->sid, sid, SECCLASS_PROCESS, | 5254 | error = avc_has_perm(tsec->sid, sid, SECCLASS_PROCESS, |
