Date: Fri, 9 Jul 1999 04:08:41 -0400 (EDT) From: Robert Watson <robert@cyrus.watson.org> To: Nate Williams <nate@mt.sri.com> Cc: Darren Reed <avalon@coombs.anu.edu.au>, Ben Gras <ben@nl.euro.net>, freebsd-security@FreeBSD.ORG Subject: Re: how to keep track of root users? Message-ID: <Pine.BSF.3.96.990709034644.24202B-100000@fledge.watson.org> In-Reply-To: <199907081645.KAA29163@mt.sri.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, 8 Jul 1999, Nate Williams wrote: > > > [ Intrusion detection ] > > ... > > > > My feeling is that perhaps KTRACE should be initially modified so that > > records for a particular context (that is, when entering kernel mode, a > > particular syscall) should be buffered in some way associated with the > > context, and then "commit" could be called in the syscall return (or > > signal return, etc), resulting in the records being flushed to the KTRACE > > management routines. > > There are other issues with the KTRACE facility that have come up. Most > notably, for IDS systems, you need a *LOT* more information than KTRACE > provides. > > For example, in the exec() syscall, not only do you want the argument of > the file you are exec'ing, you also want the file permissions, size, > ownership, gid of the user, mount flags of the FS (it may be NO_EXEC of > NO_SUID) so you can do proper detection. None of this information is > provided via KTRACE, and according to our IDS expert, it's necessary to > do proper detection. This is certainly true--I believe KTRACE also does not provide the environmental variables, also desirable at exec-time. I suppose what we should really be doing, in line with what we've discussed thus far, as assembling an API for submitting IDS information. Hopefully one a little more general and cleaner than the hack I have been using. Something exposed enough in syscalls that it is clear to the casual syscall implementer how to apply it in their own code. Maybe something on the order of: #ifdef POSIX_AUD /* declare a record context */ audrec_t audrec; #endif ... #ifdef POSIX_AUD /* allocate the record */ if (!audrec = k_aud_new_record()) return(...appropriate error...) k_aud_settype(audrec, AUD_AEV_CHMOD); k_aud_setcred(audrec, p->p_cred); ... #endif The problem raised here again, of course, is the copyin of string arguments. Another problem is error-handling: at any possible exit point from the syscall, we need to commit an audit record describing the exit (in error, success, etc). This suggests instead making auditing to some extent implicit to the syscall: a record is created associated with the process structure (or thread or whatevr) when entering kernel mode, and committed when returning to userland (or explicitely committed if we are never going to return, i.e., the process called _exit). Kernel code in the syscall may optionally add additional information about the kernel entry point using a set of calls that automatically modify the implicit audit record state associated with the proc, meaning no need to allocate an audrec or pass it into all the routines, as it might be in p->p_curaudrec. #ifdef POSIX_AUD AUD_SET_SYSCALL(AUD_AEV_CHMOD); AUD_ADD_ARG(AUD_PATHNAME, ...); AUD_ADD_ARG(AUD_MODE, SC(args, mdoe)); ... #endif Information like credentials, pid, return code, syscall number would automatically be inserted when available by the syscall handler. Syscall number could be overriden by an explicit call. This still leaves us with dealing with the arguments, especially pathnames and arrays of strings (e.g., argv[] or env[]). > I'm of the opinion that to make truly useful IDS records, we're going to > have to make some significant changes to the FreeBSD kernel. Note, > these changes are only going to affect folks who ask for kernel auditing > (not KTRACE), but because of the type and quantity of information > desired in IDS systems, it will cause a performance hit in those systems > that desire it. The difference between "don't want any auditing" and "interested in auditing" is easily enough dealt with by #ifdef POSIX_AUD. The difference between "some auditing" and "all auditing" is more challenging: to what degree is filtering of records in the kernel appropriate, and to what degree should that be done by a userland audit daemon or audit record manager? A large volume stream of records in the kernel bloats the kernel and cuts into preemptible execution time. But adding too much filtering in kernel is costly also, and requires a lot more bloat in the kernel. POSIX.1E only defines a way to tell whether auditing is turned on or off for a specific process, and to toggle that (so that, for example, the audit daemon can turn off auditing so as to prevent feedback on audit record delivery). This seems to broad to me. Suppose active IDS modules only require fork(), exec() and exit() tracing--then delivering the 20,000 calls to gettimeofday() is a waste of resources. For my userland audit daemon, I currently have a simple propositional logic matching language, essentially providing boolean matching on record features (requiring certain named entries to exist, perhaps requiring certain things of their value) for the audit daemon to pass a record to a particular dynamically linked module. That seems like too much overhead to go in the kernel, perhaps, and also too late as a fairly large amount of the effort goes in to copying around strings and allocating space: once it's all been collected, you've expended the energy you hoped to save. > > > > My hope is to put a lot of this code online when I return from the UK in > > > > early August. I haven't made any forward progress in the KTRACE changes > > > > and my code largely relies on the hackish hooks in syscalls to gather > > > > data. > > > > > > These are the 'easy' way to do things, and *may* be the only sane way to > > > do things. However, it requires alot of work for anyone modifying the > > > kernel to keep things straight (this isn't overly bad), but it requires > > > anyone adding a new syscall to add this in, and this 'requirement' may > > > not be followed. It would be nicer if this could somehow be 'automated' > > > like it is in KTRACE currently, but I haven't thought of a good way > > > (yet). > > > > As I pointed out in a prior email, one immediate problem is that namei > > submits the KTRACE entry for pathname arguments that undergo name lookups. > > As a result, my syscall patches end up copying in the argument a second > > time. This is clearly a problem if shared memory is allows between > > contexts, as there are race conditions. Similarly, it's also fairly > > inefficient. It's not clear to me what the best solution is: we could > > either move the copyin out of namei and submit the path via an argument, > > or we could provide an argument to namei that allows it to tag its KTRACE > > submission appropriately. > > I'm beginning to think that using KTRACE is not an acceptable way of > doing things, and that we need to re-instrument the kernel with IDS > auditing on it's own. In other words, your current strategy of > instrumenting individual syscalls is the 'correct' approach, although it > leaves the potential for modifying large portions of the system and the > possibility that as new syscall are added they will not be instrumented > correctly, or at all. > > Unfortunately, I don't see any way around this if we want useful IDS > records. I also don't know how well the FreeBSD kernel guys are going > to take having almost every kernel source file modified in an attempt to > 'slow down' the system to get IDS information. :) My comments on all this are above--I had hoped KTRACE could ease introduction, but I'm concerned it cannot without significant overhead and modification. Robert N M Watson robert@fledge.watson.org http://www.watson.org/~robert/ PGP key fingerprint: AF B5 5F FF A6 4A 79 37 ED 5F 55 E9 58 04 6A B1 TIS Labs at Network Associates, Computing Laboratory at Cambridge University Safeport Network Services To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-security" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.3.96.990709034644.24202B-100000>