Date: Tue, 7 Jul 2009 20:15:42 GMT From: Ilias Marinos <marinosi@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 165785 for review Message-ID: <200907072015.n67KFg8D003143@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=165785 Change 165785 by marinosi@marinosi_redrum on 2009/07/07 20:15:18 BSM record fetching from devices implemented.Needs test. Affected files ... .. //depot/projects/soc2009/marinosi_appaudit/src/sys/bsm/audit_internal.h#3 edit .. //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit.c#8 edit .. //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_private.h#5 edit .. //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_slice.c#4 edit .. //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_slice.h#6 edit Differences ... ==== //depot/projects/soc2009/marinosi_appaudit/src/sys/bsm/audit_internal.h#3 (text) ==== @@ -129,7 +129,7 @@ * seconds of time 4 bytes/8 bytes (32-bit/64-bit value) * milliseconds of time 4 bytes/8 bytes (32-bit/64-bit value) */ -struct bsm_record_header { +struct bsm_rec_hdr { u_char token_id; u_int32_t rec_byte_count; u_char version; @@ -143,7 +143,7 @@ * trailer magic number 2 bytes * record byte count 4 bytes */ -struct bsm_record_trailer { +truct bsm_rec_tlr { u_char token_id; u_int16_t trailer_num; u_int32_t rec_byte_count; ==== //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit.c#8 (text) ==== @@ -277,15 +277,18 @@ * pre_q space, suspending the system call until there is room? */ struct kaudit_record * -audit_new(int event, struct thread *td) +audit_new(int event, struct thread *td, struct audit_slice *as) { struct kaudit_record *ar; int no_record; - mtx_lock(&(audit_base_slice->audit_mtx)); - no_record = (&(audit_base_slice->audit_suspended) || - !(audit_base_slice->audit_enabled)); - mtx_unlock(&(audit_base_slice->audit_mtx)); + if (as == NULL) + return (NULL); + + mtx_lock(&(as->audit_mtx)); + no_record = (&(as->audit_suspended) || + !(as->audit_enabled)); + mtx_unlock(&(as->audit_mtx)); if (no_record) return (NULL); @@ -297,9 +300,9 @@ ar = uma_zalloc_arg(audit_record_zone, td, M_WAITOK); ar->k_ar.ar_event = event; - mtx_lock(&(audit_base_slice->audit_mtx)); - audit_base_slice->audit_pre_q_len++; - mtx_unlock(&(audit_base_slice->audit_mtx)); + mtx_lock(&(as->audit_mtx)); + as->audit_pre_q_len++; + mtx_unlock(&(as->audit_mtx)); return (ar); } @@ -478,11 +481,11 @@ &(audit_base_slice->audit_mtx)); panic("audit_failing_stop: thread continued"); } - td->td_ar = audit_new(event, td); + td->td_ar = audit_new(event, td, audit_base_slice); if (td->td_ar != NULL) td->td_pflags |= TDP_AUDITREC; } else if (audit_pipe_preselect(auid, event, class, AU_PRS_BOTH, 0)) { - td->td_ar = audit_new(event, td); + td->td_ar = audit_new(event, td, audit_base_slice); if (td->td_ar != NULL) td->td_pflags |= TDP_AUDITREC; } else @@ -612,7 +615,7 @@ * Where possible coredump records should contain a pathname and arg32 * (signal) tokens. */ - ar = audit_new(AUE_CORE, td); + ar = audit_new(AUE_CORE, td, audit_base_slice); if (path != NULL) { pathp = &ar->k_ar.ar_arg_upath1; *pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK); @@ -719,3 +722,67 @@ free(as, M_AUDITSLICE); } } + +/* + * audit_slice_commit_rec() is used to commit a BSM record that was fetched + * from a special device node, to the appropriate slice-owner. + */ +void +audit_slice_commit_rec(void *rec, struct audit_slice *as) +{ + struct kaudit_record *ar; + struct thread *td; + + + + /* struct thread uninitialized! */ + if (ar == NULL) { + + /* + * This is not very efficient; we're required to allocate a + * complete kernel audit record just so the user record can + * tag along. + * + * XXXAUDIT: Maybe AUE_AUDIT in the system call context and + * special pre-select handling? + */ + td->td_ar = audit_new(AUE_NULL, td); + if (td->td_ar == NULL) + return (ENOTSUP); + td->td_pflags |= TDP_AUDITREC; + ar = td->td_ar; + } + + /* Verify the record. */ + if (bsm_rec_verify(rec) == 0) + error = EINVAL; + + + /* + * Note: it could be that some records initiated while audit was + * enabled should still be committed? + */ + mtx_lock(&(as->audit_mtx)); + if (as->audit_suspended + || !as->audit_enabled) { + as->audit_pre_q_len--; + mtx_unlock(&(as->audit_mtx)); + audit_free(ar); + return; + } + + /* + * Constrain the number of committed audit records based on the + * configurable parameter. + */ + while (as->audit_q_len >= + as->audit_qctrl.aq_hiwater) + cv_wait(&(as->audit_watermark_cv), + &(as->audit_mtx)); + + TAILQ_INSERT_TAIL(&(as->audit_q), ar, k_q); + as->audit_q_len++; + as->audit_pre_q_len--; + cv_signal(&(as->audit_worker_cv)); + mtx_unlock(&(as->audit_mtx)); +} ==== //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_private.h#5 (text) ==== @@ -303,7 +303,6 @@ void audit_abort(struct kaudit_record *ar); void audit_commit(struct kaudit_record *ar, int error, int retval); -struct kaudit_record *audit_new(int event, struct thread *td); /* * Functions relating to the conversion of internal kernel audit records to ==== //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_slice.c#4 (text+ko) ==== @@ -156,23 +156,49 @@ /* Actual work here */ int c, error = 0; - void *audit_slice_dev_buf; + u_int32_t recsz = 0; + int nbytes = 0; /*Remaining bytes */ + void *audit_slice_dev_buf, *as_rec; struct audit_slice *as; as = dev->si_drv1; /* Safe malloc the pagesz of the system.*/ - audit_slice_dev_buf = (void *)malloc(PAGE_SIZE, M_TEMP, M_WAITOK); + audit_slice_dev_buf = (void *)malloc(sizeof(struct bsm_rec_hdr), + M_TEMP, M_WAITOK); while (uio->uio_resid > 0) { - c = MIN((int)uio->uio_resid, PAGE_SIZE); + c = MIN((int)uio->uio_resid, sizeof(struct bsm_rec_hdr)); + if ( c == (int)uio->uio_resid ) + break; + + /* Fetch the bsm record's header */ error = uiomove(audit_slice_dev_buf, c, uio); if (error) break; - //(*random_systat.write)(random_buf, c); + + /* + * Store the actual record's size. Add some checks before + * this. + */ + recsz = be32dec (audit_slice_dev_buf->rec_byte_count); + as_rec = (void *)malloc((unsigned long)recsz, M_AUDITBSM, + M_WAITOK | M_ZERO); + + /* Copy the header at the start of record */ + memmove(as_rec, audit_slice_dev_buf, + sizeof(audit_slice_dev_buf)); + + nbytes = (int)recsz - sizeof(audit_slice_dev_buf); + error = uiomove(as_rec, nbytes, uio); + if (error) + break; + + audit_slice_commit_rec( as_rec, as); } free(audit_slice_dev_buf, M_TEMP); + free(as_rec, M_AUDITBSM); return (error); } ==== //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_slice.h#6 (text+ko) ==== @@ -177,6 +177,13 @@ /* + * Functions to manage the allocation, release, and commit of kernel audit + * records and require audit_slice struct as arguments. + */ +struct kaudit_record *audit_new(int event, struct thread *td, + struct audit_slice *as); + +/* * Audit related functions prototypes */ void audit_rotate_vnode(struct ucred *cred,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200907072015.n67KFg8D003143>