intercepting system calls

From: Amon Ott (aoat_private)
Date: Thu Apr 12 2001 - 00:56:44 PDT

  • Next message: Amon Ott: "GACI item list - to give some items for discussion"

    Hello to you!
    
    I am the main developer of the RSBAC project, so I have seen quite a few
    problems addressed here.
    
    Just to mention: A discussion about a Generic Access Control Interface (GACI)
    for the Linux kernel has already been started between developers from most such
    projects. Unfortunately, the discussion died down.
    
    However, some of the interception problems as well as some others have already
    been conceptually solved on that list in a most-projects-compatible way, and a
    look into its archive at http://www.compuniverse.de/lwgate/gaci might help.
    
    On Don, 12 Apr 2001 Anil B. Somayaji wrote:
    > Linus Torvalds wrote:
    > 
    > > On Sat, 7 Apr 2001, David Wagner wrote:
    > > >   - What to interpose on?
    > > >     Here are a few suggestions for possibilities: interposition on all
    > > >     system calls; interposition on all VFS calls; on sockets.  What else?
    > >
    > > Not at a system call level. It gets too intrusive, and too many people
    > > (including me) start to worry a _lot_ if you lose even one cycle in the
    > > system call path. Linux system calls are lightweight, and I like them that
    > > way.
    > 
    > Light system calls are good, indeed.  I sorry to say that my
    > modifications have killed system call latency (but because system
    > calls in Linux are so lightweight, nobody seems to notice).  However,
    > I also know that security costs something, and if you want to minimize
    > those costs, it is best to do actions at the right place, and at the
    > right time.  If you want to mess with system calls, you should mess
    > with them in kernel-space - anywhere else is either too expensive,
    > insecure, or both.
    
    > >> You interpose on well-defined abstraction levels. Anything else is a waste
    > > of time, and useless. Why should you care if the user does a system call:
    > > sometimes the user can do the same thing by hand, and the system call is
    > > nothing but a convenience. The extreme case of this would be the whole
    > > TCP/IP stack: the user _could_ just open a raw packet socket and do its
    > > own TCP/IP stack totally in user mode. Or think about "gettimeofday()":
    > > it could be a system call on some architectures, and avaiable in user mode
    > > on others.
    > >
    > > And even when you have meaningful system calls like "write", why interpose
    > > on that. Nobody cares if you write to /dev/null, while if you write to
    > > /etc/passwd people might take a second look. You need to get in at the
    > > _meaningful_ level.
    > 
    > System calls _are_ a well-defined abstraction level - it is the
    > abstraction of functions that userspace programs can invoke in the
    > kernel.  It is a fundamental mechanism - system calls are how
    > processes talk with the kernel.  Even memory-mapped IO and raw socket
    > accesses start with system calls.  Except for maybe a few exceptions
    > (which I can't think of at the moment - anyone, please correct me), a
    > process without system calls is a process locked away in its own box,
    > incapable of interacting with the outside world.  Sure, it is
    > Turing-complete, but it isn't too interesting.
    
    I fully agree here. The interception should be optional, but it must be inside
    the syscall implementation. Also, it is hardly possible to keep common code
    up to date for all branches and current versions without some abstraction.
    
    > 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
    > from making changes in the right places.  If you want to mess around
    > with the behavior of execve, you should do it from within the code of
    > 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.
    
    On GACI list, the overhead problem has been solved by having a very light
    decision whether anybody is interested in the interception.
    
    > 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
    > attempted execve's of non-existent files, and differentiate those from
    > execve's of non-executable files.  I don't see how to do this without
    > duplicating the functionality of do_execve, or having hooks at every
    > error condition.
    
    Another point already though about. We (mostly) agreed on at least two
    interceptions per system call implementation function, one before and one after
    performing the actual syscall functionality. The first call should either
    include the result of previous permission() or capable(), or those functions
    should be included into the decision.
    
    All interceptions are only performed, if anybody is listening. This
    check is just a simple table lookup. Each module listening has to give a list
    of interceptions it is interested in, which is used to update the global table.
    
    > So, while I like the general idea of interposing on system calls, I
    > see lots of problems with doing it in practice.  I'm curious - what do
    > 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
    > have one that does 90% of the job for 10% of the effort and 1% of the
    > slowdown.  Otherwise, system call hacks will probably have to continue
    > to live outside the main kernel tree.
    
    Speaking for RSBAC, we need the type of access (e.g. in sys_open etc.
    type of opening (read, write, append)), the full subject and object
    identification and sometimes some extra parameter data, e.g. the uid in
    setuid() or the mode for creation.
    
    I will post the last item list of the GACI discussion in a separate message.
    
    Amon.
    



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