From owner-p4-projects@FreeBSD.ORG Tue Jul 7 20:15:43 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 1AEB91065673; Tue, 7 Jul 2009 20:15:43 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CF64C1065670 for ; Tue, 7 Jul 2009 20:15:42 +0000 (UTC) (envelope-from marinosi@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id BCE918FC1A for ; Tue, 7 Jul 2009 20:15:42 +0000 (UTC) (envelope-from marinosi@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n67KFgY0003146 for ; Tue, 7 Jul 2009 20:15:42 GMT (envelope-from marinosi@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n67KFg8D003143 for perforce@freebsd.org; Tue, 7 Jul 2009 20:15:42 GMT (envelope-from marinosi@FreeBSD.org) Date: Tue, 7 Jul 2009 20:15:42 GMT Message-Id: <200907072015.n67KFg8D003143@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to marinosi@FreeBSD.org using -f From: Ilias Marinos To: Perforce Change Reviews Cc: Subject: PERFORCE change 165785 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 07 Jul 2009 20:15:44 -0000 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,