From owner-p4-projects@FreeBSD.ORG Tue Jul 11 22:10:49 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 7EEFB16A4E1; Tue, 11 Jul 2006 22:10:49 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 470D016A4DA for ; Tue, 11 Jul 2006 22:10:49 +0000 (UTC) (envelope-from wsalamon@computer.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 1015243D6D for ; Tue, 11 Jul 2006 22:10:48 +0000 (GMT) (envelope-from wsalamon@computer.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k6BMAlOH015826 for ; Tue, 11 Jul 2006 22:10:47 GMT (envelope-from wsalamon@computer.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k6BMAl3n015814 for perforce@freebsd.org; Tue, 11 Jul 2006 22:10:47 GMT (envelope-from wsalamon@computer.org) Date: Tue, 11 Jul 2006 22:10:47 GMT Message-Id: <200607112210.k6BMAl3n015814@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to wsalamon@computer.org using -f From: Wayne Salamon To: Perforce Change Reviews Cc: Subject: PERFORCE change 101305 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Jul 2006 22:10:49 -0000 http://perforce.freebsd.org/chv.cgi?CH=101305 Change 101305 by wsalamon@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 +#include + 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: