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 (¤t->security->semaphore); > /* do my stuff that changes the contents of current->security */ > ... > up (¤t->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