From owner-p4-projects@FreeBSD.ORG Sun Mar 19 20:22:23 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 3BD6116A423; Sun, 19 Mar 2006 20:22:23 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 17CAE16A420 for ; Sun, 19 Mar 2006 20:22:23 +0000 (UTC) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id CB6D243D45 for ; Sun, 19 Mar 2006 20:22:22 +0000 (GMT) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id k2JKMMYI023304 for ; Sun, 19 Mar 2006 20:22:22 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id k2JKMMg1023301 for perforce@freebsd.org; Sun, 19 Mar 2006 20:22:22 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Date: Sun, 19 Mar 2006 20:22:22 GMT Message-Id: <200603192022.k2JKMMg1023301@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to bb+lists.freebsd.perforce@cyrus.watson.org using -f From: Robert Watson To: Perforce Change Reviews Cc: Subject: PERFORCE change 93595 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: Sun, 19 Mar 2006 20:22:23 -0000 http://perforce.freebsd.org/chv.cgi?CH=93595 Change 93595 by rwatson@rwatson_peppercorn on 2006/03/19 20:22:12 Pull BSM conversion logic out of audit_record_write(), as well as knowledge of user vs. kernel audit records into audit_worker_process_record(). This largely confines vnode knowledge to audit_record_write(), but avoids that logic knowing about BSM as opposed to byte streams. This will allow us to improve our ability to support real-time audit stream processing by audit pipe consumers while auditing is disabled, but this support is not yet complete. Affected files ... .. //depot/projects/trustedbsd/audit3/sys/security/audit/audit_worker.c#7 edit Differences ... ==== //depot/projects/trustedbsd/audit3/sys/security/audit/audit_worker.c#7 (text+ko) ==== @@ -109,16 +109,18 @@ * we accounted for. */ static int -audit_record_write(struct vnode *vp, struct kaudit_record *ar, - struct ucred *cred, struct thread *td) +audit_record_write(struct vnode *vp, struct ucred *cred, struct thread *td, + void *data, size_t len) { int ret; long temp; - struct au_record *bsm; struct vattr vattr; struct statfs *mnt_stat = &vp->v_mount->mnt_stat; int vfslocked; + if (vp == NULL) + return (0); + vfslocked = VFS_LOCK_GIANT(vp->v_mount); /* @@ -214,75 +216,9 @@ audit_in_failure = 1; } - /* - * If there is a user audit record attached to the kernel record, - * then write the user record. - * - * XXX Need to decide a few things here: IF the user audit record is - * written, but the write of the kernel record fails, what to do? - * Should the kernel record come before or after the user record? - * For now, we write the user record first, and we ignore errors. - */ - if (ar->k_ar_commit & AR_COMMIT_USER) { - /* - * Try submitting the record to any active audit pipes. - */ - audit_pipe_submit((void *)ar->k_udata, ar->k_ulen); - - /* - * And to disk. - */ - ret = vn_rdwr(UIO_WRITE, vp, (void *)ar->k_udata, ar->k_ulen, - (off_t)0, UIO_SYSSPACE, IO_APPEND|IO_UNIT, cred, NULL, - NULL, td); - if (ret) - goto out; - } - - /* - * Convert the internal kernel record to BSM format and write it out - * if everything's OK. - */ - if (!(ar->k_ar_commit & AR_COMMIT_KERNEL)) { - ret = 0; - goto out; - } - - /* - * XXXAUDIT: Should we actually allow this conversion to fail? With - * sleeping memory allocation and invariants checks, perhaps not. - */ - ret = kaudit_to_bsm(ar, &bsm); - if (ret == BSM_NOAUDIT) { - ret = 0; - goto out; - } - - /* - * XXX: We drop the record on BSM conversion failure, but really this - * is an assertion failure. - */ - if (ret == BSM_FAILURE) { - AUDIT_PRINTF(("BSM conversion failure\n")); - ret = EINVAL; - goto out; - } - - /* - * Try submitting the record to any active audit pipes. - */ - audit_pipe_submit((void *)bsm->data, bsm->len); + ret = vn_rdwr(UIO_WRITE, vp, data, len, (off_t)0, UIO_SYSSPACE, + IO_APPEND|IO_UNIT, cred, NULL, NULL, td); - /* - * XXX We should break the write functionality away from the BSM - * record generation and have the BSM generation done before this - * function is called. This function will then take the BSM record as - * a parameter. - */ - ret = (vn_rdwr(UIO_WRITE, vp, (void *)bsm->data, bsm->len, (off_t)0, - UIO_SYSSPACE, IO_APPEND|IO_UNIT, cred, NULL, NULL, td)); - kau_free(bsm); - out: /* * When we're done processing the current record, we have to check to @@ -386,27 +322,55 @@ } /* - * Given a kernel audit record, process as required. Currently, that means - * passing it to audit_record_write(), but in the future it will mean - * converting it to BSM and then routing it to various possible output - * streams, including the audit trail and audit pipes. The caller will free - * the record. + * Given a kernel audit record, process as required. Kernel audit records + * are converted to one, or possibly two, BSM records, depending on whether + * there is a user audit record present also. Kernel records need be + * converted to BSM before they can be written out. Both types will be + * written to disk, and audit pipes. */ static void audit_worker_process_record(struct vnode *audit_vp, struct ucred *audit_cred, struct thread *audit_td, struct kaudit_record *ar) { - int error; + struct au_record *bsm; + int error, ret; - if (audit_vp == NULL) - return; - - error = audit_record_write(audit_vp, ar, audit_cred, audit_td); - if (error) { - if (audit_panic_on_write_fail) + if (ar->k_ar_commit & AR_COMMIT_USER) { + error = audit_record_write(audit_vp, audit_cred, audit_td, + ar->k_udata, ar->k_ulen); + if (error && audit_panic_on_write_fail) panic("audit_worker: write error %d\n", error); - else + else if (error) printf("audit_worker: write error %d\n", error); + audit_pipe_submit(ar->k_udata, ar->k_ulen); + } + + if (ar->k_ar_commit & AR_COMMIT_KERNEL) { + ret = kaudit_to_bsm(ar, &bsm); + switch (ret) { + case BSM_NOAUDIT: + break; + + case BSM_FAILURE: + printf("audit_worker_process_record: BSM_FAILURE\n"); + break; + + case BSM_SUCCESS: + error = audit_record_write(audit_vp, audit_cred, + audit_td, bsm->data, bsm->len); + if (error && audit_panic_on_write_fail) + panic("audit_worker: write error %d\n", + error); + else if (error) + printf("audit_worker: write error %d\n", + error); + audit_pipe_submit(bsm->data, bsm->len); + kau_free(bsm); + break; + + default: + panic("kaudit_to_bsm returned %d", ret); + } } }