Skip site navigation (1)Skip section navigation (2)
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>