PERFORCE change 101305 for review

Wayne Salamon wsalamon at FreeBSD.org
Tue Jul 11 22:10:56 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=101305

Change 101305 by wsalamon at vh3 on 2006/07/11 22:10:38

	Audit the argv and env vectors passed in on exec:
	Add the argument auditing functions for argv and env.
	Add kernel-specific versions of the tokenizer functions for the
	arg and env represented as a char array.
	Integrate the changes from OpenBSM for the tokenizer function
	prototypes (and pick up an earlier change for free).
	Implement the AUDIT_ARGV and AUDIT_ARGE audit policy commands to
	enable/disable argv/env auditing.
	Call the argument auditing from the exec system calls.

Affected files ...

.. //depot/projects/trustedbsd/audit3/sys/bsm/audit_record.h#17 integrate
.. //depot/projects/trustedbsd/audit3/sys/kern/kern_exec.c#11 edit
.. //depot/projects/trustedbsd/audit3/sys/security/audit/audit.c#34 edit
.. //depot/projects/trustedbsd/audit3/sys/security/audit/audit.h#18 edit
.. //depot/projects/trustedbsd/audit3/sys/security/audit/audit_arg.c#20 edit
.. //depot/projects/trustedbsd/audit3/sys/security/audit/audit_bsm.c#18 edit
.. //depot/projects/trustedbsd/audit3/sys/security/audit/audit_bsm_token.c#21 edit
.. //depot/projects/trustedbsd/audit3/sys/security/audit/audit_private.h#30 edit
.. //depot/projects/trustedbsd/audit3/sys/security/audit/audit_syscalls.c#18 edit

Differences ...

==== //depot/projects/trustedbsd/audit3/sys/bsm/audit_record.h#17 (text+ko) ====

@@ -30,7 +30,7 @@
  *
  * @APPLE_BSD_LICENSE_HEADER_END@
  *
- * $P4: //depot/projects/trustedbsd/audit3/sys/bsm/audit_record.h#16 $
+ * $P4: //depot/projects/trustedbsd/audit3/sys/bsm/audit_record.h#17 $
  * $FreeBSD: src/sys/bsm/audit_record.h,v 1.3 2006/07/03 14:44:13 rwatson Exp $
  */
 
@@ -185,7 +185,7 @@
 #define AUR_CHAR        AUR_BYTE
 #define AUR_SHORT       1
 #define AUR_INT32       2
-#define AUR_INT         AUR_INT
+#define AUR_INT         AUR_INT32
 #define AUR_INT64       3
 
 /* ... and their sizes */
@@ -309,8 +309,13 @@
 	    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid);
 token_t	*au_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
 	    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid);
-token_t	*au_to_exec_args(const char **);
-token_t	*au_to_exec_env(const char **);
+#if defined(_KERNEL) || defined(KERNEL)
+token_t	*au_to_exec_args(char *args, int argc);
+token_t	*au_to_exec_env(char *envs, int envc);
+#else
+token_t	*au_to_exec_args(char **argv);
+token_t	*au_to_exec_env(char **envp);
+#endif
 token_t	*au_to_text(char *text);
 token_t	*au_to_kevent(struct kevent *kev);
 token_t	*au_to_trailer(int rec_size);

==== //depot/projects/trustedbsd/audit3/sys/kern/kern_exec.c#11 (text+ko) ====

@@ -79,6 +79,8 @@
 
 #include <machine/reg.h>
 
+#include <security/audit/audit.h>
+
 MALLOC_DEFINE(M_PARGS, "proc-args", "Process arguments");
 
 static int sysctl_kern_ps_strings(SYSCTL_HANDLER_ARGS);
@@ -239,6 +241,10 @@
 	struct proc *p = td->td_proc;
 	int error;
 
