Re: Another version of stacker.c (URL attached)

From: Lachlan McIlroy (lachlanat_private)
Date: Sun Jul 21 2002 - 21:03:43 PDT

  • Next message: Stephen Smalley: "Re: new hook for do_sys_settimeofday"

    dwheelerat_private wrote:
    > Here's yet another version of stacker.c.  Thanks for the feedback, folks!
    > Rather than post a mailbomb, I've placed the current version at:
    >  http://www.dwheeler.com/misc/stacker.c
    > 
    > I've added a date - the current version is dated 2002-07-20, which
    > is (proudly?) displayed near the beginning of the file.
    > I'll just update this URL with newer versions, since I don't expect
    > anyone to be interested in old drafts of this thing yet.
    > 
    > Changes:
    > * More documentation, especially noting that modules that want to be
    >   stackable must NOT, when stacked, try to do another's job.
    >   E.G., in capable(), your code should look like this:
    >         if (!secondary)
    >                 if (cap_is_fs_cap (cap) ? tsk->fsuid == 0 : tsk->euid == 0)
    >                          return 0;
    >         return -EPERM;
    > * Also noted that modules that want to be stackable need to set
    >   "secondary" to 1 _before_ they register as a child module, to avoid
    >   a subtle race condition that only shows up when you try to write
    >   a stacking module.  This is an interesting race condition that is
    >   universal among stacking modules.  It means, BTW, that stackable
    >   modules (like owlsm) will need to have their secondary = 1
    >   statement moved.  Details in the comments.
    > * Implemented a number of sys_security calls that apply to the
    >   stacker itself.  This includes the ability to disable adding children,
    >   removing children, and removing the module itself.
    > * Added support for removing children.
    > * Fixed a race condition when stacker is being stacked underneath
    >   ANOTHER multiplexor - now set secondary before registering.
    > 
    > 
    > 
    > Greg K-H has made a few really nice comments that I haven't figured
    > out how to respond to (re: locking and do .. while(0)).
    > For the moment, they're in the comments as TODO items so they won't get lost
    > or forgotten.
    > 
    > 
    > 
    > _______________________________________________
    > linux-security-module mailing list
    > linux-security-moduleat_private
    > http://mail.wirex.com/mailman/listinfo/linux-security-module
    > 
    > 
    
    David,
    
    There is a problem with unloading subordinate modules while
    another process is executing one of its hooks.  This can even
    happen on uniprocessor systems if a process is sleeping in a
    hook.  When the module is removed from memory the other
    process will cause an oops or panic when it continues.  One
    way to approach this is to have the multiplexor module read
    lock a subordinate module while any of the subordinate
    module's security operations are called and then grab a
    write lock before removing the module.  If the overhead of
    getting a read lock on each security op call is a problem
    then we could add support to configure child modules to be
    non-unloadable and these modules would not have to grab the
    read lock.  You may be able to solve this problem another way
    when you add locks to the module list.
    
    /* A "module entry" keeps track of one of the stacked modules */
    struct module_entry {
    	struct module_entry *next;
    	char *module_name;
    	rwlock_t module_lock;
    	int state;
    	struct security_operations *module_operations;
    };
    
    calling each child module op:
    
    	for (module_p = stacked_modules; module_p; module_p = module_p->next) { \
    
    		read_lock (&module_p->module_lock);
    		if (module_p->state == ACTIVE)
    			result = module_p->module_operations->CALL; \
    		if (result && !final_result) final_result = result;
    		read_unlock (&module_p->module_lock);
    	}
    
    
    unloading child module:
    
    	for (module_p = stacked_modules; module_p;
    	     module_p_previous = module_p, module_p = module_p->next) {
    		if (!strcmp(name, module_p->module_name)) {
    
    			write_lock(&module_p->module_lock);
    			module_p->state = INACTIVE;
    			write_unlock(&module_p->module_lock);
    
    			/* We found it! Delete it. */
    			if (module_p_previous)
    			       	module_p_previous->next = module_p->next;
    			else
    			       	stacked_modules = module_p->next;
    			/* In theory, we can now free up module_p by doing:
    			 * kfree(module_p->module_name);
    			 * kfree(module_p->module_operations);
    			 * kfree(module_p);
    			 * The problem is that there's no easy way to
    			 * determine when there will be "no more calls".
    			 * Since only highly trusted administrators
    			 * can remove security modules anyway, we'll simply
    			 * leak memory instead if a module is removed.
    			 * We lose very little memory, and removing
    			 * security modules is a pretty rare operation.
    			 */
    			return 0; /* We did it! */
    		}
    	}
    
    
    
    Lachlan
    
    _______________________________________________
    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 : Sun Jul 21 2002 - 21:06:44 PDT