Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 9 Jul 1999 10:09:45 -0600
From:      Nate Williams <nate@mt.sri.com>
To:        Robert Watson <robert+freebsd@cyrus.watson.org>
Cc:        Nate Williams <nate@mt.sri.com>, 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:  <199907091609.KAA06341@mt.sri.com>
In-Reply-To: <Pine.BSF.3.96.990709034644.24202B-100000@fledge.watson.org>
References:  <199907081645.KAA29163@mt.sri.com> <Pine.BSF.3.96.990709034644.24202B-100000@fledge.watson.org>

next in thread | previous in thread | raw e-mail | index | archive | help
> > 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.
....
> 
> 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...)

Or not.  No being able to create an audit record should not cause the
syscall to fail, but that's another discussion in itself. :)

> 
> 	k_aud_settype(audrec, AUD_AEV_CHMOD);
> 	k_aud_setcred(audrec, p->p_cred);
> 
> ...
> #endif

Agreed.  This is a *good* thing, and appears to be what Solaris does in
it's BSM module.

> 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?

> 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.

> 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?

> 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?

> 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...)

> > 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.

Agreed.

> 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. :)

> 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. :(

> 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.

See above.

> > 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.

We're in complete agreement here.  KTRACE has insufficient information
to provide adequate IDS information.  Therefore, in order to do this
correctly, it will require instrumenting the kernel.  How that is
accomplished is still up for discussion, and it must be OK'd by the
FreeBSD maintainers, but I hope we can come up with a workable solution
that satisfies all parties.


Nate

ps. I'm on vacation all next week, so I'll be away from email.


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?199907091609.KAA06341>