Defining an API for audit filter modules

Robert Watson rwatson at FreeBSD.org
Tue Mar 28 15:16:01 UTC 2006


Recently as part of the audit3 work, I added a new facility, audit pipes, to 
the FreeBSD kernel.  Audit pipes are synthetic devices that appear in /dev, 
and allow direct access to the the BSM audit record stream without dealing 
with the complexities of accessing the trail via the file system.  This avoids 
locating the trail files, parsing the files to seek to current events, dealing 
with file ownership and rotation issues, synchronizing with the audit daemon, 
etc.  It also moves us in the direction of avoiding having to commit the 
records to disk at all if live analysis (such as intrusion detection) is the 
goal of the logging, rather than producing a reliable trail for later use. 
Audit pipes, in particular, offer lossy delivery of discete records: the 
application can set the maximum queue depth, and track overflows (drops), etc.

In order to make audit pipes more accessible and immediately useful for 
application developers, I have recently prototyped an audit filter daemon and 
audit filter API.  The goal of this work is to allow developers to produce 
"pluggable modules" to a standard module API, which will be presented audit 
records as they arrive via a live audit pipe (or potentially other source, 
such as a socket).  The daemon provides both the I/O engine and execution 
context for BSM record management: the shared objects simply have to present 
an API to the daemon that it can use to submit records to for examination and 
handling.

Right now, the module API defined in audit_filter.h is quite limited:

typedef int (*audit_filter_attach_t)(void **instance, int argc, char *argv[]);

   Called when a module is attached by the daemon, in order to allow the filter
   to register state (via 'instance'), accept arguments (via 'argc' and
   'argv'), and optionally to reject attachment if the circumstances aren't
   right.

typedef int (*audit_filter_reinit_t)(void *instance, int argc, char *argv[]);

   Called when the auditfilterd configuration file is changed, resulting in the
   arguments for a module changing.  The new arguments are presented via 'argc'
   and 'argv'.  If an error is returned, the module is detached.

typedef void (*audit_filter_record_t)(void *instance, struct timespec *ts,
             int token_count, const tokenstr_t *tok[]);

   Called when an audit record is available for inspection by the module.  The
   record is pre-parsed into an array of token structures using au_fetch_tok().

typedef void (*audit_filter_bsmrecord_t)(void *instance, struct timespec *ts,
             void *data, u_int len);

   Called when an audit record is available for inspection by the module.  The
   record is presented in BSM bytestream, as some modules may wish to perform
   their own BSM handling rather than relying on the parsing performed using
   the libbsm routine.

typedef void (*audit_filter_detach_t)(void *instance);

   Called when the module is being detached, in order to allow the module to
   free any state, close files, etc.

This API will appear in OpenBSM 1.0a6 in the next week or so, once the code 
has stabilized a bit more.  However, the purpose of this e-mail isn't just to 
draw your attention to this new part of OpenBSM, but also to solicit feedback. 
In particular, I'm interested in two sorts of feedback:

(1) Comments on the API components thus far defined.  I do currently provide
     instance state, although a module could currently as easily use its own
     global state.  I did this to allow for the possibility of a module being
     loaded more than once at a time with different arguments, although that is
     currently not supported.  However, maybe there's more that needs to be
     done here.

(2) Comments on future API components.  One of the things I'd like to do is
     add an interest filter mechanism so that modules can push interest into
     the daemon, and eventually the kernel, to control the set of records
     gathered.  An easy obvious direction would be to allow the specification
     based on mechanisms already present via pre-selection: i.e., the request a
     mask of event classes based on audit identity.  You can imagine more
     complicated things, and ideas on how far to take this would be welcome.
     Are there other useful things that are clearly missing for an application
     you may have in mind?

Thanks,

Robert N M Watson


More information about the trustedbsd-audit mailing list