PERFORCE change 167379 for review
Ilias Marinos
marinosi at FreeBSD.org
Sat Aug 15 21:00:49 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=167379
Change 167379 by marinosi at 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)
More information about the p4-projects
mailing list