If an LSM module wants to be able to stack "under" a primary module, it needs to let the OTHER modules act like the dummy or capability module. This is ESPECIALLY true for the capable() hook, because it's authoritative. Also, values like "secondary" need to be set BEFORE they're registered, to avoid a race. Here's a quick example, using the owlsm module. I haven't tried to compile this yet (although I believe this one's fine, because it's such a small change). Again, I'm looking for comments on the overall approach. Comments? --- owlsm.c.orig Sun Jul 21 09:10:42 2002 +++ owlsm.c Sun Jul 21 09:22:18 2002 @@ -28,6 +28,10 @@ /* flag to keep track of how we were registered */ static int secondary; +/* Should we emulate the dummy module? Set this to 0 if + we're a secondary module or if we have a child that acts + as an LSM tail (e.g., "capability" or "dummy") */ +static int pseudo_dummy = 1; static int owlsm_sethostname (char *hostname) { @@ -89,7 +93,8 @@ static int owlsm_capable (struct task_struct *tsk, int cap) { /* from dummy.c */ - if (cap_is_fs_cap (cap) ? tsk->fsuid == 0 : tsk->euid == 0) + if (pseudo_dummy && + (cap_is_fs_cap (cap) ? tsk->fsuid == 0 : tsk->euid == 0)) /* capability granted */ return 0; @@ -136,18 +141,22 @@ static int owlsm_netlink_send (struct sk_buff *skb) { /* from dummy.c */ - if (current->euid == 0) - cap_raise (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN); - else - NETLINK_CB (skb).eff_cap = 0; + if (pseudo_dummy) { + if (current->euid == 0) + cap_raise (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN); + else + NETLINK_CB (skb).eff_cap = 0; + }; return 0; } static int owlsm_netlink_recv (struct sk_buff *skb) { /* from dummy.c */ - if (!cap_raised (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN)) - return -EPERM; + if (pseudo_dummy) { + if (!cap_raised (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN)) + return -EPERM; + }; return 0; } @@ -566,7 +575,8 @@ static void owlsm_task_reparent_to_init (struct task_struct *p) { - p->euid = p->fsuid = 0; + if (pseudo_dummy) + p->euid = p->fsuid = 0; return; } @@ -595,10 +605,12 @@ unsigned char **pp_ptr) { /* from dummy.c */ - if (!skb && !capable (CAP_NET_RAW)) { - (const unsigned char *) *pp_ptr = optptr; - return -EPERM; - } + if (pseudo_dummy) { + if (!skb && !capable (CAP_NET_RAW)) { + (const unsigned char *) *pp_ptr = optptr; + return -EPERM; + } + }; return 0; } @@ -1048,12 +1060,17 @@ printk (KERN_INFO "Failure registering owlsm module with the kernel\n"); /* try registering with primary module */ + /* NOTE: The module must be completely ready to go + * before calling mod_reg_security. In particular, to avoid + * a race condition, we must set "secondary" and + * and "pseudo_dummy" BEFORE calling mod_reg_security */ + secondary = 1; + pseudo_dummy = 0; if (mod_reg_security (MY_NAME, &owlsm_ops)) { printk (KERN_INFO "Failure registering owlsm module " "with primary security module.\n"); return -EINVAL; } - secondary = 1; } printk(KERN_INFO "owlsm LSM initialized\n"); return 0; _______________________________________________ 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 - 06:32:42 PDT