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

From: jmjonesat_private
Date: Tue Jun 05 2001 - 12:02:18 PDT

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

    On Tue, 5 Jun 2001, Chris Wright wrote:
    
    > * Stephen Smalley (sdsat_private) wrote:
    > > 
    > > On Mon, 4 Jun 2001, Crispin Cowan wrote:
    > > 
    > > > That's interesting.  "kick capabilities out" was popular with WireX engineering at
    > > > last week's weekly meeting, and with David Wagner.  The remaining request for
    > > > permissive controls is Casey's, but he hasn't said much about it.
    > > 
    > > Just to be clear, I'm not really suggesting that we "kick capabilities
    > > out".  Here is what I am proposing:
    > > 
    > > 1) We leave the existing capabilities module alone, but we revert the
    > > calls to capable() in the kernel.  The capable() function remains
    > > as a stub that calls the LSM capable() hook (or, better, we
    > > use a script to globally replace all calls to capable() with a
    > > direct call to the hook).  We also replace the capabilities system calls
    > > with stubs that call LSM hooks, and move their functionality into the
    > > capabilities module.  
    > 
    > What do we do with complex logic like (arch/i386/kernel/ptrace.c):
    > 
    > if(((current->uid != child->euid) ||
    >    (current->uid != child->suid) ||
    >    (current->uid != child->uid) ||
    >    (current->gid != child->egid) ||
    >    (current->gid != child->sgid) ||
    >    (!cap_issubset(child->cap_permitted, current->cap_permitted)) ||            
    >    (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
    >       goto out_tsk;
    > rmb();
    > if (!child->dumpable && !capable(CAP_SYS_PTRACE))
    >    goto out_tsk;
    > 
    > The problem here is with the call to cap_issubset, and how deeply it is
    > embedded in the logic.  The lsm ptrace hook actually allows for the
    > cap_issubset() call because it takes both child and parent
    > task_structs.  To use the hook would really mean pushing all of this
    > logic into the capablilties.  To leave the capable calls means either
    > leaving cap_issubset (and consequently leaving the capabilities bits in
    > the task_struct as opposed to pushing them into the task security blob)
    > _or_ exposing cap_issubset in the lsm interface (or creating something like
    > it...you may recall some ugly hack I had in the earlier interface that
    > supported a generic way to compare credentials).
    > 
    > The compute_creds function (fs/exec.c) is another example of how
    > capabilities is inbred with the kernel.  That's why I took the easy
    > approach on that function and pushed the whole thing into the module.
    > 
    
    This is the "devil in the details" that I was intuiting, although I'm 
    not sure how terrible it might be.  Pushing ALL the capabilities
    EVERYTHING (embedded logic, calls, checks) to the LSM interface cleanly
    divides it into a module that can exist or not exist, and has some 
    advantages in my mind.
    
    > > This supports the following desireable goals:
    > > a) People who don't like capabilities can easily use a superuser
    > > module in place of the capabilities module.
    > 
    > Seems reasonable, although capabilities is essentially a superuser check
    > since people rarely actually set any capabilities.  I'm not sure we need
    > to support two modules.
    
    Possibly just support capability_plug, and leave the superuser (or other) 
    to individual module developers to "bend" as their policy sees fit.
    
    > 
    > > b) The capabilities developers can easily evolve the implementation
    > > of their core logic without involving the kernel developers.  In
    > > particular, they should be able to provide their new logic with
    > > real file system capabilities as a module (assuming they can get
    > > the corresponding file system support adopted in some way).
    > 
    > This does seem useful.
    
    Meets my "move it to the module" desire.
    
    > 
    > > c) Both the superuser module and the capabilities module only
    > > need to implement the capable hook and the hooks related to
    > > execve processing and the capabilities system calls.  All
    > > other hooks can simply return 0.
    > > d) Other module developers can support DAC overrides using methods 
    > > other than superuser or capabilities (e.g. Type Enforcement) by
    > > implementing their own capable() hooks.
    > 
    > Limited of course to the course granularity provided by linux privs (I
    > believe that was 29 different capabilities with CAP_SYS_ADMIN being the
    > least useful abstraction).
    > 
    > > e) Kernel code modifications related to capabilities are minimized 
    > > and localized.
    
    More interested eyeballs on the needle in the haystack.  Very good.
    
    > > 
    > > 2) All LSM hooks other than capable() should be used authoritatively.
    > > If a LSM hook can be easily placed at the same location as the
    > > existing logic, then the LSM hook can take an additional parameter
    > > to give it the option to override the kernel's logic, in which case
    > > it can be used either restrictively or permissively.  If not,
    > > then LSM hook can only be used restrictively.  
    > 
    > I just want to make sure it is clear that this is approach is an
    > official endorsement for maintaining two sets of hooks in the lsm
    > interface (a restrictive set and a permissive set).  Is that what we
    > want?
    
    
    This, sounds messy, but may be the only "clean" way to make everybody 
    happy.  If it's generalized as a strategy, the evaluation of hook
    placement is clarified, and there's a clear forward path to later (after
    we're accepted into the kernel) adding either/or, neither/nor.
    
    if ((error=permissive_hook_X(...))==LSM_USE_KERNEL) {
      [original kernel logic]
      error=whatever;
    }
    else
    {
      whatever;
    }
    ...
    if ((error=restrictive_hook_X(...))) {
      return -ENOFREAKINGWAY;
    }
    
    // Because of the way kernel errors are reported (always negative), don't
    // we have room for LSM_USE_KERNEL=1 in most places?
    
    SEEMS to allow all sorts of neat (and desirable) things without forcing
    
    [original kernel logic]
    if (permissive-or-restructive_hook_X(error,...))
    {
      return -ENOFREAKINGWAY;
    }
    
    and, at a minimal (one test) cost.
    
    Clearly, the "deeply imbedded logic" problem must move to the module, in
    my thinking, which is where I believe it should be.  In those cases, it 
    is a sort of "assumptive tack on" to the original logic any, imho.
    
    Additionally, the "grep test" Crispin mentioned is pretty clear cut.
    Module never uses "permissive_hook_X", it's arguably "clean".
    
    By doubling the hooks, but, FOR NOW, only where there is a clear division,
    it accomplishes the same result (I think) as my "STANDARD module"
    proposal... by identifying clearly where permissivity is allowed, and 
    where it is not, without resorting to "explicit support of module
    stacking", which, while I desire it, is still in its infancy and
    *implied* here without further "evolution" at this time. :)
    
    Mr. Smalley's refinement, I BELIEVE, simply addresses the next step 
    as to how to "divide" where the FOR NOW minimum lies.
    
    Moving as much of the capability problem OUT to the "plug" lays the
    groundwork for "tossing it altogether", too.
    
    
    What we end up with in the LSM interface is
    
    The capability interruptus sub-interface
    The LSM permissive sub-interface
    The LSM restrictive sub-interace
    
    Is that correct?
    
    Could we further generalize it in the security_operations structure to 
    
    struct security_ops
    {
      struct capability_ops  *c;
      struct permissive_ops  *p;
      struct restrictive_ops *r;
    }
    
    (not meant to be actual code)
    
    With the hooks underneath exactly duplicating each other, with some 
    labeled (in comments) as "NEVER CALLED" for now, leaving minimal change
    of the structure in the future and N modules, but only an argument over
    adding newly placed hooks?
     
    > 
    > -chris
    > 
    
    I Hope I'm Not TOTALLY Lost, At This Point,
    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 : Tue Jun 05 2001 - 12:04:17 PDT