Re: permissive vs. restrictive issue and solutions...

From: jmjonesat_private
Date: Wed Jun 06 2001 - 08:43:55 PDT

  • Next message: jmjonesat_private: "Re: permissive vs. restrictive issue and solutions..."

    On Wed, 6 Jun 2001, Stephen Smalley wrote:
    
    > 
    > On Wed, 6 Jun 2001 jmjonesat_private wrote:
    > 
    > > My objection is that, in any case, your solution requires the kernel
    > > logic to be evaluated before the module is called, and requires a 
    > > hook by hook decision as to if it may be relevant enough to include 
    > > the argument in the list.  
    > 
    > Having the kernel logic evaluated and passed to the module is quite
    > useful, both in allowing the module to be authoritative and in
    > allowing the module to audit the result of the overall decision.
    > It is unavoidable that we make a hook-by-hook determination,
    > because not every hook has corresponding kernel logic and even
    > when there is corresponding kernel logic, not every hook can be 
    > colocated with that logic.  But the question is not relevance,
    > just existence and colocation.
    > 
    
    Okay, if that's the "test", I withdraw that argument, except there 
    are STILL "don't need it" places that must pay for it.
    
    > >This creates the following situation:
    > > 
    > > 1) Module designs that totally ignore the original kernel logic must
    > >    still wait for it to be resolved, discarding the result.
    > 
    > Totally ignoring the base logic would break applications.  
    > You can't arbitrarily change the kernel security model without 
    > impacting applications.
    > 
    
    This is true.  However, there are many ways to "skin a cat" and 
    the module may have other ways to determine what is permissible and 
    what is not... perhaps reducing the logic to another form (based 
    on other information it has acquired) or simply "no under any
    circumstances" in a some cases.
    
    For example, by maintaining a purely per-process ACL.  In that case
    the uid, euid, capabilities, and anything else under which the process is
    running are irrelevant.
    
    No working module should be "arbitrary", and my proposal doesn't 
    suggest it should be, just that there may be "purposful" reasons
    that the kernel logic is not necessary.
    
    > > 2) A consensus must be reached in the design of the interface to 
    > >    add "kern_retval" to each hook that "may" need it.  While we're 
    > >    all one big happy family ;), I suspect that different security 
    > >    module designs will need it in different places.  Requiring a 
    > >    central decision on where to add it instead of a mechanism that 
    > >    allows individual modules to "choose" if kern_retval is significant, 
    > >    (and, therefore, if it needs be calculated,) not only puts us in a 
    > >    perpetual argument for "add this", but forces those that don't 
    > >    need it to pay (the computational cost) for it.
    > 
    > It isn't a question of whether the hook may need the kernel
    > decision, just whether such a decision exists and can be
    > colocated.  Also, think about real security modules.  Most
    > of the access control modules under discussion are primarily concerned
    > with being restrictive, so they always want the kernel decision.
    > Likewise, auditing modules will want the kernel decision.
    > 
    
    So, this solution would require 100% of the places with a kernel decision
    to make it, and then pass it to the module?  That's the worst case for 
    modules that discard the result or base their decisions on factors other 
    than those inherent in the base kernel decision.  On the other hand, I 
    see your point as being "arguable for the most common case", but also hold
    it's not "arguable for EVERY case, nor will the current "most common case" 
    NOW remain that way in the future . 
     
    > > 3) If you move the kern_retval check to AFTER the module, by the 
    > >    request of the module, it is possible that some of what is 
    > >    checked (such as euid) *may* be altered by the module before
    > >    the evaluation is done, allowing the module some influence 
    > >    in the result.  Yes, you could duplicate the check in the module
    > >    with a value changed, but now you're doing the check twice.
    > 
    > Consider auditing modules.  They need to know the final authoritative
    > decision, including both the kernel logic and the module logic.  
    > Under your scheme, they have to duplicate the check.  That seems
    > like a much more common situation than what you describe.
    
    Yes, they'd have to duplicate the check, since the logic is left in 
    the kernel code and not "shared" externally, which would, in my opinion,
    be the best, albeit more invasive, solution.
    
    Perhaps there is common ground?  By adding a set of audit calls to which 
    the decision is passed before return, such as
    
    return security_ops->a->something(-ENOFREAKINWAY), 
    
    instead of
    
    return -ENOFREAKINWAY;
    
    which would break out the audit problem completely. 
    
    I see auditing as a totally different area we're trying to cover. It's 
    a passive information collector, not necessarily an active security
    element.
    
    Here's what I'm looking for:
    
    1) absolute consistency across the interface (with the exception 
       of any capabilities intervention.)  In essence, the same calls
       with the same arguments to both mirrored restrictive and permissive ,
       but with some "in-kernel" differentiation to enforce the restrictiveness
       or permissiveness of a function, to satisfy the "authoritative" group. 
       Perhaps the same calls mirrored in security_operations->a-> all having
       ONE argument "result".  (Because it's the more common case, I think
       "restrictive rulez" seems to be the logical choice.)
    
    2) an inherent mechanism in the hooks to divide the "functionality"
       of the code into capability, restrictive, permissive, and "other"
       which may be "audit" or "post decision."
    
    3) a design for the security_operations structure that can consistantly
       be evolved without having to rewrite modules, supporting all of
       capability, restrictive, permissive, or kernel without imposing
       additional overhead on any of the solutions.  Simply, by 
       dividing the structure, we allow modules with the "previous version"
       structure imbedded to continue to operate without
       redesign/recompilation/redistribution.
    
    4) a way to short circuit any decisions not made by the "appropriate
       area" ... module, kernel, whatever ... with module logic, preferring
       restrictive to permissive.
    
    There are a number of "messier" schemes that allow all this, including 
    "callback" schemes, etcetera.  It costs a little now, admittedly, but 
    by reducing the cost as far as we can and KEEPING the possibility inherent
    in the interface, we have a forward path to as many options as possible 
    without having to "go back and rework" or "tack on" to the interface.
    
    May save thousands of coding hours split across dozens of modules in the
    future.
    
    Your argument combines "auditing" with "authoritative", which may not
    always be combined (even finer, not combined in the same function... 
    a purely auditing module may not NEED all the crap we're
    passing it, just the "Final Answer" to quote Regis) One is active, the
    other is passive. By breaking the "switch" into the kernel side, it is
    clearer and less "necessarily burdensome" on the other side of the
    interface.
    
    I know I'm argued out on a limb, since my solution may be "messier" than 
    necessary.  But the core objectives of it are still, I think, arguably
    desirable.  I'd welcome any solution that is less messy and equally 
    functional.
    
    It comes down to this: by explicitly supporting stackable modules at this
    time we can stack the right "flavors" in the right order.  By requiring
    the kernel decision stays in the core code, I think we need to separate
    some of the "possibilities" in the interface to feed back to the logic we're
    leaving in the core kernel.
    
    If I'm alone, so be it.  I'll design to any interface that results from 
    these discussions, but I want as much freedom in my module as possible 
    without having to "accept" overhead not-absolutely-necessary-but-useful to
    other projects, and  DON'T want to have to patch the kernel (ever) or
    track every small change in the LSM interface to keep my module working.
      
    > 
    > --
    > Stephen D. Smalley, NAI Labs
    > ssmalleyat_private
    > 
    
    Respect and Admiration,
    J. Melvin Jones
    
    
    |>------------------------------------------------------
    ||  J. MELVIN JONES            jmjonesat_private 
    |>------------------------------------------------------
    ||  Microcomputer Systems Consultant  
    ||  Software Developer
    ||  Web Site Design, Hosting, and Administration
    ||  Network and Systems Administration
    |>------------------------------------------------------
    ||  http://www.jmjones.com/
    |>------------------------------------------------------
    
    
    
    
    
    
    _______________________________________________
    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 Jun 06 2001 - 08:46:23 PDT