Thinking about stacking in LSM: merge registering, add info about field use to security_operations

From: David Wheeler (dwheelerat_private)
Date: Thu Jul 18 2002 - 11:18:09 PDT

  • Next message: Chris Wright: "Re: Thinking about stacking in LSM: merge registering, add info about field use to security_operations"

    I've been thinking about how stacking is currently supported,
    and I think there's a simpler and cleaner approach:
    1. Merge the mod_reg_security() and register_security() calls
        into a single function, and do the same to
        their corresponding unregister functions.
    2. Add to security_operations a field so the LSM module identifies
        WHICH opaque security fields it uses in the kernel data structures,
        both to document its needs and as a way to perform simple
        checking for some nasty problems.
    
    
    Here's my thinking, hopefully I'm not too far off-base.
    
    
    Currently at the top level there are
    register_security()/unregister_security() calls,
    and there are also mod_reg_security()/mod_unreg_security() calls.
    The first pair pass only the struct security_operations;
    the second pair pass the name and security_operations, with the
    intent that the module is going to be "stacked".
    
    I don't think that having two _separate_ pairs of operations
    is the best approach.  Why not have a SINGLE pair of operations,
    register_security() and unregister_security(), called by any
    LSM module, that take both the name and the struct security_operations?
    That way any LSM module that registers always calls register_security().
    The "first" module loaded is always the primary security policy
    (until it's unloaded and another takes its place).
    Once a primary module is registered,
    any other LSM module that tries to load would (as always) call the top
    level register_security(), and the kernel would immediately
    detect that it's NOT the primary (since there's already one) and
    call the function defined in the primary's register_security()
    field of its security_operations.
    Primary modules that don't support stacking underneath them can just
    forbid the request, those that support stacking only specific modules
    can permit only those modules, etc.
    
    This should simplify the common case of "I have an LSM module,
    how do I register?".  The answer is always "call register_security()".
    This would make it easier to create multiplexor-capable
    modules.  More importantly, it would concentrate most decisions
    about "can these modules be multiplexed together" into the
    primary security module/multiplexor.  In short, rather than
    writing separate "capable of being subordinate" and "capable of being
    a primary" modules, a module can always be both.
    Not all LSM modules can be combined, but it seems to me
    that this decision belongs to the administrator installing the modules.
    
    Of course, this doesn't mean that any two arbitrary LSM modules
    will get along.  Although there may be other reasons, probably the
    most obvious reason is that some LSM modules may use the
    'opaque' data fields in certain kernel structures.
    Unless these modules work together and/or share the fields,
    there will serious trouble.   As both an aid to documentation and
    to detect and prevent problems, I think it'd be useful to add
    yet-one-more-field to security_operations, so that an LSM module
    can report on WHICH fields it uses and HOW it uses them.
    To do this, add a field security_operations something like this:
        unsigned field_usage;
    
    Then, for each kernel structure where there's an opaque security
    field type, identify if it's "USED" (e.g., the LSM module needs complete
    control) or "SHARED" (shared through some sort of linked-list
    convention not yet defined, though I know it's been discussed)
    by the LSM module as part of the security_operations information.
    
    Thus, an LSM module might include its declaration of its
    security_operations a value like this for the field_usage value:
        TASK_SECURITY_FIELD_USED | LINUX_BINPRM_SECURITY_FIELD_USED |
        INODE_SECURITY_FIELD_USED | FILE_SECURITY_FIELD_USED
    
    This obviously has uses for the multiplexors - they could at least
    check that any LSM module loaded didn't have a "USED" or "SHARED"
    value for a field that conflicts with the currently loaded LSM modules.
    Perhaps this could be overridden, but it would certainly be a warning.
    This is also quite useful for documentation - instead of wondering
    "which fields does this LSM module use", you can see it right there
    in the call.  Clearly this won't detect all incompatibilities, but
    this would at least detect many nasty cases at little cost.
    Obviously, this requires a tweak to VERIFY_STRUCT since "0" is a
    perfectly acceptable value for this field, but that shouldn't be
    too bad.
    
    Sorry I'm sending these observations so late, but I just
    thought them up.  I may be all wet, if so, my apologies.
    Comments?
    
    
    --- 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 : Thu Jul 18 2002 - 11:26:17 PDT