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