-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hello everyone! My name is Anil Somayaji, and as some of you know (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 differentiate between normal and abnormal program behavior. For this work I've played around with audit packages, strace, and even resorted to wrapping system calls in libc (disassembling SunOS 4 libraries, not something you should ever think of doing). Finally I broke down and started hacking the Linux kernel to do what I needed it to do, and now I'm working on ways to automatically stop attacks based on what happens at the system call level. 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. 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 actually do believe that sometimes you do care that a program is writing to /dev/null - especially if that program normally writes to a log file! But really, what it comes down to is that many people have proposed and tested effective security mechanisms that work at the system-call level. 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. 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. 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. --Anil - -- Anil Somayaji (somaat_private) http://www.cs.unm.edu/~soma +1 505 872 3150 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.4 (GNU/Linux) iEYEARECAAYFAjrVS+8ACgkQXOpXEmNZ3ScE6wCffvYX2bkHlmRSmAl5jbQh/Skx VAUAn1tsFmaMtpCS2TlPfil4zeZoX6N+ =UDEY -----END PGP SIGNATURE-----
This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 14:15:21 PDT