PERFORCE change 75889 for review
Robert Watson
rwatson at FreeBSD.org
Sun Apr 24 16:17:21 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=75889
Change 75889 by rwatson at rwatson_paprika on 2005/04/24 16:16:45
Fix au_write() to set 'errno' in the event the arguments are invalid.
Check to see if the call to au_write() would cause more data to be
written to the audit record than is available, including checking to
make sure we don't use room reserved for the header and trailer.
Break out the logic in au_close()that flattens out the audit record
tokens into a buffer, as well as the logic to prepend a the audit
header and append the audit trailer. The new function,
au_assemble(), places the contents of the tokens, ready to commit, in
the buffer attached to the record. It does not free the tokens,
which will be done by the caller.
Break out the logic used to free all memory associated with freeing
an audit record, including all tokens, into au_teardown().
Implement au_close() in terms of these calls. Comment on some
failure cases we need to look at carefully and that can maybe now be
eliminated by virtue of space reservations for the header and trailer
by au_write().
Implement au_close_buffer(), which writes the record to a memory
buffer rather than the system audit trail, which is useful for
writing test cases, as well as directly maintaining audit trails in
user space.
Affected files ...
.. //depot/projects/trustedbsd/openbsm/bsm/audit_record.h#4 edit
.. //depot/projects/trustedbsd/openbsm/libbsm/bsm_audit.c#3 edit
Differences ...
==== //depot/projects/trustedbsd/openbsm/bsm/audit_record.h#4 (text+ko) ====
@@ -234,6 +234,8 @@
int au_open(void);
int au_write(int d, token_t *m);
int au_close(int d, int keep, short event);
+int au_close_buffer(int d, short event, u_char *buffer,
+ size_t *buflen);
token_t *au_to_file(char *file);
token_t *au_to_header(int rec_size, au_event_t e_type,
au_emod_t e_mod);
==== //depot/projects/trustedbsd/openbsm/libbsm/bsm_audit.c#3 (text+ko) ====
@@ -1,5 +1,7 @@
/*
- * Copyright (c) 2004, Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2004, Apple Computer, Inc.
+ * Copyright (c) 2005 Robert N. M. Watson
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,12 +30,13 @@
#include <sys/types.h>
#include <sys/queue.h>
+
+#include <errno.h>
+#include <libbsm.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
-#include <libbsm.h>
-
/* array of used descriptors */
static au_record_t* open_desc_table[MAX_AUDIT_RECORDS];
@@ -139,21 +142,31 @@
/*
* Store the token with the record descriptor
+ *
+ * Don't permit writing more to the buffer than would let the trailer be
+ * appended later.
*/
int au_write(int d, token_t *tok)
{
au_record_t *rec;
if(tok == NULL) {
+ errno = EINVAL;
return -1; /* Invalid Token */
}
/* Write the token to the record descriptor */
rec = open_desc_table[d];
if((rec == NULL) || (rec->used == 0)) {
+ errno = EINVAL;
return -1; /* Invalid descriptor */
}
+ if (rec->len + tok->len + TRAILER_SIZE > MAX_AUDIT_RECORD_SIZE) {
+ errno = ENOMEM;
+ return (-1);
+ }
+
/* Add the token to the tail */
/*
* XXX Not locking here -- we should not be writing to
@@ -169,54 +182,55 @@
}
/*
- * Add the header token, identify any missing tokens
- * Write out the tokens to the record memory and finally,
- * call audit
+ * Assemble an audit record out of its tokens, including allocating header
+ * and trailer tokens. Does not free the token chain, which must be done by
+ * the caller if desirable.
+ *
+ * XXX: Assumes there is sufficient space for the header and trailer.
*/
-int au_close(int d, int keep, short event)
+static int
+au_assemble(au_record_t *rec, short event)
{
- au_record_t *rec;
+ token_t *header, *tok, *trailer;
+ size_t tot_rec_size;
u_char *dptr;
- size_t tot_rec_size;
- token_t *tok, *hdr, *trail;
- int retval = 0;
-
- rec = open_desc_table[d];
- if((rec == NULL) || (rec->used == 0)) {
- return -1; /* Invalid descriptor */
- }
-
+ int error;
+
tot_rec_size = rec->len + HEADER_SIZE + TRAILER_SIZE;
- if(keep && (tot_rec_size <= MAX_AUDIT_RECORD_SIZE)) {
- /* Create the header token */
- /* No modifier for libbsm records */
- hdr = au_to_header32(tot_rec_size, event, 0);
-
- if(hdr != NULL) {
- /* Add to head of list */
- TAILQ_INSERT_HEAD(&rec->token_q, hdr, tokens);
+ header = au_to_header32(tot_rec_size, event, 0);
+ if (header == NULL)
+ return (-1);
- trail = au_to_trailer(tot_rec_size);
- if(trail != NULL) {
- /* Add to tail of list */
- TAILQ_INSERT_TAIL(&rec->token_q, trail, tokens);
- }
- }
- /* Serialize token data to the record */
+ trailer = au_to_trailer(tot_rec_size);
+ if (trailer == NULL) {
+ error = errno;
+ au_free_token(header);
+ errno = error;
+ return (-1);
+ }
- rec->len = tot_rec_size;
- dptr = rec->data;
+ TAILQ_INSERT_HEAD(&rec->token_q, header, tokens);
+ TAILQ_INSERT_TAIL(&rec->token_q, trailer, tokens);
- TAILQ_FOREACH(tok, &rec->token_q, tokens) {
- memcpy(dptr, tok->t_data, tok->len);
- dptr += tok->len;
- }
+ rec->len = tot_rec_size;
+ dptr = rec->data;
- /* Call the kernel interface to audit */
- retval = audit(rec->data, rec->len);
+ TAILQ_FOREACH(tok, &rec->token_q, tokens) {
+ memcpy(dptr, tok->t_data, tok->len);
+ dptr += tok->len;
}
- /* CLEANUP */
+ return (0);
+}
+
+/*
+ * Given a record that is no longer of interest, tear it down and convert to
+ * a free record.
+ */
+static void
+au_teardown(au_record_t *rec)
+{
+ token_t *tok;
/* Free the token list */
while ((tok = TAILQ_FIRST(&rec->token_q))) {
@@ -234,7 +248,102 @@
LIST_INSERT_HEAD(&bsm_free_q, rec, au_rec_q);
pthread_mutex_unlock(&mutex);
+}
+/*
+ * Add the header token, identify any missing tokens
+ * Write out the tokens to the record memory and finally,
+ * call audit
+ */
+int au_close(int d, int keep, short event)
+{
+ au_record_t *rec;
+ u_char *dptr;
+ size_t tot_rec_size;
+ int retval = 0;
+
+ rec = open_desc_table[d];
+ if((rec == NULL) || (rec->used == 0)) {
+ return -1; /* Invalid descriptor */
+ }
+
+ if (!keep) {
+ retval = 0;
+ goto cleanup;
+ }
+
+
+ tot_rec_size = rec->len + HEADER_SIZE + TRAILER_SIZE;
+
+ if (tot_rec_size > MAX_AUDIT_RECORD_SIZE) {
+ /*
+ * XXXRW: Since au_write() is supposed to prevent this, spew
+ * an error here.
+ */
+ fprintf(stderr, "au_close failed");
+ errno = ENOMEM;
+ retval = -1;
+ goto cleanup;
+ }
+
+ if (au_assemble(rec, event) < 0) {
+ /*
+ * XXXRW: This is also not supposed to happen, but might if
+ * we are unable to allocate header and trailer memory.
+ */
+ retval = -1;
+ goto cleanup;
+ }
+
+ /* Call the kernel interface to audit */
+ retval = audit(rec->data, rec->len);
+
+cleanup:
+ /* CLEANUP */
+ au_teardown(rec);
return retval;
}
-
+
+/*
+ * au_close(), except onto an in-memory buffer. Buffer size as an argument,
+ * record size returned via same argument on success.
+ */
+int
+au_close_buffer(int d, short event, u_char *buffer, size_t *buflen)
+{
+ size_t tot_rec_size;
+ au_record_t *rec;
+ int retval;
+
+ rec = open_desc_table[d];
+ if ((rec == NULL) || (rec->used == 0)) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ tot_rec_size = rec->len + HEADER_SIZE + TRAILER_SIZE;
+ if ((tot_rec_size > MAX_AUDIT_RECORD_SIZE) ||
+ (tot_rec_size > *buflen)) {
+ /*
+ * XXXRW: See au_close() comment.
+ */
+ fprintf(stderr, "au_close_buffer failed %d", tot_rec_size);
+ errno = ENOMEM;
+ retval = -1;
+ goto cleanup;
+ }
+
+ if (au_assemble(rec, event) < 0) {
+ /*
+ * XXXRW: See au_close() comment.
+ */
+ retval = -1;
+ goto cleanup;
+ }
+
+ memcpy(buffer, rec->data, rec->len);
+ *buflen = rec->len;
+cleanup:
+ au_teardown(rec);
+ return (retval);
+}
To Unsubscribe: send mail to majordomo at trustedbsd.org
with "unsubscribe trustedbsd-cvs" in the body of the message
More information about the trustedbsd-cvs
mailing list