Skip site navigation (1)Skip section navigation (2)
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>