Greg - A few tweaks are needed so the module can stack properly. Since owlsm will be a "demo" module, it really should stack correctly. Also, I think owlsm is a great candidate for stacking, since I can easily see situations where you'd like (for example) BOTH owlsm AND some larger module like selinux. BTW, I looked at my last post and it wasn't as clear as it should have been, sorry. The problem is you need to check the "secondary" value; if it's true, return 0 for everything other than capable(), and return -EPERM in capable. Capable() is different because it's an _authoritative_ hook, unlike all other hooks. This way, the stacking module can use capable, or dummy, or something completely different as the "terminator". For example, someone who is stacking modules might want to use a _variant_ of capable() that only grants capabilities if some additional conditions are met. I realize this change adds a check for a boolean in a few hooks (the ones that call cap_*()). However, this check is only performed in cases where you were going to do a function call to a capable module function (a much more expensive operation) anyway, checks on booleans are relatively cheap, and this demonstrates how to correctly create a stackable LSM module. And look what new functionality you get: users can now select an alternative to the capable module, and stack with other modules, without changing one line of code. Thus, instead of: > static inline int do_owlsm_sfd_set (struct linux_binprm *bprm) > { > - return 0; > + return cap_bprm_set_security(bprm); > } > > static inline void do_owlsm_sfd_compute (struct linux_binprm *bprm) > { > - return; > + return cap_bprm_compute_creds(bprm); > } > #endif /* CONFIG_OWLSM_FD */ It should be: static inline int do_owlsm_sfd_set (struct linux_binprm *bprm) { if (secondary) { return 0; } else { return cap_bprm_set_security(bprm); } } static inline void do_owlsm_sfd_compute (struct linux_binprm *bprm) { if (secondary) { return 0; } else { return cap_bprm_compute_creds(bprm); } } (and so on, for all other calls, inserting if (secondary) {return 0;} else..). Also, instead of: > + .capable = cap_capable, You need: .capable = owlsm_capable, with the following implementation: static int owlsm_capable (struct task_struct *tsk, int cap) { if (secondary) { return -EPERM; } else { return cap_capable(tsk, cap); } } Now, a stacking module can replace the capable module with something else, but when you install the owlsm by itself, it uses the capable module by default. > } > > static inline void do_owlsm_sfd_compute (struct linux_binprm *bprm) > { > - return; > + return cap_bprm_compute_creds(bprm); > } Of course, all this implies that when you install yourself, you try to install as a primary, and if that fails, you FIRST set secondary=1 and THEN try to install with the primary module. Don't register with the primary module and THEN set secondary=1, you end up with a race. Here's what it looks like: static int __init owlsm_init (void) { if (register_security (&owlsm_ops)) { printk (KERN_INFO "Failure registering owlsm module with the kernel\n"); secondary = 1; /* try registering with primary module. */ if (mod_reg_security (MY_NAME, &owlsm_ops)) { printk (KERN_INFO "Failure registering owlsm module\n"); return -EINVAL; } } printk(KERN_INFO "OWLSM initialized\n"); return 0; } Is that clear?? --- David A. Wheeler dwheelerat_private _______________________________________________ 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 : Wed Dec 18 2002 - 19:35:51 PST