[PATCH] Support for stacking capabilities with SELinux (Was: Re: I can ' t use named on LSM-based Prototype. Why?)

From: Stephen Smalley (sdsat_private)
Date: Fri Sep 28 2001 - 06:16:33 PDT

  • Next message: Alan Cox: "Re: Binary only module overview"

    I've attached a patch for selinux (relative to the 9/26 release) that
    provides support for stacking the capabilities security module with the
    SELinux security module.  This allows applications that depend on the
    Linux capabilities (e.g. named with -u option) to continue to function as
    expected.  
    
    If you have already built the new release, then change to the 
    selinux/module directory and do a 'make clean' prior to applying this
    patch to reverse the old patch to the lsm tree.  This patch changes
    that patch in order to ensure that the link order is correct for
    initializing the capabilities module after the SELinux module.
    
    To apply this patch, save it to cap_stack.patch, change to the selinux 
    directory, and run 'patch -p1 < cap_stack.patch'.  Then, follow the 
    updated README instructions for building, being sure to enable the 
    Capabilities option as well as the SELinux and (LSM) IP Networking options
    as built-in.  If you do not enable the Capabilities option, then SELinux
    will instead be stacked with the dummy security module (traditional
    superuser logic).  This is fine if you do not need to support applications
    that depend on capabilities.  
    
    Please note that this patch does not provide general support for stacking
    other security modules with the SELinux module - it is specialized for use
    by the capabilities module (or the dummy module by default).  This is 
    simplified by the fact that the capabilities and dummy modules do not
    need to use the LSM security fields and that these modules only need to
    implement a very small subset of the hooks. 
    
    --
    Stephen D. Smalley, NAI Labs
    ssmalleyat_private
    
    
    
    
    
    Index: selinux/README
    diff -u selinux/README:1.20 selinux/README:1.21
    --- selinux/README:1.20	Tue Sep 25 10:00:45 2001
    +++ selinux/README	Thu Sep 27 11:47:03 2001
    @@ -18,8 +18,8 @@
         cd ../../lsm
         make menuconfig 
     	(Under Networking Options, enable Network Packet Filtering.
    -	 Under Security Options, disable Capabilities and enable 
    -	 both IP Networking and SELinux as built-in options.)
    +	 Under Security Options, enable SELinux, Capabilities, and
    +	 IP Networking as built-in options.)
         make dep; make; make modules
     
     b) Suppose that you want to build the SELinux module as a separately
    @@ -29,9 +29,9 @@
         cd ../lsm
         make menuconfig
     	(Under Networking Options, enable Network Packet Filtering.
    -	 Under Security Options, disable the Capabilities Support
    -	 but enable IP Networking as a built-in option. There is no 
    -	 SELinux option, since we are using the unmodified LSM-patched 
    +	 Under Security Options, enable the Capabilities Support
    +	 as a module and enable IP Networking as a built-in option. There is 
    +	 no SELinux option, since we are using the unmodified LSM-patched 
              kernel sources.)
         make dep; make; make modules
         cd ../selinux
    @@ -163,11 +163,14 @@
     
     12) Boot the LSM-patched kernel.  If you chose option (a), then the
     SELinux module will automatically be initialized during kernel
    -startup.  If you chose option (b), then you need to explicitly load
    -the SELinux module as follows:
    +startup.  
    +
    +If you chose option (b), then you need to explicitly load the SELinux
    +module and the capabilities plug as follows:
     	su (if not already root)
     	cd module/selinux_plug
     	/sbin/insmod selinux_plug.o
    +	/sbin/modprobe capability_plug.o 
     
     13) Login in the sysadm_r role and sysadm_t domain.
     If you are logging into the console, you can interactively
    Index: selinux/module/lsm-patch
    diff -u selinux/module/lsm-patch:1.2 selinux/module/lsm-patch:1.3
    --- selinux/module/lsm-patch:1.2	Wed Aug  8 10:19:21 2001
    +++ selinux/module/lsm-patch	Thu Sep 27 11:47:03 2001
    @@ -1,16 +1,32 @@
     Index: security/Config.in
     ===================================================================
     RCS file: /cvs/lsm/lsm/security/Config.in,v
    -retrieving revision 1.5
    -diff -r1.5 Config.in
    -6a7
    -> tristate '  NSA SELinux Support' CONFIG_SELINUX
    +retrieving revision 1.7
    +diff -u -r1.7 Config.in
    +--- security/Config.in	2001/08/22 19:23:34	1.7
    ++++ security/Config.in	2001/09/27 15:01:09
    +@@ -3,6 +3,7 @@
    + #
    + mainmenu_option next_comment
    + comment 'Security options'
    ++tristate 'NSA SELinux Support' CONFIG_SELINUX
    + tristate 'Capabilities Support' CONFIG_CAPABILITIES
    + dep_tristate 'IP Networking Support' CONFIG_LSM_IP $CONFIG_NETFILTER
    + endmenu
     Index: security/Makefile
     ===================================================================
     RCS file: /cvs/lsm/lsm/security/Makefile,v
    -retrieving revision 1.1
    -diff -r1.1 Makefile
    -16a17,19
    -> obj-$(CONFIG_SELINUX) += selinux_plug/selinux_plug.o
    -> subdir-$(CONFIG_SELINUX) += selinux_plug
    -> 
    +retrieving revision 1.4
    +diff -u -r1.4 Makefile
    +--- security/Makefile	2001/09/05 12:23:19	1.4
    ++++ security/Makefile	2001/09/27 15:01:09
    +@@ -11,6 +11,9 @@
    + # Object file lists
    + obj-y		:= security.o dummy.o
    + 
    ++obj-$(CONFIG_SELINUX) += selinux_plug/selinux_plug.o
    ++subdir-$(CONFIG_SELINUX) += selinux_plug
    ++
    + obj-$(CONFIG_CAPABILITIES)	+= capability_plug.o
    + obj-$(CONFIG_LSM_IP)		+= lsm_ip_glue.o
    + 
    Index: selinux/module/selinux_plug/hooks.c
    diff -u selinux/module/selinux_plug/hooks.c:1.138 selinux/module/selinux_plug/hooks.c:1.139
    --- selinux/module/selinux_plug/hooks.c:1.138	Mon Sep 24 14:00:51 2001
    +++ selinux/module/selinux_plug/hooks.c	Thu Sep 27 11:47:03 2001
    @@ -39,6 +39,13 @@
     #include <linux/netlink.h>
     #include "selinux_plug.h"
     
    +/* 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 capability plug. */
    +static struct security_operations *secondary_ops = NULL;
    +
     /* 
      * Tables to map the CTL table name to a security ID.
      * The members of this struct are used to define a signature for 
    @@ -1487,6 +1494,12 @@
     
     static int selinux_ptrace(struct task_struct *parent, struct task_struct *child)
     {
    +	int rc;
    +
    +	rc = secondary_ops->ptrace(parent,child);
    +	if (rc)
    +		return rc;
    +
     	return task_has_perm(parent, child, PROCESS__PTRACE);
     }
     
    @@ -1498,11 +1511,7 @@
     	if (error)
     		return error;
     
    -	/* Derived from kernel/capability.c:sys_capget. */
    -	*effective = cap_t(target->cap_effective);	
    -	*inheritable = cap_t(target->cap_inheritable); 
    -	*permitted = cap_t(target->cap_permitted);
    -	return 0;
    +	return secondary_ops->capget(target, effective, inheritable, permitted);
     }
     
     static int selinux_capset_check(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted)	
    @@ -1512,28 +1521,8 @@
     	error = task_has_perm(current, target, PROCESS__SETCAP);
     	if (error)
     		return error;
    -
    -	/* Derived from kernel/capability.c:sys_capset. */
    -	/* verify restrictions on target's new Inheritable set */
    -	if (!cap_issubset(*inheritable,
    -			  cap_combine(target->cap_inheritable,
    -				      current->cap_permitted))) {
    -		return -EPERM;
    -	}
     
    -	/* verify restrictions on target's new Permitted set */
    -	if (!cap_issubset(*permitted,
    -			  cap_combine(target->cap_permitted,
    -				      current->cap_permitted))) {
    -		return -EPERM;
    -	}
    -
    -	/* verify the _new_Effective_ is a subset of the _new_Permitted_ */
    -	if (!cap_issubset(*effective, *permitted)) {
    -		return -EPERM;
    -	}
    -	
    -	return 0;
    +	return secondary_ops->capset_check(target, effective, inheritable, permitted);
     }
     
     static void selinux_capset_set(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted) 
    @@ -1544,9 +1533,7 @@
     	if (error)
     		return;
     
    -	target->cap_effective   = *effective;
    -	target->cap_inheritable = *inheritable;
    -	target->cap_permitted   = *permitted;
    +	return secondary_ops->capset_set(target, effective, inheritable, permitted);
     }
     
     static int selinux_acct(struct file *file)
    @@ -1557,10 +1544,13 @@
     
     static int selinux_capable(struct task_struct *tsk, int cap)
     {
    -	if (cap_is_fs_cap(cap) ? tsk->fsuid == 0 : tsk->euid == 0)
    -		return task_has_capability(tsk,cap);
    -	else
    -		return -EPERM;
    +	int rc;
    +
    +	rc = secondary_ops->capable(tsk, cap);
    +	if (rc)
    +		return rc;
    +
    +	return task_has_capability(tsk,cap);
     }
     
     /* Function to search the hierarchy of ctl_sid tables for a match with a
    @@ -1735,6 +1725,10 @@
     	avc_audit_data_t ad;
     	int rc;
     
    +	rc = secondary_ops->bprm_ops->set_security(bprm);
    +	if (rc)
    +		return rc;
    +
     	if (bprm->sh_bang || bprm->security)
     		/* The security field should already be set properly. */
     		return 0;
    @@ -1883,6 +1877,8 @@
     	security_id_t sid;
     	int rc;
     
    +	secondary_ops->bprm_ops->compute_creds(bprm);
    +
     	rc = task_precondition(current);
     	if (rc <= 0)
     		return;
    @@ -2485,7 +2481,7 @@
     
     static int selinux_task_post_setuid(uid_t id0, uid_t id1, uid_t id2, int flags)
     {
    -	return 0;
    +	return secondary_ops->task_ops->post_setuid(id0,id1,id2,flags);
     }
     
     static int selinux_task_setgid(gid_t id0, gid_t id1, gid_t id2, int flags)
    @@ -2615,6 +2611,8 @@
       	struct task_security_struct *tsec;
     	int rc;
     
    +	secondary_ops->task_ops->kmod_set_label();
    +
     	rc = task_precondition(current);
     	if (rc <= 0)
     		return;
    @@ -4134,12 +4132,34 @@
     /* module stacking operations */
     int selinux_register_security (const char *name, struct security_operations *ops)
     {
    -	return -EPERM;
    +	if (secondary_ops != original_ops) {
    +		printk(KERN_INFO __FUNCTION__ ":  There is already a secondary security module registered.\n");
    +		return -EINVAL;
    + 	}
    +	
    +	if (strcmp(name, "capability_plug.o")) {
    +		printk(KERN_INFO __FUNCTION__ ":  Only the capability plug may register as a secondary module.\n");
    +		return -EINVAL;
    +	}
    +
    +	secondary_ops = ops;
    +
    +	printk(KERN_INFO __FUNCTION__ ":  Registering secondary module %s\n",
    +	       name);
    +
    +	return 0;
     }
     
     int selinux_unregister_security (const char *name, struct security_operations *ops)
     {
    -	return -EPERM;
    +	if (ops != secondary_ops) {
    +		printk (KERN_INFO __FUNCTION__ ":  trying to unregister a security module that is not registered.\n");
    +		return -EINVAL;
    +	}
    +
    +	secondary_ops = original_ops;
    +
    +	return 0;
     }
     
     static struct binprm_security_ops selinux_bprm_ops = {
    @@ -4374,6 +4394,12 @@
     	init_MUTEX(&netdev_alloc_semaphore);
     	init_MUTEX(&ipc_alloc_semaphore);
     	init_MUTEX(&msg_alloc_semaphore);
    +
    +	original_ops = secondary_ops = security_ops;
    +	if (!original_ops) {
    +		printk (KERN_INFO __FUNCTION__ ": No dummy security operations\n");
    +		return -EINVAL;
    +	}
     
     	avc_init();
     
    
    _______________________________________________
    linux-security-module mailing list
    linux-security-moduleat_private
    http://mail.wirex.com/mailman/listinfo/linux-security-module
    



    This archive was generated by hypermail 2b30 : Fri Sep 28 2001 - 06:19:42 PDT