From owner-freebsd-security Fri Jul 9 9:43:19 1999 Delivered-To: freebsd-security@freebsd.org Received: from fledge.watson.org (fledge.watson.org [204.156.12.50]) by hub.freebsd.org (Postfix) with ESMTP id 6C935155CB for ; Fri, 9 Jul 1999 09:43:11 -0700 (PDT) (envelope-from robert@cyrus.watson.org) Received: from fledge.watson.org (robert@fledge.pr.watson.org [192.0.2.3]) by fledge.watson.org (8.8.8/8.8.8) with SMTP id MAA25970; Fri, 9 Jul 1999 12:42:52 -0400 (EDT) (envelope-from robert@cyrus.watson.org) Date: Fri, 9 Jul 1999 12:42:52 -0400 (EDT) From: Robert Watson X-Sender: robert@fledge.watson.org Reply-To: Robert Watson To: Nate Williams Cc: Darren Reed , Ben Gras , freebsd-security@FreeBSD.ORG Subject: Re: how to keep track of root users? In-Reply-To: <199907091609.KAA06341@mt.sri.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-security@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org On Fri, 9 Jul 1999, Nate Williams wrote: > > #ifdef POSIX_AUD > > /* allocate the record */ > > if (!audrec = k_aud_new_record()) > > return(...appropriate error...) > > Or not. No being able to create an audit record should not cause the > syscall to fail, but that's another discussion in itself. :) Indeed it is--offhand I see two choices: 1) you don't let a syscall succeed unless you can audit it, as otherwise you won't set off your IDS as they can overload the system, or 2) an IDS module recognizes that a congested audit system may be an attack. Blocking for an available record might be a problem if it results in deadlock... > > The problem raised here again, of course, is the copyin of string > > arguments. > > I don't see any way around this, given the audit record needs to exist > as a discrete record that has a lifetime outside of the syscall, so the > information must be copied in. Yes, it does mean that it will have to > be copied in to stored in the kernel, and then copied out, but given > that the time difference between in/out could be long (in terms of > computer time) I can't think of another solution. > > Does anyone else have any ideas? My concern was that it was being copied in twice, as opposed to that it was being copied in. I'm tempted to pull the copyin out of namei and instead pass in a string buffer to namei, stored in kernel space. > > 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). > > Again, I am in total agreement with you. Especially given that we have > already agreed that the type of information gathered is already > syscall specific. Adding exit hooks isn't that much more difficult. I did something like this to add speculative process execution to FreeBSD/i386 a few months ago (that is, generating disk prefetch hints based on speculatively executing a sandboxed process copy), and it proved quite straightforward. However, I believe the architecture-dependent code is what sits directly below the syscall code: we should perhaps insert another architecture-independent layer that wraps the syscall, where things like this can be placed. Similarly, auditing signal delivery would need to happen the same way: currently signal deliver lives in architecture-dependent-land, and we'd want the auditing wrapper to sit somewhere independent of architecture, I suspect. > > 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 > > I don't think this will work, simply because how do we differentiate > between different syscall that will eventually be running in parallel in > the kernel? As Garrett mentions, there will still be a context record from somewhere that could be extended to carry an active audit record for the activities of that context. Presumably that is the place to put it? > > Information like credentials, pid, return code, syscall number would > > automatically be inserted when available by the syscall handler. > > Why not just add it at the entry point to the syscall? We're going to > have to instrument them all anyway, so why not make things consistant by > instrumenting at the syscall entry/exit points? Yes. > > 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[]). > > See above. We can properly deal with the arguments if we have the > context of these arguments, which of course we do at particular syscall > entry point (execve, chmod, link, etc...) But we do have to know what the syscall is, otherwise we don't understand the arguments. I think the argument sniffing should happen inside the current syscall code so that it's obvious to people changing the syscall that they need to update the auditing behavior--otherwise we have inconsistent sources of argument data? (perhaps this could go in syscalls.master and be assembled as part of that?) > > 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. > > I believe there is a trade-off that allows us to somehow 'reduce' > creation of records with a simple filtering scheme that should be much > more effecient than generating records that the benefits are easily > seen. > > However, this is probably not needed for IDS-V1. :) I agree. Currently I have a userland matching mechanism, but it's not very efficient as this is really just an initial exploration. My feeling is that some very simple limiting mechanisms would be quite sufficient to block the majority of the unneeded record generation. For example, per-syscall-number and per-pid, per-uid, etc, plus a per-process enable flag on auditing. This can be caught quite early, and all submissions become no-ops on the record. > > 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. > > See above. However, building a truly generic filtering mechanism would > be 'hard to do', so for now I think we can live with no filtering, or a > very simple filtering scheme. But, will the FreeBSD kernel maintainers > allow this is another story. :( See above: simple stuff in kernel may be the optimum approach, and I suspect a little bit of simple goes a long way. > Nate > > ps. I'm on vacation all next week, so I'll be away from email. Have a great time. 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