intercepting system calls

From: Douglas Kilpatrick (dougkat_private)
Date: Thu Apr 12 2001 - 06:52:34 PDT

  • Next message: Scott Leerssen: "intercepting system calls"

    On 12 Apr 2001, Anil B. Somayaji wrote:
    
    > (and most of you probably don't), for the past few years I've been
    > doing research on how short sequences of system calls can be used to
    
    My name is Doug Kilpatrick, and I've been working on the Generic
    Software Wrappers TookKit (GSWTK), an in-kernel module that tries to
    make writing security-related kernel modifications easy.
    
    One of our example wrappers does sequence based intrusion detection
    and enforcement...
    
    > I mention this just to say that I've had to grapple with what it means
    > to monitor and interfere with system calls in Linux, and so I have
    > some comments to make about Linus's thoughts on system-call
    > interposition.
    
    Same.
    
    > Light system calls are good, indeed.  I sorry to say that my
    > modifications have killed system call latency (but because system
    
    We tried to measure our effect.  Basically, the only way to measure it
    is to pick the smallest system call you can find (gettimeofday() or
    getpid(), or something like that) and hammer it.
    
    Since most interresting decision points happen on expensive operations
    (fork, open), the added latency was normally not an issue.
    
    FreeBSD does a per-process system call vector: That approach should
    allow flexibility in terms of "cost only when used".
    
    > System calls _are_ a well-defined abstraction level - it is the
    
    Until you start looking at some of the SysV messaging system calls.
    Or trying to change return-data for something like recvfrom...
    
    > Having said that, I don't think a completely general system-call
    > interposition mechanism would be a good idea.  It would definitely add
    > significant overhead.  But worse, it would probably discourage people
    
    Take a look at GSWTK... It has some ugly build issues right now as it
    builds a module that intercepts things not exported to modules, but
    its reasonably quick for what it does.
    
    > do_execve.  If some security code gains control before do_execve has
    > run, you're stuck with decoding the arguments to execve, which means
    > that the security code has to duplicate the checks and repeat the
    > processing done in do_execve.
    
    Yep.  Execve is a pretty straight forward example though... As long as
    you are trying to augment the system call and not replace it, the
    argument decoding you do is pretty straight forward.
    
    For a worse example, look at the network syscall (socketcall(2).  Lots
    of painfull copying and bit banging that the real syscall will just
    do again later.
    
    > OK, maybe you could have a hook somewhere in execve - but where would
    > you put that hook?  Maybe a security module wants to keep track of
    
    7I'll talk about "event notification below... but that's not to change
    execve, that's just to know that it happened.
    
    > other people actually want to do to system calls?  How much info is
    > needed?  Maybe we can't have a really flexible API, but maybe we can
    
    IMHO:
    	Per process sysent vector
    	OnExec/OnExit/OnFork notification
    
    	Those 4 things buy you a lot As Far As Prototyping goes.
    (Please see GSWTK for a language that makes it even easier).  As far
    as real security modules go, I suspect most of them want to be much
    more invasive.
    
    
    
    Ok, I mentioned lifecycle-event notification:
    
    Notification of
    
    exec:	syscall capture works, although is painfull.  A notification
            point at which success vs. failure has been determined, but
            the args (file, argv) still exist would be better.
    
    fork:   Put hook right before "wake_up_process".  Child exists, the
            child's process pointer is available, but it has not started
            running yet.
    
    exit:  For linux we needed two hooks, one at "exit_thread", the other
           at "free_uid".  The first prevents us fro doing anything stupid
           during process exit, the second tells us to nuke objects
           associated with the process.
    
    
    The other issue is per-process data.  I know we needed quite a bit of
    bookkeeping information.  Not being able to modify the proc structure,
    we had our own internal list keyed on pid.  A small number of generic
    void* pointers on task_struct would make life easier.
    
    We also frequently found ourselves wanting to make decisions based on
    what a given file descriptor refered to.  Usually we ended up cacheing
    information about the fd at fd-creation time, and looking it up at
    decision time.  I don't know if this is an issue, or just evidence of
    how easy it is to forget "The One Unix Way" of doing things.
    
    
    Doug
    -- 
    dougkat_private
    dkilpatrat_private
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 14:15:23 PDT