Date: Sat, 15 Aug 2009 21:00:48 GMT From: Ilias Marinos <marinosi@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 167379 for review Message-ID: <200908152100.n7FL0mSl031105@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=167379 Change 167379 by marinosi@marinosi_redrum on 2009/08/15 21:00:30 - Implemented auditctl_slice_internal() function which is used from auditctl() and auditctl_slice() system calls. - Implemented the necessary code for auditctl_slice() syscall. - Improved audit_slice_commit_rec().( added a new arg, handling the records etc). - Added some debugging code. With this commit the audit slices system is functional! Records are successfully submitted to the devices, processed from the appropriate workers and committed to the filesystem! Affected files ... .. //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit.c#25 edit .. //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_slice.c#11 edit .. //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_slice.h#17 edit .. //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_syscalls.c#13 edit .. //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_worker.c#11 edit Differences ... ==== //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit.c#25 (text) ==== @@ -70,6 +70,7 @@ #include <security/audit/audit.h> #include <security/audit/audit_private.h> +#include <security/mac/mac_framework.h> #include <security/audit/audit_slice.h> @@ -759,7 +760,7 @@ * XXX: As M_ZERO flag is used during allocation, some of the * following initilization is pointless and should be removed. */ - as->audit_enabled = 1; + as->audit_enabled = 0; as->audit_suspended = 0; as->audit_panic_on_write_fail = 0; as->audit_fail_stop = 0; @@ -804,6 +805,7 @@ */ if ( as != audit_base_slice ) { as->audit_enabled = 1; + as->perms = 0700; mtx_init(&(as->as_dev_mtx), "as_dev_mtx", NULL, MTX_DEF); } @@ -864,9 +866,10 @@ * code. */ int -audit_slice_commit_rec(struct thread *td, void *rec, struct audit_slice *as) +audit_slice_commit_rec(struct thread *td, void *rec, u_int len, struct audit_slice *as) { struct kaudit_record *ar = NULL; + void *bsm = NULL; int error; /* @@ -887,6 +890,13 @@ } /* + * Allocate the appropriate memory for the record and fetch it. + * The record will be free'd by audit_record_dtor(). + */ + bsm = (void *) malloc(len, M_TEMP, M_WAITOK | M_ZERO); + memmove(bsm, rec, len); + + /* * XXXRW: Audit slices other than the base should probably never * touch td->td_ar, so the below should unconditionally allocate the * container record. @@ -922,6 +932,12 @@ ar->k_ar_commit |= AR_PRESELECT_USER_TRAIL; /* + * Update the pointer to the actual record and set the length. + */ + ar->k_udata = bsm; + ar->k_ulen = len; + + /* * Note: it could be that some records initiated while audit was * enabled should still be committed? */ @@ -1455,3 +1471,77 @@ return (0); } + +/* + * auditon_slice_internal() performs the actual work for auditon_slice(2) and + * auditon(2) system calls. + */ +int +auditctl_slice_internal(struct thread *td, char *as_name, char *path) +{ + + struct nameidata nd; + struct ucred *cred = NULL; + struct vnode *vp = NULL; + struct audit_slice *as = NULL; + int error = 0; + int flags, vfslocked; + + /* + * Find the slice we should operate on. + */ + as = audit_slice_lookup(as_name); + if (as == NULL) + return (EINVAL); + /* + * If a path is specified, open the replacement vnode, perform + * validity checks, and grab another reference to the current + * credential. + * + * On Darwin, a NULL path argument is also used to disable audit. + */ + if (path == NULL) + return (EINVAL); + + NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, + UIO_USERSPACE, path, td); + flags = AUDIT_OPEN_FLAGS; + error = vn_open(&nd, &flags, 0, NULL); + if (error) + return (error); + vfslocked = NDHASGIANT(&nd); + vp = nd.ni_vp; +#ifdef MAC + error = mac_system_check_auditctl(td->td_ucred, vp); + VOP_UNLOCK(vp, 0); + if (error) { + vn_close(vp, AUDIT_CLOSE_FLAGS, td->td_ucred, td); + VFS_UNLOCK_GIANT(vfslocked); + return (error); + } +#else + VOP_UNLOCK(vp, 0); +#endif + NDFREE(&nd, NDF_ONLY_PNBUF); + if (vp->v_type != VREG) { + vn_close(vp, AUDIT_CLOSE_FLAGS, td->td_ucred, td); + VFS_UNLOCK_GIANT(vfslocked); + return (EINVAL); + } + VFS_UNLOCK_GIANT(vfslocked); + cred = td->td_ucred; + crhold(cred); + + /* + * XXXAUDIT: Should audit_suspended actually be cleared by + * audit_worker? + */ + as->audit_suspended = 0; + /* What is the need of this? */ + if ( as == audit_base_slice ) + audit_suspended = as->audit_suspended; + + audit_rotate_vnode(as, cred, vp); + + return (error); +} ==== //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_slice.c#11 (text+ko) ==== @@ -236,7 +236,7 @@ // if (error) // break; - audit_slice_commit_rec( uio->uio_td, audit_slice_dev_buf, as); + audit_slice_commit_rec( uio->uio_td, audit_slice_dev_buf, c, as); // uprintf("Size to be fetched: %d\n", uio->uio_resid); // c = MIN((int)uio->uio_resid, PAGE_SIZE); @@ -294,9 +294,6 @@ audit_slice_cdev_init(struct audit_slice *as) { - - as->perms = 0700; - /* Create the special device file. */ as->as_dev = make_dev(&audit_slice_cdevsw, as->unit, as->uid, as->gid, as->perms, "auditslice/%s", as->as_name); ==== //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_slice.h#17 (text+ko) ==== @@ -193,10 +193,10 @@ void audit_slice_create(char *name); int audit_slice_destroy(struct audit_slice *as); void audit_slice_cdev_init(struct audit_slice *as); -int audit_slice_commit_rec(struct thread *td, void *rec, +int audit_slice_commit_rec(struct thread *td, void *rec, u_int len, struct audit_slice *as); struct audit_slice *audit_slice_lookup(char *as_name); int auditon_slice_internal(struct thread *td, int cmd, char *as_name, void *data, u_int length); - +int auditctl_slice_internal(struct thread *td, char *as_name, char *path); #endif /* ! _SECURITY_AUDIT_SLICE_H_ */ ==== //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_syscalls.c#13 (text) ==== @@ -427,11 +427,9 @@ int auditctl(struct thread *td, struct auditctl_args *uap) { - struct nameidata nd; - struct ucred *cred; - struct vnode *vp; + int error = 0; - int flags, vfslocked; + int ret; if (jailed(td->td_ucred)) return (ENOSYS); @@ -439,58 +437,12 @@ if (error) return (error); - vp = NULL; - cred = NULL; - /* - * If a path is specified, open the replacement vnode, perform - * validity checks, and grab another reference to the current - * credential. - * - * On Darwin, a NULL path argument is also used to disable audit. + * Call audit_slice_internal() to manage tha audit file.auditctl() + * always selects the base slice to operate on. */ - if (uap->path == NULL) - return (EINVAL); - - NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, - UIO_USERSPACE, uap->path, td); - flags = AUDIT_OPEN_FLAGS; - error = vn_open(&nd, &flags, 0, NULL); - if (error) - return (error); - vfslocked = NDHASGIANT(&nd); - vp = nd.ni_vp; -#ifdef MAC - error = mac_system_check_auditctl(td->td_ucred, vp); - VOP_UNLOCK(vp, 0); - if (error) { - vn_close(vp, AUDIT_CLOSE_FLAGS, td->td_ucred, td); - VFS_UNLOCK_GIANT(vfslocked); - return (error); - } -#else - VOP_UNLOCK(vp, 0); -#endif - NDFREE(&nd, NDF_ONLY_PNBUF); - if (vp->v_type != VREG) { - vn_close(vp, AUDIT_CLOSE_FLAGS, td->td_ucred, td); - VFS_UNLOCK_GIANT(vfslocked); - return (EINVAL); - } - VFS_UNLOCK_GIANT(vfslocked); - cred = td->td_ucred; - crhold(cred); - - /* - * XXXAUDIT: Should audit_suspended actually be cleared by - * audit_worker? - */ - audit_base_slice->audit_suspended = 0; - audit_suspended = audit_base_slice->audit_suspended; - - audit_rotate_vnode(audit_base_slice, cred, vp); - - return (error); + ret = auditctl_slice_internal(td, "audit_base_slice", uap->path); + return(ret); } /* @@ -501,7 +453,35 @@ auditctl_slice(struct thread *td, struct auditctl_slice_args *uap) { - return (ENOSYS); + int error = 0; + int ret, nbytes; + char as_name[AUDIT_SLICE_NAME_LEN]; + + if (jailed(td->td_ucred)) + return (ENOSYS); + error = priv_check(td, PRIV_AUDIT_CONTROL); + if (error) + return (error); + + /* + * Check slice name. + */ + nbytes = strlen(uap->as_name); + if ( nbytes <= 0 || nbytes > AUDIT_SLICE_NAME_LEN ) + return (EINVAL); + + /* + * Copyin the name of the slice we need to operate on. + */ + error = copyinstr(uap->as_name, as_name, AUDIT_SLICE_NAME_LEN, NULL); + if (error) + return (EINVAL); + + /* + * Call audit_slice_internal() to manage tha audit file. + */ + ret = auditctl_slice_internal(td, as_name, uap->path); + return(ret); } #else /* !AUDIT */ ==== //depot/projects/soc2009/marinosi_appaudit/src/sys/security/audit/audit_worker.c#11 (text) ==== @@ -113,6 +113,8 @@ if (as->audit_vp == NULL) return; + printf("audit_record_write(): as->audit_vp not NULL!\n"); + mnt_stat = &as->audit_vp->v_mount->mnt_stat; vfslocked = VFS_LOCK_GIANT(as->audit_vp->v_mount); @@ -223,6 +225,7 @@ } } + printf("Ready to call vn_rdwr!\n"); error = vn_rdwr(UIO_WRITE, as->audit_vp, data, len, (off_t)0, UIO_SYSSPACE, IO_APPEND|IO_UNIT, as->audit_cred, NULL, NULL, curthread); if (error == ENOSPC)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200908152100.n7FL0mSl031105>