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
dwheeler@ida.org
_______________________________________________
linux-security-module mailing list
linux-security-module@wirex.com
http://mail.wirex.com/mailman/listinfo/linux-security-module
This archive was generated by hypermail 2b30 : Wed Dec 18 2002 - 19:35:51 PST