aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-09-24 03:56:20 -0400
committerIngo Molnar <mingo@elte.hu>2008-09-24 03:56:20 -0400
commitebdd90a8cb2e3963f55499850f02ce6003558b55 (patch)
treed153f917ed41d257ddafa22f9cc2201bfddf8f9c /security/selinux/hooks.c
parent3c9339049df5cc3a468c11de6c4101a1ea8c3d83 (diff)
parent72d31053f62c4bc464c2783974926969614a8649 (diff)
Merge commit 'v2.6.27-rc7' into x86/pebs
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c85
1 files changed, 36 insertions, 49 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 63f131fc42e4..03fc6a81ae32 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -25,7 +25,7 @@
25 25
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/ptrace.h> 28#include <linux/tracehook.h>
29#include <linux/errno.h> 29#include <linux/errno.h>
30#include <linux/sched.h> 30#include <linux/sched.h>
31#include <linux/security.h> 31#include <linux/security.h>
@@ -998,8 +998,12 @@ static int selinux_sb_show_options(struct seq_file *m, struct super_block *sb)
998 int rc; 998 int rc;
999 999
1000 rc = selinux_get_mnt_opts(sb, &opts); 1000 rc = selinux_get_mnt_opts(sb, &opts);
1001 if (rc) 1001 if (rc) {
1002 /* before policy load we may get EINVAL, don't show anything */
1003 if (rc == -EINVAL)
1004 rc = 0;
1002 return rc; 1005 return rc;
1006 }
1003 1007
1004 selinux_write_opts(m, &opts); 1008 selinux_write_opts(m, &opts);
1005 1009
@@ -1734,24 +1738,34 @@ static inline u32 file_to_av(struct file *file)
1734 1738
1735/* Hook functions begin here. */ 1739/* Hook functions begin here. */
1736 1740
1737static int selinux_ptrace(struct task_struct *parent, 1741static int selinux_ptrace_may_access(struct task_struct *child,
1738 struct task_struct *child, 1742 unsigned int mode)
1739 unsigned int mode)
1740{ 1743{
1741 int rc; 1744 int rc;
1742 1745
1743 rc = secondary_ops->ptrace(parent, child, mode); 1746 rc = secondary_ops->ptrace_may_access(child, mode);
1744 if (rc) 1747 if (rc)
1745 return rc; 1748 return rc;
1746 1749
1747 if (mode == PTRACE_MODE_READ) { 1750 if (mode == PTRACE_MODE_READ) {
1748 struct task_security_struct *tsec = parent->security; 1751 struct task_security_struct *tsec = current->security;
1749 struct task_security_struct *csec = child->security; 1752 struct task_security_struct *csec = child->security;
1750 return avc_has_perm(tsec->sid, csec->sid, 1753 return avc_has_perm(tsec->sid, csec->sid,
1751 SECCLASS_FILE, FILE__READ, NULL); 1754 SECCLASS_FILE, FILE__READ, NULL);
1752 } 1755 }
1753 1756
1754 return task_has_perm(parent, child, PROCESS__PTRACE); 1757 return task_has_perm(current, child, PROCESS__PTRACE);
1758}
1759
1760static int selinux_ptrace_traceme(struct task_struct *parent)
1761{
1762 int rc;
1763
1764 rc = secondary_ops->ptrace_traceme(parent);
1765 if (rc)
1766 return rc;
1767
1768 return task_has_perm(parent, current, PROCESS__PTRACE);
1755} 1769}
1756 1770
1757static int selinux_capget(struct task_struct *target, kernel_cap_t *effective, 1771static int selinux_capget(struct task_struct *target, kernel_cap_t *effective,
@@ -1971,22 +1985,6 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages)
1971 return __vm_enough_memory(mm, pages, cap_sys_admin); 1985 return __vm_enough_memory(mm, pages, cap_sys_admin);
1972} 1986}
1973 1987
1974/**
1975 * task_tracer_task - return the task that is tracing the given task
1976 * @task: task to consider
1977 *
1978 * Returns NULL if noone is tracing @task, or the &struct task_struct
1979 * pointer to its tracer.
1980 *
1981 * Must be called under rcu_read_lock().
1982 */
1983static struct task_struct *task_tracer_task(struct task_struct *task)
1984{
1985 if (task->ptrace & PT_PTRACED)
1986 return rcu_dereference(task->parent);
1987 return NULL;
1988}
1989
1990/* binprm security operations */ 1988/* binprm security operations */
1991 1989
1992static int selinux_bprm_alloc_security(struct linux_binprm *bprm) 1990static int selinux_bprm_alloc_security(struct linux_binprm *bprm)
@@ -2238,7 +2236,7 @@ static void selinux_bprm_apply_creds(struct linux_binprm *bprm, int unsafe)
2238 u32 ptsid = 0; 2236 u32 ptsid = 0;
2239 2237
2240 rcu_read_lock(); 2238 rcu_read_lock();
2241 tracer = task_tracer_task(current); 2239 tracer = tracehook_tracer_task(current);
2242 if (likely(tracer != NULL)) { 2240 if (likely(tracer != NULL)) {
2243 sec = tracer->security; 2241 sec = tracer->security;
2244 ptsid = sec->sid; 2242 ptsid = sec->sid;
@@ -2640,12 +2638,11 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *na
2640 return dentry_has_perm(current, NULL, dentry, FILE__READ); 2638 return dentry_has_perm(current, NULL, dentry, FILE__READ);
2641} 2639}
2642 2640
2643static int selinux_inode_permission(struct inode *inode, int mask, 2641static int selinux_inode_permission(struct inode *inode, int mask)
2644 struct nameidata *nd)
2645{ 2642{
2646 int rc; 2643 int rc;
2647 2644
2648 rc = secondary_ops->inode_permission(inode, mask, nd); 2645 rc = secondary_ops->inode_permission(inode, mask);
2649 if (rc) 2646 if (rc)
2650 return rc; 2647 return rc;
2651 2648
@@ -5247,7 +5244,7 @@ static int selinux_setprocattr(struct task_struct *p,
5247 Otherwise, leave SID unchanged and fail. */ 5244 Otherwise, leave SID unchanged and fail. */
5248 task_lock(p); 5245 task_lock(p);
5249 rcu_read_lock(); 5246 rcu_read_lock();
5250 tracer = task_tracer_task(p); 5247 tracer = tracehook_tracer_task(p);
5251 if (tracer != NULL) { 5248 if (tracer != NULL) {
5252 struct task_security_struct *ptsec = tracer->security; 5249 struct task_security_struct *ptsec = tracer->security;
5253 u32 ptsid = ptsec->sid; 5250 u32 ptsid = ptsec->sid;
@@ -5359,7 +5356,8 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer)
5359static struct security_operations selinux_ops = { 5356static struct security_operations selinux_ops = {
5360 .name = "selinux", 5357 .name = "selinux",
5361 5358
5362 .ptrace = selinux_ptrace, 5359 .ptrace_may_access = selinux_ptrace_may_access,
5360 .ptrace_traceme = selinux_ptrace_traceme,
5363 .capget = selinux_capget, 5361 .capget = selinux_capget,
5364 .capset_check = selinux_capset_check, 5362 .capset_check = selinux_capset_check,
5365 .capset_set = selinux_capset_set, 5363 .capset_set = selinux_capset_set,
@@ -5670,27 +5668,20 @@ static struct nf_hook_ops selinux_ipv6_ops[] = {
5670static int __init selinux_nf_ip_init(void) 5668static int __init selinux_nf_ip_init(void)
5671{ 5669{
5672 int err = 0; 5670 int err = 0;
5673 u32 iter;
5674 5671
5675 if (!selinux_enabled) 5672 if (!selinux_enabled)
5676 goto out; 5673 goto out;
5677 5674
5678 printk(KERN_DEBUG "SELinux: Registering netfilter hooks\n"); 5675 printk(KERN_DEBUG "SELinux: Registering netfilter hooks\n");
5679 5676
5680 for (iter = 0; iter < ARRAY_SIZE(selinux_ipv4_ops); iter++) { 5677 err = nf_register_hooks(selinux_ipv4_ops, ARRAY_SIZE(selinux_ipv4_ops));
5681 err = nf_register_hook(&selinux_ipv4_ops[iter]); 5678 if (err)
5682 if (err) 5679 panic("SELinux: nf_register_hooks for IPv4: error %d\n", err);
5683 panic("SELinux: nf_register_hook for IPv4: error %d\n",
5684 err);
5685 }
5686 5680
5687#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 5681#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
5688 for (iter = 0; iter < ARRAY_SIZE(selinux_ipv6_ops); iter++) { 5682 err = nf_register_hooks(selinux_ipv6_ops, ARRAY_SIZE(selinux_ipv6_ops));
5689 err = nf_register_hook(&selinux_ipv6_ops[iter]); 5683 if (err)
5690 if (err) 5684 panic("SELinux: nf_register_hooks for IPv6: error %d\n", err);
5691 panic("SELinux: nf_register_hook for IPv6: error %d\n",
5692 err);
5693 }
5694#endif /* IPV6 */ 5685#endif /* IPV6 */
5695 5686
5696out: 5687out:
@@ -5702,15 +5693,11 @@ __initcall(selinux_nf_ip_init);
5702#ifdef CONFIG_SECURITY_SELINUX_DISABLE 5693#ifdef CONFIG_SECURITY_SELINUX_DISABLE
5703static void selinux_nf_ip_exit(void) 5694static void selinux_nf_ip_exit(void)
5704{ 5695{
5705 u32 iter;
5706
5707 printk(KERN_DEBUG "SELinux: Unregistering netfilter hooks\n"); 5696 printk(KERN_DEBUG "SELinux: Unregistering netfilter hooks\n");
5708 5697
5709 for (iter = 0; iter < ARRAY_SIZE(selinux_ipv4_ops); iter++) 5698 nf_unregister_hooks(selinux_ipv4_ops, ARRAY_SIZE(selinux_ipv4_ops));
5710 nf_unregister_hook(&selinux_ipv4_ops[iter]);
5711#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 5699#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
5712 for (iter = 0; iter < ARRAY_SIZE(selinux_ipv6_ops); iter++) 5700 nf_unregister_hooks(selinux_ipv6_ops, ARRAY_SIZE(selinux_ipv6_ops));
5713 nf_unregister_hook(&selinux_ipv6_ops[iter]);
5714#endif /* IPV6 */ 5701#endif /* IPV6 */
5715} 5702}
5716#endif 5703#endif