+	AUDIT_ARG(argv, args->begin_argv, args->argc,
+	    args->begin_envv - args->begin_argv);
+	AUDIT_ARG(envv, args->begin_envv, args->envc,
+	    args->endp - args->begin_envv);
 	if (p->p_flag & P_HADTHREADS) {
 		PROC_LOCK(p);
 		if (thread_single(SINGLE_BOUNDARY)) {

==== //depot/projects/trustedbsd/audit3/sys/security/audit/audit.c#34 (text+ko) ====

@@ -92,6 +92,8 @@
  */
 int			audit_panic_on_write_fail;
 int			audit_fail_stop;
+int			audit_argv;
+int			audit_arge;
 
 /*
  * Are we currently "failing stop" due to out of disk space?
@@ -206,6 +208,10 @@
 		free(ar->k_ar.ar_arg_iovecstr, M_AUDITTEXT);
 	if (ar->k_udata != NULL)
 		free(ar->k_udata, M_AUDITDATA);
+	if (ar->k_ar.ar_arg_argv != NULL)
+		free(ar->k_ar.ar_arg_argv, M_AUDITTEXT);
+	if (ar->k_ar.ar_arg_envv != NULL)
+		free(ar->k_ar.ar_arg_envv, M_AUDITTEXT);
 }
 
 /*
@@ -223,6 +229,8 @@
 	audit_panic_on_write_fail = 0;
 	audit_fail_stop = 0;
 	audit_in_failure = 0;
+	audit_argv = 0;
+	audit_arge = 0;
 
 	audit_fstat.af_filesz = 0;	/* '0' means unset, unbounded */
 	audit_fstat.af_currsz = 0;

==== //depot/projects/trustedbsd/audit3/sys/security/audit/audit.h#18 (text+ko) ====

@@ -113,6 +113,8 @@
 #define ARG_MACHPORT2		0x0000200000000000ULL
 #define	ARG_EXIT		0x0000400000000000ULL
 #define	ARG_IOVECSTR		0x0000800000000000ULL
+#define	ARG_ARGV		0x0001000000000000ULL
+#define	ARG_ENVV		0x0002000000000000ULL
 #define ARG_NONE		0x0000000000000000ULL
 #define ARG_ALL			0xFFFFFFFFFFFFFFFFULL
 
@@ -168,6 +170,8 @@
 void	 audit_arg_posix_ipc_perm(uid_t uid, gid_t gid, mode_t mode);
 void	 audit_arg_auditon(union auditon_udata *udata);
 void	 audit_arg_file(struct proc *p, struct file *fp);
+void	 audit_arg_argv(char *argv, int argc, int length);
+void	 audit_arg_envv(char *envv, int envc, int length);
 void	 audit_sysclose(struct thread *td, int fd);
 void	 audit_proc_alloc(struct proc *p);
 void	 audit_proc_kproc0(struct proc *p);

==== //depot/projects/trustedbsd/audit3/sys/security/audit/audit_arg.c#20 (text+ko) ====

@@ -800,6 +800,48 @@
 }
 
 /*
+ * Audit the argument strings passed to exec.
+ */
+void
+audit_arg_argv(char *argv, int argc, int length)
+{
+	struct kaudit_record *ar;
+
+	if (audit_argv == 0)
+		return;
+
+	ar = currecord();
+	if (ar == NULL)
+		return;
+
+	ar->k_ar.ar_arg_argv = malloc(length, M_AUDITTEXT, M_WAITOK);
+	bcopy(argv, ar->k_ar.ar_arg_argv, length);
+	ar->k_ar.ar_arg_argc = argc;
+	ARG_SET_VALID(ar, ARG_ARGV);
+}
+
+/*
+ * Audit the environment strings passed to exec.
+ */
+void
+audit_arg_envv(char *envv, int envc, int length)
+{
+	struct kaudit_record *ar;
+
+	if (audit_arge == 0)
+		return;
+
+	ar = currecord();
+	if (ar == NULL)
+		return;
+
+	ar->k_ar.ar_arg_envv = malloc(length, M_AUDITTEXT, M_WAITOK);
+	bcopy(envv, ar->k_ar.ar_arg_envv, length);
+	ar->k_ar.ar_arg_envc = envc;
+	ARG_SET_VALID(ar, ARG_ENVV);
+}
+
+/*
  * The close() system call uses it's own audit call to capture the path/vnode
  * information because those pieces are not easily obtained within the system
  * call itself.

==== //depot/projects/trustedbsd/audit3/sys/security/audit/audit_bsm.c#18 (text+ko) ====

@@ -585,7 +585,6 @@
 	case AUE_CHDIR:
 	case AUE_CHROOT:
 	case AUE_EACCESS:
-	case AUE_EXECVE:
 	case AUE_GETATTRLIST:
 	case AUE_NFS_GETFH:
 	case AUE_LSTAT:
@@ -684,6 +683,20 @@
 		EXTATTR_TOKENS;
 		break;
 
+	case AUE_EXECVE:
+		if (ARG_IS_VALID(kar, ARG_ARGV)) {
+			tok = au_to_exec_args(ar->ar_arg_argv,
+			    ar->ar_arg_argc);
+			kau_write(rec, tok);
+		}
+		if (ARG_IS_VALID(kar, ARG_ENVV)) {
+			tok = au_to_exec_env(ar->ar_arg_envv,
+			    ar->ar_arg_envc);
+			kau_write(rec, tok);
+		}
+		UPATH1_VNODE1_TOKENS;
+		break;
+
 	case AUE_FCHMOD:
 		if (ARG_IS_VALID(kar, ARG_MODE)) {
 			tok = au_to_arg32(2, "new file mode",

==== //depot/projects/trustedbsd/audit3/sys/security/audit/audit_bsm_token.c#21 (text+ko) ====

@@ -30,7 +30,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- * $P4: //depot/projects/trustedbsd/audit3/sys/security/audit/audit_bsm_token.c#20 $
+ * $P4: //depot/projects/trustedbsd/audit3/sys/security/audit/audit_bsm_token.c#21 $
  * $FreeBSD: src/sys/security/audit/audit_bsm_token.c,v 1.4 2006/06/17 13:53:04 wsalamon Exp $
  */
 
@@ -1018,13 +1018,60 @@
 }
 #endif
 
