Re: OWLSM - please update! Also, here are tweaks to stack it.

From: David Wheeler (dwheelerat_private)
Date: Tue Dec 17 2002 - 06:25:37 PST

  • Next message: Greg KH: "Re: [PATCH] LSM changes for 2.5.52"

    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