Diffs to owlsm for stacking - first cut

From: dwheelerat_private
Date: Fri Dec 20 2002 - 13:35:55 PST

  • Next message: wwat_private: "新年快乐!Happy New Year!"

    Here's my first cut at diffs to owlsm to better support stacking.
    The main change here is that, when stacked, owlsm doesn't try
    to invoke capability or dummy with any action; instead, it lets the
    primary module determine when or if to do that.
    
    Obviously, any primary module that presumes that owlsm _does_
    invoke capability or dummy will need to be modified to eliminate
    that assumption.
    
    Most of this code is to work around something I hadn't realized:
    the "fill in unstated functions" code presumes that the module is
    a primary module - for stacked modules, the defaults need to be
    slightly different.  I'll explain that in more detail in a separate email.
    It can be worked around, but I think it'd be better if the
    defaults for stacking allowed arbitrary stacking as well, and it
    won't be hard to do.  I would claim that it's a bugfix, so it should
    still be acceptable as a patch for the mainline.
    
    
    diff -u security.orig/owlsm.c security/owlsm.c
    --- security.orig/owlsm.c	Thu Dec 19 23:27:22 2002
    +++ security/owlsm.c	Fri Dec 20 14:52:22 2002
    @@ -13,6 +13,7 @@
      * Copyright (C) 2001 Emily Ratliff <ratliffat_private>
      * Copyright (C) 2001 Nick Bellinger, Esquire <nickbat_private>
      * Copyright (C) 2001 Chris Wright <chrisat_private>
    + * Copyright (C) 2002 David A. Wheeler <dwheelerat_private>
      *
      * The fd 0-2 code is based off of code Copyright (C) Pavel Kankovsky
      *
    @@ -79,17 +80,60 @@
     static int owlsm_decode_options (struct sk_buff *skb, const char *optptr,
     				unsigned char **pp_ptr)
     {
    -	/* from dummy.c */
    -	if (!skb && !capable (CAP_NET_RAW)) {
    -		(const unsigned char *) *pp_ptr = optptr;
    -		return -EPERM;
    +	if (!secondary) {
    +		/* from dummy.c */
    +		if (!skb && !capable (CAP_NET_RAW)) {
    +			(const unsigned char *) *pp_ptr = optptr;
    +			return -EPERM;
    +		}
     	}
     	return 0;
     }
     
     
    +
    +/* No-ops, used when owlsm is loaded as a secondary module */
    +
    +static int noop_capget (struct task_struct *target, kernel_cap_t * effective,
    +			 kernel_cap_t * inheritable, kernel_cap_t * permitted)
    +{
    +	return 0;
    +}
    +
    +static int noop_capset_check (struct task_struct *target,
    +			       kernel_cap_t * effective,
    +			       kernel_cap_t * inheritable,
    +			       kernel_cap_t * permitted)
    +{
    +	return 0;
    +}
    +
    +static int noop_capable (struct task_struct *tsk, int cap)
    +{
    +	/* capability denied; this is different than the other noop hooks
    +	 * because capable() is authoritative. */
    +	return -EPERM;
    +}
    +
    +static int noop_netlink_send (struct sk_buff *skb)
    +{
    +	return 0;
    +}
    +
    +static int noop_netlink_recv (struct sk_buff *skb)
    +{
    +	return 0;
    +}
    +
    +static void noop_task_reparent_to_init (struct task_struct *p)
    +{
    +	return;
    +}
    +
    +
     static struct security_operations owlsm_ops = {
    -	/* Use the capability functions for some of the hooks */
    +	/* When used as a primary, use the capability functions for some
    +	 * of the hooks */
     	.ptrace =			cap_ptrace,
     	.capget =			cap_capget,
     	.capset_check =			cap_capset_check,
    @@ -111,6 +155,33 @@
     	.ip_decode_options =		owlsm_decode_options,
     };
     
    +static struct security_operations owlsm_ops_secondary = {
    +	/* When used as a secondary module, don't call either the capability
    +	 * functions or the dummy functions that do anything. That way,
    +	 * the primary module has complete freedom over how to combine the
    +	 * secondary's security policies.
    +	 * A secondary must always override the dummy functions that do
    +	 * anything: capget, capset_check, capable, netlink_send,
    +	 * netlink_recv, task_reparent_to_init, and ip_decode_options: */
    +	.capget =			noop_capget,
    +	.capset_check =			noop_capset_check,
    +	.capable =			noop_capable,
    +	.netlink_send =			noop_netlink_send,
    +	.netlink_recv =			noop_netlink_recv,
    +	.task_reparent_to_init =	noop_task_reparent_to_init,
    +
    +	.bprm_alloc_security =		owlsm_binprm_alloc_security,
    +	.bprm_free_security =		owlsm_binprm_free_security,
    +	.bprm_compute_creds =		owlsm_binprm_compute_creds,
    +	.bprm_set_security =		owlsm_binprm_set_security,
    +	
    +	.inode_link =			owlsm_inode_link,
    +	.inode_follow_link =		owlsm_inode_follow_link,
    +
    +	.ip_decode_options =		owlsm_decode_options,
    +
    +};
    +
     #if defined(CONFIG_SECURITY_owlsm_MODULE)
     #define MY_NAME THIS_MODULE->name
     #else
    @@ -123,13 +194,15 @@
     	if (register_security (&owlsm_ops)) {
     		printk (KERN_INFO 
     			"Failure registering owlsm module with the kernel\n");
    -		/* try registering with primary module */
    -		if (mod_reg_security (MY_NAME, &owlsm_ops)) {
    +		/* Try registering with primary module.
    +		 * Set secondary before calling mod_reg_security;
    +		   doing it afterwards would cause a race. */
    +		secondary = 1;
    +		if (mod_reg_security (MY_NAME, &owlsm_ops_secondary)) {
     			printk (KERN_INFO "Failure registering owlsm module "
     				"with primary security module.\n");
     			return -EINVAL;
     		}
    -		secondary = 1;
     	}
     	printk(KERN_INFO "owlsm LSM initialized\n");
     	return 0;
    @@ -139,7 +212,7 @@
     {
     	/* remove ourselves from the security framework */
     	if (secondary) {
    -		if (mod_unreg_security (MY_NAME, &owlsm_ops))
    +		if (mod_unreg_security (MY_NAME, &owlsm_ops_secondary))
     			printk (KERN_INFO "Failure unregistering owlsm module "
     				"with primary module.\n");
     		return;
    diff -u security.orig/owlsm.h security/owlsm.h
    --- security.orig/owlsm.h	Thu Dec 19 23:27:22 2002
    +++ security/owlsm.h	Fri Dec 20 14:17:31 2002
    @@ -277,12 +277,20 @@
     
     static inline int do_owlsm_sfd_set (struct linux_binprm *bprm)
     {
    -	return cap_bprm_set_security(bprm);
    +	if (secondary) {
    +		return 0;
    +	} else {
    +		return cap_bprm_set_security(bprm);
    +	}
     }
     
     static inline void do_owlsm_sfd_compute (struct linux_binprm *bprm)
     {
    -	return cap_bprm_compute_creds(bprm);
    +	if (secondary) {
    +		return;
    +	} else {
    +		return cap_bprm_compute_creds(bprm);
    +	}
     }
     #endif /* CONFIG_OWLSM_FD */
     
    
    _______________________________________________
    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 Dec 20 2002 - 19:58:53 PST