Date: Sun, 19 Mar 2006 20:22:22 GMT From: Robert Watson <rwatson@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 93595 for review Message-ID: <200603192022.k2JKMMg1023301@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
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); + } } }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200603192022.k2JKMMg1023301>