Re: semaphores (was Re: quotactl hook)

From: Stephen Smalley (sdsat_private)
Date: Tue Sep 04 2001 - 12:20:18 PDT

  • Next message: jmjonesat_private: "Re: quotactl hook"

    Just as a side note, you have to be careful about using semaphores in the 
    hook functions, because some of the hook functions are called from 
    interrupt (e.g. networking-related hooks, send_sigiotask).  So, for 
    example, if you insert your module into a running kernel, and one of these 
    hooks is called on a task that doesn't have a security blob yet or on a 
    socket whose inode doesn't have a security blob yet, and your hook calls 
    my_module_task_alloc_security or my_module_inode_alloc_security, the 
    kernel will die if your function blindly tries to take the semaphore.
    
    I raised this issue with Greg in private email, and he suggested checking 
    in_interrupt() prior to trying to take the semaphore and aborting if you
    were called from interrupt (or falling back to some safe behavior that
    doesn't require the semaphore and is non-blocking).  
    
    --
    Stephen D. Smalley, NAI Labs
    ssmalleyat_private
    
    
    On Sun, 2 Sep 2001, Greg KH wrote:
    
    > On Sat, Sep 01, 2001 at 08:48:23PM -0400, jmjonesat_private wrote:
    > > 
    > > How?
    > > 
    > > If the "blob" is not allocated and the module gets it, how do I lock it
    > > prior to one of the threads allocating and starting it flying?
    > 
    > Here's one way to do it:
    > 
    > This is all in your module code:
    > 
    > static struct semaphore task_semaphore;
    > 
    > int my_module_init_function (void)
    > {
    > 	init_MUTEX (&task_semaphore);
    > 
    > 	/* now register my module with the lsm framework */
    > 	...
    > }
    > 
    > int my_module_task_alloc_security (struct task_struct *p)
    > {
    > 	down (&task_semaphore);
    > 	if (p->security == NULL) {
    > 		p->security = kmalloc (sizeof (struct my_task_security_struct));
    > 		if (p->security == NULL) {
    > 			up (&task_semaphore);
    > 			return -ENOMEM;
    > 		}
    > 		init_MUTEX (&p->security->semaphore);
    > 		/* init the rest of your stuff */
    > 		...
    > 	}
    > 	up (&task_semaphore);
    > 	return 0;
    > }
    > 
    > int my_module_task_setgroups (int gidsetsize, gid_t *grouplist)
    > {
    > 	if (current->security == NULL) {
    > 		ret = my_module_task_alloc_security (current);
    > 		if (ret)
    > 			return ret;
    > 	}
    > 	
    > 	down (&current->security->semaphore);
    > 	/* do my stuff that changes the contents of current->security */
    > 	...
    > 	up (&current->security->semaphore);
    > 
    > 	return 0;
    > }
    > 
    > 
    > So you have a semaphore that protects you initializing the task
    > structure's security blob.  This has to be a semaphore as you will be
    > calling kmalloc which can sleep (can't hold a spinlock across a sleep).
    > 
    > And you check the value of p->security _after_ you get the lock in case
    > you were sleeping on the lock when another call was allocating the same
    > structure.
    > 
    > Then you have a local semaphore (or can be a spinlock, just don't call
    > any sleepable functions while it is held.  these are functions like
    > kmalloc, copy_*_user, printk, and others) that protects your local data
    > within your blob.  A read_write lock might be good to use for your
    > internal data if you find that you are mostly reading things and not
    > writing them.  Check out the research done in the netfilter locks if you
    > want to see some truly looney read_write locks that are very cool (paper
    > was presented at OLS 2001 about this.)
    > 
    > Did that help?  Much easier than keeping a list of places you've been.
    > 
    > Usual disclaimer applies, this is not tested code, was written first
    > thing in the morning before really waking up, etc...
    > 
    > greg k-h
    
    
    _______________________________________________
    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 : Tue Sep 04 2001 - 12:22:46 PDT