+#if defined(_KERNEL) || defined(KERNEL)
+static token_t *
+au_to_exec_strings(char *strs, int count, u_char type)
+{
+	token_t *t;
+	u_char *dptr = NULL;
+	u_int32_t totlen;
+	int ctr;
+	char *p;
+
+	totlen = 0;
+	ctr = count;
+	p = strs;
+	while (ctr-- > 0) {
+		totlen += strlen(p) + 1;
+		p = strs + totlen;
+	}
+	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
+	ADD_U_CHAR(dptr, type);
+	ADD_U_INT32(dptr, count);
+	ADD_STRING(dptr, strs, totlen);
+
+	return (t);
+}
+
+/*
+ * token ID				1 byte
+ * count				4 bytes
+ * text					count null-terminated strings
+ */
+token_t *
+au_to_exec_args(char *args, int argc)
+{
+	return (au_to_exec_strings(args, argc, AUT_EXEC_ARGS));
+}
+
 /*
  * token ID				1 byte
  * count				4 bytes
  * text					count null-terminated strings
  */
 token_t *
-au_to_exec_args(const char **args)
+au_to_exec_env(char *envs, int envc)
+{
+	return (au_to_exec_strings(envs, envc, AUT_EXEC_ENV));
+}
+#else
+/*
+ * token ID				1 byte
+ * count				4 bytes
+ * text					count null-terminated strings
+ */
+token_t *
+au_to_exec_args(char **argv)
 {
 	token_t *t;
 	u_char *dptr = NULL;
@@ -1032,7 +1079,7 @@
 	int i, count = 0;
 	size_t totlen = 0;
 
-	nextarg = *args;
+	nextarg = *argv;
 
 	while (nextarg != NULL) {
 		int nextlen;
@@ -1040,7 +1087,7 @@
 		nextlen = strlen(nextarg);
 		totlen += nextlen + 1;
 		count++;
-		nextarg = *(args + count);
+		nextarg = *(argv + count);
 	}
 
 	totlen += count * sizeof(char);	/* nul terminations. */
@@ -1050,7 +1097,7 @@
 	ADD_U_INT32(dptr, count);
 
 	for (i = 0; i < count; i++) {
-		nextarg = *(args + i);
+		nextarg = *(argv + i);
 		ADD_MEM(dptr, nextarg, strlen(nextarg) + 1);
 	}
 
@@ -1063,7 +1110,7 @@
  * text					count null-terminated strings
  */
 token_t *
-au_to_exec_env(const char **env)
+au_to_exec_env(char **envp)
 {
 	token_t *t;
 	u_char *dptr = NULL;
@@ -1071,7 +1118,7 @@
 	size_t totlen = 0;
 	const char *nextenv;
 
-	nextenv = *env;
+	nextenv = *envp;
 
 	while (nextenv != NULL) {
 		int nextlen;
@@ -1079,7 +1126,7 @@
 		nextlen = strlen(nextenv);
 		totlen += nextlen + 1;
 		count++;
-		nextenv = *(env + count);
+		nextenv = *(envp + count);
 	}
 
 	totlen += sizeof(char) * count;
@@ -1089,12 +1136,13 @@
 	ADD_U_INT32(dptr, count);
 
 	for (i = 0; i < count; i++) {
-		nextenv = *(env + i);
+		nextenv = *(envp + i);
 		ADD_MEM(dptr, nextenv, strlen(nextenv) + 1);
 	}
 
 	return (t);
 }
+#endif
 
 /*
  * token ID                1 byte

==== //depot/projects/trustedbsd/audit3/sys/security/audit/audit_private.h#30 (text+ko) ====

@@ -74,6 +74,8 @@
 extern struct au_mask		audit_nae_mask;
 extern int			audit_panic_on_write_fail;
 extern int			audit_fail_stop;
+extern int			audit_argv;
+extern int			audit_arge;
 
 /*
  * Success/failure conditions for the conversion of a kernel audit record to
@@ -219,6 +221,10 @@
 	void *			ar_arg_svipc_addr;
 	struct posix_ipc_perm	ar_arg_pipc_perm;
 	union auditon_udata	ar_arg_auditon;
+	char			*ar_arg_argv;
+	int			ar_arg_argc;
+	char			*ar_arg_envv;
+	int			ar_arg_envc;
 	int			ar_arg_exitstatus;
 	int			ar_arg_exitretval;
 };

==== //depot/projects/trustedbsd/audit3/sys/security/audit/audit_syscalls.c#18 (text+ko) ====

@@ -195,16 +195,23 @@
 			udata.au_policy |= AUDIT_CNT;
 		if (audit_panic_on_write_fail)
 			udata.au_policy |= AUDIT_AHLT;
+		if (audit_argv)
+			udata.au_policy |= AUDIT_ARGV;
+		if (audit_arge)
+			udata.au_policy |= AUDIT_ARGE;
 		break;
 
 	case A_SETPOLICY:
-		if (udata.au_policy & ~(AUDIT_CNT|AUDIT_AHLT))
+		if (udata.au_policy & ~(AUDIT_CNT|AUDIT_AHLT|AUDIT_ARGV|
+		    AUDIT_ARGE))
 			return (EINVAL);
 		/*
 		 * XXX - Need to wake up waiters if the policy relaxes?
 		 */
 		audit_fail_stop = ((udata.au_policy & AUDIT_CNT) == 0);
 		audit_panic_on_write_fail = (udata.au_policy & AUDIT_AHLT);
+		audit_argv = (udata.au_policy & AUDIT_ARGV);
+		audit_arge = (udata.au_policy & AUDIT_ARGE);
 		break;
 
 	case A_GETKMASK:


More information about the trustedbsd-cvs mailing list