[patch 9/12] lsm stacking v0.2: selinux: remove secondary support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Remove the SELinux support for secondary modules.  This is no longer necessary
as SELinux can now be simply stacked with the cap-stack module.

Signed-off-by: Serge Hallyn <[email protected]>
---
 hooks.c |  266 ++++++++--------------------------------------------------------
 1 files changed, 35 insertions(+), 231 deletions(-)

Index: linux-2.6.13-rc1/security/selinux/hooks.c
===================================================================
--- linux-2.6.13-rc1.orig/security/selinux/hooks.c	2005-06-30 16:02:02.000000000 -0500
+++ linux-2.6.13-rc1/security/selinux/hooks.c	2005-06-30 16:05:34.000000000 -0500
@@ -80,6 +80,8 @@
 extern unsigned int policydb_loaded_version;
 extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);
 
+static int secondary;  /* how were we registered? */
+
 #ifdef CONFIG_SECURITY_SELINUX_DEVELOP
 int selinux_enforcing = 0;
 
@@ -102,15 +104,6 @@ static int __init selinux_enabled_setup(
 __setup("selinux=", selinux_enabled_setup);
 #endif
 
-/* Original (dummy) security module. */
-static struct security_operations *original_ops = NULL;
-
-/* Minimal support for a secondary security module,
-   just to allow the use of the dummy or capability modules.
-   The owlsm module can alternatively be used as a secondary
-   module as long as CONFIG_OWLSM_FD is not enabled. */
-static struct security_operations *secondary_ops = NULL;
-
 /* Lists of inode and superblock security structures initialized
    before the policy was loaded. */
 static LIST_HEAD(superblock_security_head);
@@ -1399,9 +1392,6 @@ static int selinux_ptrace(struct task_st
 	struct task_security_struct *csec;
 	int rc;
 
-	rc = secondary_ops->ptrace(parent,child);
-	if (rc)
-		return rc;
 	psec = security_get_value_type(&parent->security, SELINUX_LSM_ID,
 		struct task_security_struct);
 	csec = security_get_value_type(&child->security, SELINUX_LSM_ID,
@@ -1417,41 +1407,17 @@ static int selinux_ptrace(struct task_st
 static int selinux_capget(struct task_struct *target, kernel_cap_t *effective,
                           kernel_cap_t *inheritable, kernel_cap_t *permitted)
 {
-	int error;
-
-	error = task_has_perm(current, target, PROCESS__GETCAP);
-	if (error)
-		return error;
-
-	return secondary_ops->capget(target, effective, inheritable, permitted);
+	return task_has_perm(current, target, PROCESS__GETCAP);
 }
 
 static int selinux_capset_check(struct task_struct *target, kernel_cap_t *effective,
                                 kernel_cap_t *inheritable, kernel_cap_t *permitted)
 {
-	int error;
-
-	error = secondary_ops->capset_check(target, effective, inheritable, permitted);
-	if (error)
-		return error;
-
 	return task_has_perm(current, target, PROCESS__SETCAP);
 }
 
-static void selinux_capset_set(struct task_struct *target, kernel_cap_t *effective,
-                               kernel_cap_t *inheritable, kernel_cap_t *permitted)
-{
-	secondary_ops->capset_set(target, effective, inheritable, permitted);
-}
-
 static int selinux_capable(struct task_struct *tsk, int cap)
 {
-	int rc;
-
-	rc = secondary_ops->capable(tsk, cap);
-	if (rc)
-		return rc;
-
 	return task_has_capability(tsk,cap);
 }
 
@@ -1463,10 +1429,6 @@ static int selinux_sysctl(ctl_table *tab
 	u32 tsid;
 	int rc;
 
-	rc = secondary_ops->sysctl(table, op);
-	if (rc)
-		return rc;
-
 	tsec = security_get_value_type(&current->security, SELINUX_LSM_ID,
 		struct task_security_struct);
 
@@ -1534,11 +1496,7 @@ static int selinux_quota_on(struct dentr
 
 static int selinux_syslog(int type)
 {
-	int rc;
-
-	rc = secondary_ops->syslog(type);
-	if (rc)
-		return rc;
+	int rc = 0;
 
 	switch (type) {
 		case 3:         /* Read last kernel messages */
@@ -1562,36 +1520,6 @@ static int selinux_syslog(int type)
 	return rc;
 }
 
-/*
- * Check that a process has enough memory to allocate a new virtual
- * mapping. 0 means there is enough memory for the allocation to
- * succeed and -ENOMEM implies there is not.
- *
- * Note that secondary_ops->capable and task_has_perm_noaudit return 0
- * if the capability is granted, but __vm_enough_memory requires 1 if
- * the capability is granted.
- *
- * Do not audit the selinux permission check, as this is applied to all
- * processes that allocate mappings.
- */
-static int selinux_vm_enough_memory(long pages)
-{
-	int rc, cap_sys_admin = 0;
-	struct task_security_struct *tsec = current->security;
-
-	rc = secondary_ops->capable(current, CAP_SYS_ADMIN);
-	if (rc == 0)
-		rc = avc_has_perm_noaudit(tsec->sid, tsec->sid,
-					SECCLASS_CAPABILITY,
-					CAP_TO_MASK(CAP_SYS_ADMIN),
-					NULL);
-
-	if (rc == 0)
-		cap_sys_admin = 1;
-
-	return __vm_enough_memory(pages, cap_sys_admin);
-}
-
 /* binprm security operations */
 
 static int selinux_bprm_alloc_security(struct linux_binprm *bprm)
@@ -1621,10 +1549,6 @@ static int selinux_bprm_set_security(str
 	struct avc_audit_data ad;
 	int rc;
 
-	rc = secondary_ops->bprm_set_security(bprm);
-	if (rc)
-		return rc;
-
 	bsec = security_get_value_type(&bprm->security, SELINUX_LSM_ID,
 		struct bprm_security_struct);
 
@@ -1689,12 +1613,6 @@ static int selinux_bprm_set_security(str
 	return 0;
 }
 
-static int selinux_bprm_check_security (struct linux_binprm *bprm)
-{
-	return secondary_ops->bprm_check_security(bprm);
-}
-
-
 static int selinux_bprm_secureexec (struct linux_binprm *bprm)
 {
 	struct task_security_struct *tsec;
@@ -1711,7 +1629,7 @@ static int selinux_bprm_secureexec (stru
 					 PROCESS__NOATSECURE, NULL);
 	}
 
-	return (atsecure || secondary_ops->bprm_secureexec(bprm));
+	return atsecure;
 }
 
 static void selinux_bprm_free_security(struct linux_binprm *bprm)
@@ -1815,8 +1733,6 @@ static void selinux_bprm_apply_creds(str
 	u32 sid;
 	int rc;
 
-	secondary_ops->bprm_apply_creds(bprm, unsafe);
-
 	tsec = security_get_value_type(&current->security, SELINUX_LSM_ID,
 		struct task_security_struct);
 	bsec = security_get_value_type(&bprm->security, SELINUX_LSM_ID,
@@ -2042,12 +1958,6 @@ static int selinux_mount(char * dev_name
                          unsigned long flags,
                          void * data)
 {
-	int rc;
-
-	rc = secondary_ops->sb_mount(dev_name, nd, type, flags, data);
-	if (rc)
-		return rc;
-
 	if (flags & MS_REMOUNT)
 		return superblock_has_perm(current, nd->mnt->mnt_sb,
 		                           FILESYSTEM__REMOUNT, NULL);
@@ -2058,12 +1968,6 @@ static int selinux_mount(char * dev_name
 
 static int selinux_umount(struct vfsmount *mnt, int flags)
 {
-	int rc;
-
-	rc = secondary_ops->sb_umount(mnt, flags);
-	if (rc)
-		return rc;
-
 	return superblock_has_perm(current,mnt->mnt_sb,
 	                           FILESYSTEM__UNMOUNT,NULL);
 }
@@ -2092,11 +1996,6 @@ static void selinux_inode_post_create(st
 
 static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
 {
-	int rc;
-
-	rc = secondary_ops->inode_link(old_dentry,dir,new_dentry);
-	if (rc)
-		return rc;
 	return may_link(dir, old_dentry, MAY_LINK);
 }
 
@@ -2107,11 +2006,6 @@ static void selinux_inode_post_link(stru
 
 static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry)
 {
-	int rc;
-
-	rc = secondary_ops->inode_unlink(dir, dentry);
-	if (rc)
-		return rc;
 	return may_link(dir, dentry, MAY_UNLINK);
 }
 
@@ -2142,12 +2036,6 @@ static int selinux_inode_rmdir(struct in
 
 static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
 {
-	int rc;
-
-	rc = secondary_ops->inode_mknod(dir, dentry, mode, dev);
-	if (rc)
-		return rc;
-
 	return may_create(dir, dentry, inode_mode_to_security_class(mode));
 }
 
@@ -2175,23 +2063,12 @@ static int selinux_inode_readlink(struct
 
 static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata)
 {
-	int rc;
-
-	rc = secondary_ops->inode_follow_link(dentry,nameidata);
-	if (rc)
-		return rc;
 	return dentry_has_perm(current, NULL, dentry, FILE__READ);
 }
 
 static int selinux_inode_permission(struct inode *inode, int mask,
 				    struct nameidata *nd)
 {
-	int rc;
-
-	rc = secondary_ops->inode_permission(inode, mask, nd);
-	if (rc)
-		return rc;
-
 	if (!mask) {
 		/* No permission to check.  Existence test. */
 		return 0;
@@ -2203,12 +2080,6 @@ static int selinux_inode_permission(stru
 
 static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
 {
-	int rc;
-
-	rc = secondary_ops->inode_setattr(dentry, iattr);
-	if (rc)
-		return rc;
-
 	if (iattr->ia_valid & ATTR_FORCE)
 		return 0;
 
@@ -2530,12 +2401,6 @@ static int file_map_prot_check(struct fi
 static int selinux_file_mmap(struct file *file, unsigned long reqprot,
 			     unsigned long prot, unsigned long flags)
 {
-	int rc;
-
-	rc = secondary_ops->file_mmap(file, reqprot, prot, flags);
-	if (rc)
-		return rc;
-
 	if (selinux_checkreqprot)
 		prot = reqprot;
 
@@ -2549,10 +2414,6 @@ static int selinux_file_mprotect(struct 
 {
 	int rc;
 
-	rc = secondary_ops->file_mprotect(vma, reqprot, prot);
-	if (rc)
-		return rc;
-
 	if (selinux_checkreqprot)
 		prot = reqprot;
 
@@ -2575,7 +2436,7 @@ static int selinux_file_mprotect(struct 
 		 * check ability to execute the possibly modified content.
 		 * This typically should only occur for text relocations.
 		 */
-		int rc = file_has_perm(current, vma->vm_file, FILE__EXECMOD);
+		rc = file_has_perm(current, vma->vm_file, FILE__EXECMOD);
 		if (rc)
 			return rc;
 	}
@@ -2691,12 +2552,6 @@ static int selinux_file_receive(struct f
 
 static int selinux_task_create(unsigned long clone_flags)
 {
-	int rc;
-
-	rc = secondary_ops->task_create(clone_flags);
-	if (rc)
-		return rc;
-
 	return task_has_perm(current, current, PROCESS__FORK);
 }
 
@@ -2745,11 +2600,6 @@ static int selinux_task_setuid(uid_t id0
 	return 0;
 }
 
-static int selinux_task_post_setuid(uid_t id0, uid_t id1, uid_t id2, int flags)
-{
-	return secondary_ops->task_post_setuid(id0,id1,id2,flags);
-}
-
 static int selinux_task_setgid(gid_t id0, gid_t id1, gid_t id2, int flags)
 {
 	/* See the comment for setuid above. */
@@ -2779,24 +2629,12 @@ static int selinux_task_setgroups(struct
 
 static int selinux_task_setnice(struct task_struct *p, int nice)
 {
-	int rc;
-
-	rc = secondary_ops->task_setnice(p, nice);
-	if (rc)
-		return rc;
-
 	return task_has_perm(current,p, PROCESS__SETSCHED);
 }
 
 static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim)
 {
 	struct rlimit *old_rlim = current->signal->rlim + resource;
-	int rc;
-
-	rc = secondary_ops->task_setrlimit(resource, new_rlim);
-	if (rc)
-		return rc;
-
 	/* Control the ability to change the hard limit (whether
 	   lowering or raising it), so that the hard limit can
 	   later be used as a safe reset point for the soft limit
@@ -2820,11 +2658,6 @@ static int selinux_task_getscheduler(str
 static int selinux_task_kill(struct task_struct *p, struct siginfo *info, int sig)
 {
 	u32 perm;
-	int rc;
-
-	rc = secondary_ops->task_kill(p, info, sig);
-	if (rc)
-		return rc;
 
 	if (info && ((unsigned long)info == 1 ||
 	             (unsigned long)info == 2 || SI_FROMKERNEL(info)))
@@ -2863,8 +2696,6 @@ static void selinux_task_reparent_to_ini
 {
   	struct task_security_struct *tsec;
 
-	secondary_ops->task_reparent_to_init(p);
-
 	tsec = security_get_value_type(&p->security, SELINUX_LSM_ID,
 		struct task_security_struct);
 	tsec->osid = tsec->sid;
@@ -3328,10 +3159,6 @@ static int selinux_socket_unix_stream_co
 	struct avc_audit_data ad;
 	int err;
 
-	err = secondary_ops->unix_stream_connect(sock, other, newsk);
-	if (err)
-		return err;
-
 	isec = security_get_value_type(&SOCK_INODE(sock)->i_security,
 		SELINUX_LSM_ID, struct inode_security_struct);
 	other_isec = security_get_value_type(&SOCK_INODE(other)->i_security,
@@ -3715,11 +3542,7 @@ static int selinux_netlink_send(struct s
 {
 	struct task_security_struct *tsec;
 	struct av_decision avd;
-	int err;
-
-	err = secondary_ops->netlink_send(sk, skb);
-	if (err)
-		return err;
+	int err = 0;
 
 	tsec = security_get_value_type(&current->security,
 		SELINUX_LSM_ID, struct task_security_struct);
@@ -3735,13 +3558,6 @@ static int selinux_netlink_send(struct s
 	return err;
 }
 
-static int selinux_netlink_recv(struct sk_buff *skb)
-{
-	if (!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN))
-		return -EPERM;
-	return 0;
-}
-
 static int ipc_alloc_security(struct task_struct *task,
 			      struct kern_ipc_perm *perm,
 			      u16 sclass)
@@ -4079,11 +3895,6 @@ static int selinux_shm_shmat(struct shmi
 			     char __user *shmaddr, int shmflg)
 {
 	u32 perms;
-	int rc;
-
-	rc = secondary_ops->shm_shmat(shp, shmaddr, shmflg);
-	if (rc)
-		return rc;
 
 	if (shmflg & SHM_RDONLY)
 		perms = SHM__READ;
@@ -4219,32 +4030,12 @@ static int selinux_ipc_permission(struct
 /* module stacking operations */
 static int selinux_register_security (const char *name, struct security_operations *ops)
 {
-	if (secondary_ops != original_ops) {
-		printk(KERN_INFO "%s:  There is already a secondary security "
-		       "module registered.\n", __FUNCTION__);
-		return -EINVAL;
- 	}
-
-	secondary_ops = ops;
-
-	printk(KERN_INFO "%s:  Registering secondary module %s\n",
-	       __FUNCTION__,
-	       name);
-
-	return 0;
+	return -EINVAL;
 }
 
 static int selinux_unregister_security (const char *name, struct security_operations *ops)
 {
-	if (ops != secondary_ops) {
-		printk (KERN_INFO "%s:  trying to unregister a security module "
-		        "that is not registered.\n", __FUNCTION__);
-		return -EINVAL;
-	}
-
-	secondary_ops = original_ops;
-
-	return 0;
+	return -EINVAL;
 }
 
 static void selinux_d_instantiate (struct dentry *dentry, struct inode *inode)
@@ -4407,23 +4198,19 @@ static struct security_operations selinu
 	.ptrace =			selinux_ptrace,
 	.capget =			selinux_capget,
 	.capset_check =			selinux_capset_check,
-	.capset_set =			selinux_capset_set,
 	.sysctl =			selinux_sysctl,
 	.capable =			selinux_capable,
 	.quotactl =			selinux_quotactl,
 	.quota_on =			selinux_quota_on,
 	.syslog =			selinux_syslog,
-	.vm_enough_memory =		selinux_vm_enough_memory,
 
 	.netlink_send =			selinux_netlink_send,
-        .netlink_recv =			selinux_netlink_recv,
 
 	.bprm_alloc_security =		selinux_bprm_alloc_security,
 	.bprm_free_security =		selinux_bprm_free_security,
 	.bprm_apply_creds =		selinux_bprm_apply_creds,
 	.bprm_post_apply_creds =	selinux_bprm_post_apply_creds,
 	.bprm_set_security =		selinux_bprm_set_security,
-	.bprm_check_security =		selinux_bprm_check_security,
 	.bprm_secureexec =		selinux_bprm_secureexec,
 
 	.sb_alloc_security =		selinux_sb_alloc_security,
@@ -4480,7 +4267,6 @@ static struct security_operations selinu
 	.task_alloc_security =		selinux_task_alloc_security,
 	.task_free_security =		selinux_task_free_security,
 	.task_setuid =			selinux_task_setuid,
-	.task_post_setuid =		selinux_task_post_setuid,
 	.task_setgid =			selinux_task_setgid,
 	.task_setpgid =			selinux_task_setpgid,
 	.task_getpgid =			selinux_task_getpgid,
@@ -4552,10 +4338,12 @@ static struct security_operations selinu
 #endif
 };
 
+#define MY_NAME "selinux"
 static __init int selinux_init(void)
 {
 	struct task_security_struct *tsec;
 
+	secondary = 0;
 	if (!selinux_enabled) {
 		printk(KERN_INFO "SELinux:  Disabled at boot.\n");
 		return 0;
@@ -4566,22 +4354,30 @@ static __init int selinux_init(void)
 	/* Set the security state for the initial task. */
 	if (task_alloc_security(current))
 		panic("SELinux:  Failed to initialize initial task.\n");
-	tsec = current->security;
+	tsec = security_get_value_type(&current->security, SELINUX_LSM_ID,
+		struct task_security_struct);
 	tsec->osid = tsec->sid = SECINITSID_KERNEL;
 
 	avc_init();
 
-	original_ops = secondary_ops = security_ops;
-	if (!secondary_ops)
-		panic ("SELinux: No initial security operations\n");
-	if (register_security (&selinux_ops))
-		panic("SELinux: Unable to register with kernel.\n");
+	if (register_security (&selinux_ops)) {
+		if (mod_reg_security( MY_NAME, &selinux_ops)) {
+			printk(KERN_ERR "%s: Failed to register with primary LSM.\n",
+				__FUNCTION__);
+			panic("SELinux: Unable to register with kernel.\n");
+		} else {
+			printk(KERN_ERR "%s: registered with primary LSM.\n",
+				__FUNCTION__);
+		}
+		secondary = 1;
+	}
 
 	if (selinux_enforcing) {
 		printk(KERN_INFO "SELinux:  Starting in enforcing mode\n");
 	} else {
 		printk(KERN_INFO "SELinux:  Starting in permissive mode\n");
 	}
+
 	return 0;
 }
 
@@ -4691,6 +4487,7 @@ int selinux_disable(void)
 {
 	extern void exit_sel_fs(void);
 	static int selinux_disabled = 0;
+	int ret;
 
 	if (ss_initialized) {
 		/* Not permitted after initial policy load. */
@@ -4706,8 +4503,15 @@ int selinux_disable(void)
 
 	selinux_disabled = 1;
 
-	/* Reset security_ops to the secondary module, dummy or capability. */
-	security_ops = secondary_ops;
+	if (secondary)
+		ret = mod_unreg_security(MY_NAME, &selinux_ops);
+	else
+		ret = unregister_security(&selinux_ops);
+
+	if (ret)
+		printk(KERN_INFO "Failure unregistering selinux.\n");
+	else
+		printk(KERN_INFO "Unregistered selinux.\n");
 
 	/* Unregister netfilter hooks. */
 	selinux_nf_ip_exit();
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux