xref: /xnu-12377.41.6/bsd/security/audit/audit_bsm.c (revision bbb1b6f9e71b8cdde6e5cd6f4841f207dee3d828)
1 /*
2  * Copyright (c) 1999-2020 Apple Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1.  Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  * 2.  Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
13  *     its contributors may be used to endorse or promote products derived
14  *     from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
20  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
25  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 /*
29  * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce
30  * support for mandatory and extensible security protections.  This notice
31  * is included in support of clause 2.2 (b) of the Apple Public License,
32  * Version 2.0.
33  */
34 
35 #include <sys/types.h>
36 #include <sys/vnode_internal.h>
37 #include <sys/ipc.h>
38 #include <sys/sem.h>
39 #include <sys/socketvar.h>
40 #include <sys/socket.h>
41 #include <sys/queue.h>
42 #include <sys/fcntl.h>
43 #include <sys/user.h>
44 #include <sys/ipc.h>
45 
46 #include <bsm/audit.h>
47 #include <bsm/audit_internal.h>
48 #include <bsm/audit_record.h>
49 #include <bsm/audit_kevents.h>
50 
51 #include <security/audit/audit.h>
52 #include <security/audit/audit_bsd.h>
53 #include <security/audit/audit_private.h>
54 
55 #include <netinet/in_systm.h>
56 #include <netinet/in.h>
57 #include <netinet/ip.h>
58 
59 #if CONFIG_AUDIT
60 MALLOC_DEFINE(M_AUDITBSM, "audit_bsm", "Audit BSM data");
61 
62 #if CONFIG_MACF
63 #include <security/mac_framework.h>
64 #endif
65 
66 static void     audit_sys_auditon(struct audit_record *ar,
67     struct au_record *rec);
68 static void     audit_sys_fcntl(struct kaudit_record *kar,
69     struct au_record *rec);
70 
71 /*
72  * Initialize the BSM auditing subsystem.
73  */
74 void
kau_init(void)75 kau_init(void)
76 {
77 	au_evclassmap_init();
78 }
79 
80 /*
81  * This call reserves memory for the audit record.  Memory must be guaranteed
82  * before any auditable event can be generated.  The au_record structure
83  * maintains a reference to the memory allocated above and also the list of
84  * tokens associated with this record.
85  */
86 static struct au_record *
kau_open(void)87 kau_open(void)
88 {
89 	struct au_record *rec;
90 
91 	rec = kalloc_type(struct au_record, Z_WAITOK | Z_ZERO | Z_NOFAIL);
92 	TAILQ_INIT(&rec->token_q);
93 	rec->used = 1;
94 	rec->data = NULL;
95 
96 	return rec;
97 }
98 
99 /*
100  * Store the token with the record descriptor.
101  */
102 static void
kau_write(struct au_record * rec,struct au_token * tok)103 kau_write(struct au_record *rec, struct au_token *tok)
104 {
105 	KASSERT(tok != NULL, ("kau_write: tok == NULL"));
106 
107 	TAILQ_INSERT_TAIL(&rec->token_q, tok, tokens);
108 	rec->len += tok->len;
109 }
110 
111 /*
112  * Close out the audit record by adding the header token, identifying any
113  * missing tokens.  Write out the tokens to the record memory.
114  */
115 static int
kau_close(struct au_record * rec,struct timespec * ctime,short event)116 kau_close(struct au_record *rec, struct timespec *ctime, short event)
117 {
118 	u_char *dptr;
119 	size_t tot_rec_size;
120 	token_t *cur, *hdr, *trail;
121 	struct timeval tm;
122 	size_t hdrsize;
123 	struct auditinfo_addr ak;
124 	struct in6_addr *ap;
125 
126 	audit_get_kinfo(&ak);
127 	hdrsize = 0;
128 	switch (ak.ai_termid.at_type) {
129 	case AU_IPv4:
130 		hdrsize = (ak.ai_termid.at_addr[0] == INADDR_ANY) ?
131 		    AUDIT_HEADER_SIZE : AUDIT_HEADER_EX_SIZE(&ak);
132 		break;
133 	case AU_IPv6:
134 		ap = (struct in6_addr *)&ak.ai_termid.at_addr[0];
135 		hdrsize = (IN6_IS_ADDR_UNSPECIFIED(ap)) ? AUDIT_HEADER_SIZE :
136 		    AUDIT_HEADER_EX_SIZE(&ak);
137 		break;
138 	default:
139 		panic("kau_close: invalid address family");
140 	}
141 	tot_rec_size = rec->len + AUDIT_HEADER_SIZE + AUDIT_TRAILER_SIZE;
142 	rec->data = kalloc_data(tot_rec_size, Z_WAITOK | Z_ZERO);
143 	if (rec->data == NULL) {
144 		return ENOMEM;
145 	}
146 
147 	tm.tv_usec = ctime->tv_nsec / 1000;
148 	tm.tv_sec = ctime->tv_sec;
149 	if (hdrsize != AUDIT_HEADER_SIZE) {
150 		hdr = au_to_header32_ex_tm(tot_rec_size, event, 0, tm, &ak);
151 	} else {
152 		hdr = au_to_header32_tm(tot_rec_size, event, 0, tm);
153 	}
154 	TAILQ_INSERT_HEAD(&rec->token_q, hdr, tokens);
155 
156 	trail = au_to_trailer(tot_rec_size);
157 	TAILQ_INSERT_TAIL(&rec->token_q, trail, tokens);
158 
159 	rec->len = tot_rec_size;
160 	dptr = rec->data;
161 	TAILQ_FOREACH(cur, &rec->token_q, tokens) {
162 		memcpy(dptr, cur->t_data, cur->len);
163 		dptr += cur->len;
164 	}
165 
166 	return 0;
167 }
168 
169 /*
170  * Free a BSM audit record by releasing all the tokens and clearing the audit
171  * record information.
172  */
173 void
kau_free(struct au_record * rec)174 kau_free(struct au_record *rec)
175 {
176 	struct au_token *tok;
177 
178 	/* Free the token list. */
179 	while ((tok = TAILQ_FIRST(&rec->token_q))) {
180 		TAILQ_REMOVE(&rec->token_q, tok, tokens);
181 		kfree_data(tok->t_data, tok->len);
182 		kfree_type(token_t, tok);
183 	}
184 
185 	if (rec->data != NULL) {
186 		kfree_data(rec->data, rec->len);
187 	}
188 	kfree_type(struct au_record, rec);
189 }
190 
191 /*
192  * XXX: May want turn some (or all) of these macros into functions in order
193  * to reduce the generated code size.
194  *
195  * XXXAUDIT: These macros assume that 'kar', 'ar', 'rec', and 'tok' in the
196  * caller are OK with this.
197  */
198 #if CONFIG_MACF
199 #define MAC_VNODE1_LABEL_TOKEN   do {                                     \
200 	if (ar->ar_vnode1_mac_labels != NULL &&                           \
201 	    strlen(ar->ar_vnode1_mac_labels) != 0) {                      \
202 	        tok = au_to_text(ar->ar_vnode1_mac_labels);               \
203 	        kau_write(rec, tok);                                      \
204 	}                                                                 \
205 } while (0)
206 
207 #define MAC_VNODE2_LABEL_TOKEN  do {                                      \
208 	if (ar->ar_vnode2_mac_labels != NULL &&                           \
209 	    strlen(ar->ar_vnode2_mac_labels) != 0) {                      \
210 	        tok = au_to_text(ar->ar_vnode2_mac_labels);               \
211 	        kau_write(rec, tok);                                      \
212 	}                                                                 \
213 } while (0)
214 #else
215 #define MAC_VNODE1_LABEL_TOKEN
216 #define MAC_VNODE2_LABEL_TOKEN
217 #endif
218 #define UPATH1_TOKENS do {                                              \
219 	if (ARG_IS_VALID(kar, ARG_UPATH1)) {                            \
220 	        tok = au_to_path(ar->ar_arg_upath1);                    \
221 	        kau_write(rec, tok);                                    \
222 	}                                                               \
223 } while (0)
224 
225 #define UPATH2_TOKENS do {                                              \
226 	if (ARG_IS_VALID(kar, ARG_UPATH2)) {                            \
227 	        tok = au_to_path(ar->ar_arg_upath2);                    \
228 	        kau_write(rec, tok);                                    \
229 	}                                                               \
230 } while (0)
231 
232 #define KPATH2_TOKENS do {                                              \
233 	if (ARG_IS_VALID(kar, ARG_KPATH2)) {                            \
234 	        tok = au_to_path(ar->ar_arg_kpath2);                    \
235 	        kau_write(rec, tok);                                    \
236 	}                                                               \
237 } while (0)
238 
239 #define VNODE1_TOKENS do {                                              \
240 	if (ARG_IS_VALID(kar, ARG_KPATH1)) {                            \
241 	        tok = au_to_path(ar->ar_arg_kpath1);                    \
242 	        kau_write(rec, tok);                                    \
243 	}                                                               \
244 	if (ARG_IS_VALID(kar, ARG_VNODE1)) {                            \
245 	        tok = au_to_attr32(&ar->ar_arg_vnode1);                 \
246 	        kau_write(rec, tok);                                    \
247 	        MAC_VNODE1_LABEL_TOKEN;                                 \
248 	}                                                               \
249 } while (0)
250 
251 #define UPATH1_VNODE1_TOKENS do {                                       \
252 	if (ARG_IS_VALID(kar, ARG_UPATH1)) {                            \
253 	        tok = au_to_path(ar->ar_arg_upath1);                    \
254 	        kau_write(rec, tok);                                    \
255 	}                                                               \
256 	if (ARG_IS_VALID(kar, ARG_KPATH1)) {                            \
257 	        tok = au_to_path(ar->ar_arg_kpath1);                    \
258 	        kau_write(rec, tok);                                    \
259 	}                                                               \
260 	if (ARG_IS_VALID(kar, ARG_VNODE1)) {                            \
261 	        tok = au_to_attr32(&ar->ar_arg_vnode1);                 \
262 	        kau_write(rec, tok);                                    \
263 	        MAC_VNODE1_LABEL_TOKEN;                                 \
264 	}                                                               \
265 } while (0)
266 
267 #define VNODE2_TOKENS do {                                              \
268 	if (ARG_IS_VALID(kar, ARG_VNODE2)) {                            \
269 	        tok = au_to_attr32(&ar->ar_arg_vnode2);                 \
270 	        kau_write(rec, tok);                                    \
271 	        MAC_VNODE2_LABEL_TOKEN;                                 \
272 	}                                                               \
273 } while (0)
274 
275 #define VNODE2_PATH_TOKENS do {                                 \
276 	if (ARG_IS_VALID(kar, ARG_KPATH2)) {                            \
277 	        tok = au_to_path(ar->ar_arg_kpath2);                    \
278 	        kau_write(rec, tok);                                    \
279 	}                                                               \
280 	if (ARG_IS_VALID(kar, ARG_VNODE2)) {                            \
281 	        tok = au_to_attr32(&ar->ar_arg_vnode2);                 \
282 	        kau_write(rec, tok);                                    \
283 	        MAC_VNODE2_LABEL_TOKEN;                                 \
284 	}                                                               \
285 } while (0)
286 
287 #define FD_VNODE1_TOKENS do {                                           \
288 	if (ARG_IS_VALID(kar, ARG_VNODE1)) {                            \
289 	        if (ARG_IS_VALID(kar, ARG_KPATH1)) {                    \
290 	                tok = au_to_path(ar->ar_arg_kpath1);            \
291 	                kau_write(rec, tok);                            \
292 	        }                                                       \
293 	        if (ARG_IS_VALID(kar, ARG_FD)) {                        \
294 	                tok = au_to_arg32(1, "fd", ar->ar_arg_fd);      \
295 	                kau_write(rec, tok);                            \
296 	                MAC_VNODE1_LABEL_TOKEN;                         \
297 	        }                                                       \
298 	        tok = au_to_attr32(&ar->ar_arg_vnode1);                 \
299 	        kau_write(rec, tok);                                    \
300 	} else {                                                        \
301 	        if (ARG_IS_VALID(kar, ARG_FD)) {                        \
302 	                tok = au_to_arg32(1, "fd",                      \
303 	                    ar->ar_arg_fd);                             \
304 	                kau_write(rec, tok);                            \
305 	                MAC_VNODE1_LABEL_TOKEN;                         \
306 	        }                                                       \
307 	}                                                               \
308 } while (0)
309 
310 #define PROCESS_PID_TOKENS(argn) do {                                   \
311 	if ((ar->ar_arg_pid > 0) /* Reference a single process */       \
312 	    && (ARG_IS_VALID(kar, ARG_PROCESS))) {                      \
313 	        tok = au_to_process32_ex(ar->ar_arg_auid,               \
314 	            ar->ar_arg_euid, ar->ar_arg_egid,                   \
315 	            ar->ar_arg_ruid, ar->ar_arg_rgid,                   \
316 	            ar->ar_arg_pid, ar->ar_arg_asid,                    \
317 	            &ar->ar_arg_termid_addr);                           \
318 	        kau_write(rec, tok);                                    \
319 	} else if (ARG_IS_VALID(kar, ARG_PID)) {                        \
320 	        tok = au_to_arg32(argn, "process", ar->ar_arg_pid);     \
321 	        kau_write(rec, tok);                                    \
322 	}                                                               \
323 } while (0)
324 
325 #define EXTATTR_TOKENS do {                                             \
326 	if (ARG_IS_VALID(kar, ARG_VALUE32)) {                           \
327 	        switch (ar->ar_arg_value32) {                           \
328 	        case EXTATTR_NAMESPACE_USER:                            \
329 	                tok = au_to_text(EXTATTR_NAMESPACE_USER_STRING);\
330 	                break;                                          \
331 	        case EXTATTR_NAMESPACE_SYSTEM:                          \
332 	                tok = au_to_text(EXTATTR_NAMESPACE_SYSTEM_STRING);\
333 	                break;                                          \
334 	        default:                                                \
335 	                tok = au_to_arg32(3, "attrnamespace",           \
336 	                    ar->ar_arg_value32);                        \
337 	                break;                                          \
338 	        }                                                       \
339 	        kau_write(rec, tok);                                    \
340 	}                                                               \
341 	/* attrname is in the text field */                             \
342 	if (ARG_IS_VALID(kar, ARG_TEXT)) {                              \
343 	        tok = au_to_text(ar->ar_arg_text);                      \
344 	        kau_write(rec, tok);                                    \
345 	}                                                               \
346 } while (0)
347 
348 #define EXTENDED_TOKENS(n) do {                                         \
349 	/* ACL data */                                          \
350 	        if (ARG_IS_VALID(kar, ARG_OPAQUE)) {                    \
351 	                tok = au_to_opaque(ar->ar_arg_opaque,           \
352 	                    ar->ar_arg_opq_size);                       \
353 	                kau_write(rec, tok);                            \
354 	        }                                                       \
355 	        if (ARG_IS_VALID(kar, ARG_MODE)) {                      \
356 	                tok = au_to_arg32(n+2, "mode", ar->ar_arg_mode);\
357 	                kau_write(rec, tok);                            \
358 	        }                                                       \
359 	        if (ARG_IS_VALID(kar, ARG_GID)) {                       \
360 	                tok = au_to_arg32(n+1, "gid", ar->ar_arg_gid);  \
361 	                kau_write(rec, tok);                            \
362 	        }                                                       \
363 	        if (ARG_IS_VALID(kar, ARG_UID)) {                       \
364 	                tok = au_to_arg32(n, "uid", ar->ar_arg_uid);    \
365 	                kau_write(rec, tok);                            \
366 	        }                                                       \
367 } while (0)
368 
369 #define PROCESS_MAC_TOKENS do {                                         \
370 	if (ar->ar_valid_arg & ARG_MAC_STRING) {                        \
371 	        tok = au_to_text(ar->ar_arg_mac_string);                \
372 	        kau_write(rec, tok);                                    \
373 	}                                                               \
374 } while (0)
375 
376 /*
377  * Implement auditing for the auditon() system call. The audit tokens that
378  * are generated depend on the command that was sent into the auditon()
379  * system call.
380  */
381 static void
audit_sys_auditon(struct audit_record * ar,struct au_record * rec)382 audit_sys_auditon(struct audit_record *ar, struct au_record *rec)
383 {
384 	struct au_token *tok;
385 
386 	switch (ar->ar_arg_cmd) {
387 	case A_OLDSETPOLICY:
388 		if (ar->ar_arg_len > sizeof(int)) {
389 			tok = au_to_arg32(3, "length", ar->ar_arg_len);
390 			kau_write(rec, tok);
391 			tok = au_to_arg64(2, "policy",
392 			    ar->ar_arg_auditon.au_policy64);
393 			kau_write(rec, tok);
394 			break;
395 		}
396 		OS_FALLTHROUGH;
397 	case A_SETPOLICY:
398 		tok = au_to_arg32(3, "length", ar->ar_arg_len);
399 		kau_write(rec, tok);
400 		tok = au_to_arg32(2, "policy", ar->ar_arg_auditon.au_policy);
401 		kau_write(rec, tok);
402 		break;
403 
404 	case A_SETKMASK:
405 		tok = au_to_arg32(3, "length", ar->ar_arg_len);
406 		kau_write(rec, tok);
407 		tok = au_to_arg32(2, "setkmask:as_success",
408 		    ar->ar_arg_auditon.au_mask.am_success);
409 		kau_write(rec, tok);
410 		tok = au_to_arg32(2, "setkmask:as_failure",
411 		    ar->ar_arg_auditon.au_mask.am_failure);
412 		kau_write(rec, tok);
413 		break;
414 
415 	case A_OLDSETQCTRL:
416 		if (ar->ar_arg_len > sizeof(au_qctrl_t)) {
417 			tok = au_to_arg32(3, "length", ar->ar_arg_len);
418 			kau_write(rec, tok);
419 			tok = au_to_arg64(2, "setqctrl:aq_hiwater",
420 			    ar->ar_arg_auditon.au_qctrl64.aq64_hiwater);
421 			kau_write(rec, tok);
422 			tok = au_to_arg64(2, "setqctrl:aq_lowater",
423 			    ar->ar_arg_auditon.au_qctrl64.aq64_lowater);
424 			kau_write(rec, tok);
425 			tok = au_to_arg64(2, "setqctrl:aq_bufsz",
426 			    ar->ar_arg_auditon.au_qctrl64.aq64_bufsz);
427 			kau_write(rec, tok);
428 			tok = au_to_arg64(2, "setqctrl:aq_delay",
429 			    ar->ar_arg_auditon.au_qctrl64.aq64_delay);
430 			kau_write(rec, tok);
431 			tok = au_to_arg32(2, "setqctrl:aq_minfree",
432 			    ar->ar_arg_auditon.au_qctrl64.aq64_minfree);
433 			kau_write(rec, tok);
434 			break;
435 		}
436 		OS_FALLTHROUGH;
437 	case A_SETQCTRL:
438 		tok = au_to_arg32(3, "length", ar->ar_arg_len);
439 		kau_write(rec, tok);
440 		tok = au_to_arg32(2, "setqctrl:aq_hiwater",
441 		    ar->ar_arg_auditon.au_qctrl.aq_hiwater);
442 		kau_write(rec, tok);
443 		tok = au_to_arg32(2, "setqctrl:aq_lowater",
444 		    ar->ar_arg_auditon.au_qctrl.aq_lowater);
445 		kau_write(rec, tok);
446 		tok = au_to_arg32(2, "setqctrl:aq_bufsz",
447 		    ar->ar_arg_auditon.au_qctrl.aq_bufsz);
448 		kau_write(rec, tok);
449 		tok = au_to_arg32(2, "setqctrl:aq_delay",
450 		    ar->ar_arg_auditon.au_qctrl.aq_delay);
451 		kau_write(rec, tok);
452 		tok = au_to_arg32(2, "setqctrl:aq_minfree",
453 		    ar->ar_arg_auditon.au_qctrl.aq_minfree);
454 		kau_write(rec, tok);
455 		break;
456 
457 	case A_SETUMASK:
458 		tok = au_to_arg32(3, "length", ar->ar_arg_len);
459 		kau_write(rec, tok);
460 		tok = au_to_arg32(2, "setumask:as_success",
461 		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_success);
462 		kau_write(rec, tok);
463 		tok = au_to_arg32(2, "setumask:as_failure",
464 		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_failure);
465 		kau_write(rec, tok);
466 		break;
467 
468 	case A_SETSMASK:
469 		tok = au_to_arg32(3, "length", ar->ar_arg_len);
470 		kau_write(rec, tok);
471 		tok = au_to_arg32(2, "setsmask:as_success",
472 		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_success);
473 		kau_write(rec, tok);
474 		tok = au_to_arg32(2, "setsmask:as_failure",
475 		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_failure);
476 		kau_write(rec, tok);
477 		break;
478 
479 	case A_OLDSETCOND:
480 		if (ar->ar_arg_len > sizeof(int)) {
481 			tok = au_to_arg32(3, "length", ar->ar_arg_len);
482 			kau_write(rec, tok);
483 			tok = au_to_arg64(2, "setcond",
484 			    ar->ar_arg_auditon.au_cond64);
485 			kau_write(rec, tok);
486 			break;
487 		}
488 		OS_FALLTHROUGH;
489 	case A_SETCOND:
490 		tok = au_to_arg32(3, "length", ar->ar_arg_len);
491 		kau_write(rec, tok);
492 		tok = au_to_arg32(2, "setcond", ar->ar_arg_auditon.au_cond);
493 		kau_write(rec, tok);
494 		break;
495 
496 	case A_SETCLASS:
497 		tok = au_to_arg32(3, "length", ar->ar_arg_len);
498 		kau_write(rec, tok);
499 		tok = au_to_arg32(2, "setclass:ec_event",
500 		    ar->ar_arg_auditon.au_evclass.ec_number);
501 		kau_write(rec, tok);
502 		tok = au_to_arg32(3, "setclass:ec_class",
503 		    ar->ar_arg_auditon.au_evclass.ec_class);
504 		kau_write(rec, tok);
505 		break;
506 
507 	case A_SETPMASK:
508 		tok = au_to_arg32(3, "length", ar->ar_arg_len);
509 		kau_write(rec, tok);
510 		tok = au_to_arg32(2, "setpmask:as_success",
511 		    ar->ar_arg_auditon.au_aupinfo.ap_mask.am_success);
512 		kau_write(rec, tok);
513 		tok = au_to_arg32(2, "setpmask:as_failure",
514 		    ar->ar_arg_auditon.au_aupinfo.ap_mask.am_failure);
515 		kau_write(rec, tok);
516 		break;
517 
518 	case A_SETFSIZE:
519 		tok = au_to_arg32(3, "length", ar->ar_arg_len);
520 		kau_write(rec, tok);
521 		tok = au_to_arg32(2, "setfsize:filesize",
522 		    ar->ar_arg_auditon.au_fstat.af_filesz);
523 		kau_write(rec, tok);
524 		break;
525 
526 	default:
527 		break;
528 	}
529 	tok = au_to_arg32(1, "cmd", ar->ar_arg_cmd);
530 	kau_write(rec, tok);
531 }
532 
533 /*
534  * Implement auditing for the fcntl() system call. The audit tokens that
535  * are generated depend on the command that was sent into the fcntl()
536  * system call.
537  */
538 static void
audit_sys_fcntl(struct kaudit_record * kar,struct au_record * rec)539 audit_sys_fcntl(struct kaudit_record *kar, struct au_record *rec)
540 {
541 	struct au_token *tok;
542 	struct audit_record *ar = &kar->k_ar;
543 
544 	switch (ar->ar_arg_cmd) {
545 	case F_DUPFD:
546 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
547 			tok = au_to_arg32(3, "min fd", ar->ar_arg_value32);
548 			kau_write(rec, tok);
549 		}
550 		break;
551 
552 	case F_SETFD:
553 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
554 			tok = au_to_arg32(3, "close-on-exec flag",
555 			    ar->ar_arg_value32);
556 			kau_write(rec, tok);
557 		}
558 		break;
559 
560 	case F_SETFL:
561 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
562 			tok = au_to_arg32(3, "fd flags", ar->ar_arg_value32);
563 			kau_write(rec, tok);
564 		}
565 		break;
566 
567 	case F_SETOWN:
568 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
569 			tok = au_to_arg32(3, "pid", ar->ar_arg_value32);
570 			kau_write(rec, tok);
571 		}
572 		break;
573 
574 #ifdef  F_SETSIZE
575 	case F_SETSIZE:
576 		if (ARG_IS_VALID(kar, ARG_VALUE64)) {
577 			tok = au_to_arg64(3, "offset", ar->ar_arg_value64);
578 			kau_write(rec, tok);
579 		}
580 		break;
581 #endif /* F_SETSIZE */
582 
583 #ifdef  F_PATHPKG_CHECK
584 	case F_PATHPKG_CHECK:
585 		if (ARG_IS_VALID(kar, ARG_TEXT)) {
586 			tok = au_to_text(ar->ar_arg_text);
587 			kau_write(rec, tok);
588 		}
589 		break;
590 #endif
591 
592 	default:
593 		break;
594 	}
595 	tok = au_to_arg32(2, "cmd", au_fcntl_cmd_to_bsm(ar->ar_arg_cmd));
596 	kau_write(rec, tok);
597 }
598 
599 /*
600  * Convert an internal kernel audit record to a BSM record and return a
601  * success/failure indicator. The BSM record is passed as an out parameter to
602  * this function.
603  *
604  * Return conditions:
605  *   BSM_SUCCESS: The BSM record is valid
606  *   BSM_FAILURE: Failure; the BSM record is NULL.
607  *   BSM_NOAUDIT: The event is not auditable for BSM; the BSM record is NULL.
608  */
609 int
kaudit_to_bsm(struct kaudit_record * kar,struct au_record ** pau)610 kaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau)
611 {
612 	struct au_token *tok = NULL, *subj_tok;
613 	struct au_record *rec = NULL;
614 	au_tid_t tid;
615 	struct audit_record *ar;
616 	int ctr;
617 	u_int uctr;
618 	int rv;
619 
620 	KASSERT(kar != NULL, ("kaudit_to_bsm: kar == NULL"));
621 
622 	*pau = NULL;
623 	ar = &kar->k_ar;
624 	rec = kau_open();
625 
626 	/*
627 	 * Create the subject token.
628 	 */
629 	switch (ar->ar_subj_term_addr.at_type) {
630 	case AU_IPv4:
631 		tid.port = ar->ar_subj_term_addr.at_port;
632 		tid.machine = ar->ar_subj_term_addr.at_addr[0];
633 		subj_tok = au_to_subject32(ar->ar_subj_auid,  /* audit ID */
634 		    ar->ar_subj_cred.cr_uid, /* eff uid */
635 		    ar->ar_subj_egid,   /* eff group id */
636 		    ar->ar_subj_ruid,   /* real uid */
637 		    ar->ar_subj_rgid,   /* real group id */
638 		    ar->ar_subj_pid,    /* process id */
639 		    ar->ar_subj_asid,   /* session ID */
640 		    &tid);
641 		break;
642 	case AU_IPv6:
643 		subj_tok = au_to_subject32_ex(ar->ar_subj_auid,
644 		    ar->ar_subj_cred.cr_uid,
645 		    ar->ar_subj_egid,
646 		    ar->ar_subj_ruid,
647 		    ar->ar_subj_rgid,
648 		    ar->ar_subj_pid,
649 		    ar->ar_subj_asid,
650 		    &ar->ar_subj_term_addr);
651 		break;
652 	default:
653 		bzero(&tid, sizeof(tid));
654 		subj_tok = au_to_subject32(ar->ar_subj_auid,
655 		    ar->ar_subj_cred.cr_uid,
656 		    ar->ar_subj_egid,
657 		    ar->ar_subj_ruid,
658 		    ar->ar_subj_rgid,
659 		    ar->ar_subj_pid,
660 		    ar->ar_subj_asid,
661 		    &tid);
662 	}
663 
664 	/*
665 	 * The logic inside each case fills in the tokens required for the
666 	 * event, except for the header, trailer, and return tokens.  The
667 	 * header and trailer tokens are added by the kau_close() function.
668 	 * The return token is added outside of the switch statement.
669 	 */
670 	switch (ar->ar_event) {
671 	case AUE_SENDFILE:
672 		/* For sendfile the file and socket descriptor are both saved */
673 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
674 			tok = au_to_arg32(2, "sd", ar->ar_arg_value32);
675 			kau_write(rec, tok);
676 		}
677 		OS_FALLTHROUGH;
678 	case AUE_ACCEPT:
679 	case AUE_BIND:
680 	case AUE_LISTEN:
681 	case AUE_CONNECT:
682 	case AUE_RECVFROM:
683 	case AUE_RECVMSG:
684 	case AUE_SENDMSG:
685 	case AUE_SENDTO:
686 		/*
687 		 * Socket-related events.
688 		 */
689 		if (ARG_IS_VALID(kar, ARG_FD)) {
690 			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
691 			kau_write(rec, tok);
692 		}
693 		if (ARG_IS_VALID(kar, ARG_SADDRINET)) {
694 			tok = au_to_sock_inet((struct sockaddr_in *)
695 			    &ar->ar_arg_sockaddr);
696 			kau_write(rec, tok);
697 		}
698 		if (ARG_IS_VALID(kar, ARG_SADDRUNIX)) {
699 			tok = au_to_sock_unix((struct sockaddr_un *)
700 			    &ar->ar_arg_sockaddr);
701 			kau_write(rec, tok);
702 			UPATH1_TOKENS;
703 		}
704 		if (ARG_IS_VALID(kar, ARG_SADDRINET6)) {
705 			tok = au_to_sock_inet128((struct sockaddr_in6 *)
706 			    &ar->ar_arg_sockaddr);
707 			kau_write(rec, tok);
708 		}
709 		break;
710 
711 	case AUE_SOCKET:
712 	case AUE_SOCKETPAIR:
713 		if (ARG_IS_VALID(kar, ARG_SOCKINFO)) {
714 			tok = au_to_arg32(1, "domain",
715 			    au_domain_to_bsm(ar->ar_arg_sockinfo.sai_domain));
716 			kau_write(rec, tok);
717 			tok = au_to_arg32(2, "type",
718 			    au_socket_type_to_bsm(ar->ar_arg_sockinfo.sai_type));
719 			kau_write(rec, tok);
720 			tok = au_to_arg32(3, "protocol",
721 			    ar->ar_arg_sockinfo.sai_protocol);
722 			kau_write(rec, tok);
723 		}
724 		break;
725 
726 	case AUE_SETSOCKOPT:
727 	case AUE_SHUTDOWN:
728 		if (ARG_IS_VALID(kar, ARG_FD)) {
729 			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
730 			kau_write(rec, tok);
731 		}
732 		break;
733 
734 	case AUE_ACCT:
735 		if (ARG_IS_VALID(kar, (ARG_KPATH1 | ARG_UPATH1))) {
736 			UPATH1_VNODE1_TOKENS;
737 		} else {
738 			tok = au_to_arg32(1, "accounting off", 0);
739 			kau_write(rec, tok);
740 		}
741 		break;
742 
743 	case AUE_SETAUID:
744 		if (ARG_IS_VALID(kar, ARG_AUID)) {
745 			tok = au_to_arg32(2, "setauid", ar->ar_arg_auid);
746 			kau_write(rec, tok);
747 		}
748 		break;
749 
750 	case AUE_SETAUDIT:
751 		if (ARG_IS_VALID(kar, ARG_AUID) &&
752 		    ARG_IS_VALID(kar, ARG_ASID) &&
753 		    ARG_IS_VALID(kar, ARG_AMASK) &&
754 		    ARG_IS_VALID(kar, ARG_TERMID)) {
755 			tok = au_to_arg32(1, "setaudit:auid",
756 			    ar->ar_arg_auid);
757 			kau_write(rec, tok);
758 			tok = au_to_arg32(1, "setaudit:port",
759 			    ar->ar_arg_termid.port);
760 			kau_write(rec, tok);
761 			tok = au_to_arg32(1, "setaudit:machine",
762 			    ar->ar_arg_termid.machine);
763 			kau_write(rec, tok);
764 			tok = au_to_arg32(1, "setaudit:as_success",
765 			    ar->ar_arg_amask.am_success);
766 			kau_write(rec, tok);
767 			tok = au_to_arg32(1, "setaudit:as_failure",
768 			    ar->ar_arg_amask.am_failure);
769 			kau_write(rec, tok);
770 			tok = au_to_arg32(1, "setaudit:asid",
771 			    ar->ar_arg_asid);
772 			kau_write(rec, tok);
773 		}
774 		break;
775 
776 	case AUE_SETAUDIT_ADDR:
777 		if (ARG_IS_VALID(kar, ARG_AUID) &&
778 		    ARG_IS_VALID(kar, ARG_ASID) &&
779 		    ARG_IS_VALID(kar, ARG_AMASK) &&
780 		    ARG_IS_VALID(kar, ARG_TERMID_ADDR)) {
781 			tok = au_to_arg32(1, "setaudit_addr:auid",
782 			    ar->ar_arg_auid);
783 			kau_write(rec, tok);
784 			tok = au_to_arg32(1, "setaudit_addr:as_success",
785 			    ar->ar_arg_amask.am_success);
786 			kau_write(rec, tok);
787 			tok = au_to_arg32(1, "setaudit_addr:as_failure",
788 			    ar->ar_arg_amask.am_failure);
789 			kau_write(rec, tok);
790 			tok = au_to_arg32(1, "setaudit_addr:asid",
791 			    ar->ar_arg_asid);
792 			kau_write(rec, tok);
793 			tok = au_to_arg32(1, "setaudit_addr:type",
794 			    ar->ar_arg_termid_addr.at_type);
795 			kau_write(rec, tok);
796 			tok = au_to_arg32(1, "setaudit_addr:port",
797 			    ar->ar_arg_termid_addr.at_port);
798 			kau_write(rec, tok);
799 			switch (ar->ar_arg_termid_addr.at_type) {
800 			case AU_IPv6:
801 				tok = au_to_in_addr_ex((struct in6_addr *)
802 				    &ar->ar_arg_termid_addr.at_addr[0]);
803 				kau_write(rec, tok);
804 				break;
805 			case AU_IPv4:
806 				tok = au_to_in_addr((struct in_addr *)
807 				    &ar->ar_arg_termid_addr.at_addr[0]);
808 				kau_write(rec, tok);
809 				break;
810 			}
811 		}
812 		break;
813 
814 	case AUE_AUDITON:
815 		/*
816 		 * For AUDITON commands without own event, audit the cmd.
817 		 */
818 		if (ARG_IS_VALID(kar, ARG_CMD)) {
819 			tok = au_to_arg32(1, "cmd", ar->ar_arg_cmd);
820 			kau_write(rec, tok);
821 		}
822 		OS_FALLTHROUGH;
823 
824 	case AUE_AUDITON_GETCAR:
825 	case AUE_AUDITON_GETCLASS:
826 	case AUE_AUDITON_GETCOND:
827 	case AUE_AUDITON_GETCWD:
828 	case AUE_AUDITON_GETKMASK:
829 	case AUE_AUDITON_GETSTAT:
830 	case AUE_AUDITON_GPOLICY:
831 	case AUE_AUDITON_GQCTRL:
832 	case AUE_AUDITON_SETCLASS:
833 	case AUE_AUDITON_SETCOND:
834 	case AUE_AUDITON_SETKMASK:
835 	case AUE_AUDITON_SETSMASK:
836 	case AUE_AUDITON_SETSTAT:
837 	case AUE_AUDITON_SETUMASK:
838 	case AUE_AUDITON_SPOLICY:
839 	case AUE_AUDITON_SQCTRL:
840 		if (ARG_IS_VALID(kar, ARG_AUDITON)) {
841 			audit_sys_auditon(ar, rec);
842 		}
843 		break;
844 
845 	case AUE_AUDITCTL:
846 		UPATH1_VNODE1_TOKENS;
847 		break;
848 
849 	case AUE_EXIT:
850 		if (ARG_IS_VALID(kar, ARG_EXIT)) {
851 			tok = au_to_exit(ar->ar_arg_exitretval,
852 			    ar->ar_arg_exitstatus);
853 			kau_write(rec, tok);
854 		}
855 		break;
856 
857 	case AUE_ADJTIME:
858 	case AUE_AUDIT:
859 	case AUE_DUP2:
860 	case AUE_GETAUDIT:
861 	case AUE_GETAUDIT_ADDR:
862 	case AUE_GETAUID:
863 	case AUE_GETFSSTAT:
864 	case AUE_KQUEUE:
865 	case AUE_LSEEK:
866 #if 0
867 /*  XXXss replace with kext  */
868 	case AUE_MODLOAD:
869 	case AUE_MODUNLOAD:
870 #endif
871 	case AUE_MAC_GETFSSTAT:
872 	case AUE_PIPE:
873 	case AUE_PROFILE:
874 	case AUE_SEMSYS:
875 	case AUE_SHMSYS:
876 	case AUE_SETPGRP:
877 	case AUE_SETRLIMIT:
878 	case AUE_SETSID:
879 	case AUE_SETTIMEOFDAY:
880 	case AUE_KDEBUGTRACE:
881 	case AUE_PTHREADSIGMASK:
882 		/*
883 		 * Header, subject, and return tokens added at end.
884 		 */
885 		break;
886 
887 	case AUE_MKFIFO:
888 		if (ARG_IS_VALID(kar, ARG_MODE)) {
889 			tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
890 			kau_write(rec, tok);
891 		}
892 		UPATH1_VNODE1_TOKENS;
893 		break;
894 
895 	case AUE_ACCESS_EXTENDED:
896 		/*
897 		 * The access_extended() argument vector is stored in an
898 		 * opaque token.
899 		 */
900 		if (ARG_IS_VALID(kar, ARG_OPAQUE)) {
901 			tok = au_to_opaque(ar->ar_arg_opaque,
902 			    ar->ar_arg_opq_size);
903 			kau_write(rec, tok);
904 		}
905 		/*
906 		 * The access_extended() result vector is stored in an arbitrary
907 		 * data token.
908 		 */
909 		if (ARG_IS_VALID(kar, ARG_DATA)) {
910 			tok = au_to_data(AUP_DECIMAL, ar->ar_arg_data_type,
911 			    ar->ar_arg_data_count, ar->ar_arg_data);
912 			kau_write(rec, tok);
913 		}
914 		UPATH1_VNODE1_TOKENS;
915 		break;
916 
917 	case AUE_LSTAT_EXTENDED:
918 	case AUE_STAT_EXTENDED:
919 	case AUE_ACCESS:
920 	case AUE_CHDIR:
921 	case AUE_CHROOT:
922 	case AUE_GETATTRLIST:
923 	case AUE_NFS_GETFH:
924 	case AUE_LSTAT:
925 	case AUE_PATHCONF:
926 	case AUE_READLINK:
927 	case AUE_REVOKE:
928 	case AUE_RMDIR:
929 	case AUE_SEARCHFS:
930 	case AUE_SETATTRLIST:
931 	case AUE_STAT:
932 	case AUE_STATFS:
933 	case AUE_TRUNCATE:
934 	case AUE_UNDELETE:
935 	case AUE_UNLINK:
936 	case AUE_UTIMES:
937 		UPATH1_VNODE1_TOKENS;
938 		break;
939 
940 	case AUE_FHOPEN:
941 		break;
942 
943 	case AUE_CHFLAGS:
944 		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
945 			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
946 			kau_write(rec, tok);
947 		}
948 		UPATH1_VNODE1_TOKENS;
949 		break;
950 
951 	case AUE_CHMOD:
952 		if (ARG_IS_VALID(kar, ARG_MODE)) {
953 			tok = au_to_arg32(2, "new file mode",
954 			    ar->ar_arg_mode);
955 			kau_write(rec, tok);
956 		}
957 		UPATH1_VNODE1_TOKENS;
958 		break;
959 
960 	case AUE_CHOWN:
961 	case AUE_LCHOWN:
962 		if (ARG_IS_VALID(kar, ARG_UID)) {
963 			tok = au_to_arg32(2, "new file uid", ar->ar_arg_uid);
964 			kau_write(rec, tok);
965 		}
966 		if (ARG_IS_VALID(kar, ARG_GID)) {
967 			tok = au_to_arg32(3, "new file gid", ar->ar_arg_gid);
968 			kau_write(rec, tok);
969 		}
970 		UPATH1_VNODE1_TOKENS;
971 		break;
972 
973 	case AUE_EXCHANGEDATA:
974 		UPATH1_VNODE1_TOKENS;
975 		UPATH2_TOKENS;
976 		break;
977 
978 	case AUE_CLOSE:
979 		if (ARG_IS_VALID(kar, ARG_FD)) {
980 			tok = au_to_arg32(2, "fd", ar->ar_arg_fd);
981 			kau_write(rec, tok);
982 		}
983 		UPATH1_VNODE1_TOKENS;
984 		break;
985 
986 	case AUE_CORE:
987 		if (ARG_IS_VALID(kar, ARG_SIGNUM)) {
988 			tok = au_to_arg32(0, "signal", ar->ar_arg_signum);
989 			kau_write(rec, tok);
990 		}
991 		UPATH1_VNODE1_TOKENS;
992 		break;
993 
994 	case AUE_POSIX_SPAWN:
995 		if (ARG_IS_VALID(kar, ARG_PID)) {
996 			tok = au_to_arg32(0, "child PID", ar->ar_arg_pid);
997 			kau_write(rec, tok);
998 		}
999 		OS_FALLTHROUGH;
1000 
1001 	case AUE_EXECVE:
1002 		if (ARG_IS_VALID(kar, ARG_ARGV)) {
1003 			tok = au_to_exec_args(ar->ar_arg_argv,
1004 			    ar->ar_arg_argc);
1005 			kau_write(rec, tok);
1006 		}
1007 		if (ARG_IS_VALID(kar, ARG_ENVV)) {
1008 			tok = au_to_exec_env(ar->ar_arg_envv,
1009 			    ar->ar_arg_envc);
1010 			kau_write(rec, tok);
1011 		}
1012 		UPATH1_VNODE1_TOKENS;
1013 		VNODE2_PATH_TOKENS;
1014 		if (ARG_IS_VALID(kar, ARG_DATA)) {
1015 			tok = au_to_data(AUP_HEX, ar->ar_arg_data_type,
1016 			    ar->ar_arg_data_count, ar->ar_arg_data);
1017 			kau_write(rec, tok);
1018 		}
1019 		break;
1020 
1021 	case AUE_FCHMOD_EXTENDED:
1022 		EXTENDED_TOKENS(2);
1023 		FD_VNODE1_TOKENS;
1024 		break;
1025 
1026 	case AUE_FCHMOD:
1027 		if (ARG_IS_VALID(kar, ARG_MODE)) {
1028 			tok = au_to_arg32(2, "new file mode",
1029 			    ar->ar_arg_mode);
1030 			kau_write(rec, tok);
1031 		}
1032 		FD_VNODE1_TOKENS;
1033 		break;
1034 
1035 	case AUE_NFS_SVC:
1036 		tok = au_to_arg32(1, "request", ar->ar_arg_cmd);
1037 		kau_write(rec, tok);
1038 		if (ar->ar_valid_arg & (ARG_KPATH1 | ARG_UPATH1)) {
1039 			UPATH1_VNODE1_TOKENS;
1040 		}
1041 		break;
1042 
1043 	/*
1044 	 * XXXRW: Some of these need to handle non-vnode cases as well.
1045 	 */
1046 	case AUE_FSTAT_EXTENDED:
1047 	case AUE_FCHDIR:
1048 	case AUE_FPATHCONF:
1049 	case AUE_FSTAT:         /* XXX Need to handle sockets and shm */
1050 	case AUE_FSTATFS:
1051 	case AUE_FSYNC:
1052 	case AUE_FTRUNCATE:
1053 	case AUE_FUTIMES:
1054 	case AUE_GETDIRENTRIES:
1055 	case AUE_GETDIRENTRIESATTR:
1056 	case AUE_GETATTRLISTBULK:
1057 #if 0  /* XXXss new */
1058 	case AUE_POLL:
1059 #endif
1060 	case AUE_READ:
1061 	case AUE_READV:
1062 	case AUE_PREAD:
1063 	case AUE_PREADV:
1064 	case AUE_WRITE:
1065 	case AUE_WRITEV:
1066 	case AUE_PWRITE:
1067 	case AUE_PWRITEV:
1068 		FD_VNODE1_TOKENS;
1069 		break;
1070 
1071 	case AUE_FCHOWN:
1072 		if (ARG_IS_VALID(kar, ARG_UID)) {
1073 			tok = au_to_arg32(2, "new file uid", ar->ar_arg_uid);
1074 			kau_write(rec, tok);
1075 		}
1076 		if (ARG_IS_VALID(kar, ARG_GID)) {
1077 			tok = au_to_arg32(3, "new file gid", ar->ar_arg_gid);
1078 			kau_write(rec, tok);
1079 		}
1080 		FD_VNODE1_TOKENS;
1081 		break;
1082 
1083 	case AUE_FCNTL:
1084 		if (ARG_IS_VALID(kar, ARG_CMD)) {
1085 			audit_sys_fcntl(kar, rec);
1086 		}
1087 		FD_VNODE1_TOKENS;
1088 		break;
1089 
1090 	case AUE_FSCTL:
1091 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1092 			tok = au_to_arg32(4, "options", ar->ar_arg_value32);
1093 			kau_write(rec, tok);
1094 		}
1095 		if (ARG_IS_VALID(kar, ARG_CMD)) {
1096 			tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd);
1097 			kau_write(rec, tok);
1098 		}
1099 		UPATH1_VNODE1_TOKENS;
1100 		break;
1101 
1102 	case AUE_FFSCTL:
1103 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1104 			tok = au_to_arg32(4, "options", ar->ar_arg_value32);
1105 			kau_write(rec, tok);
1106 		}
1107 		if (ARG_IS_VALID(kar, ARG_CMD)) {
1108 			tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd);
1109 			kau_write(rec, tok);
1110 		}
1111 		FD_VNODE1_TOKENS;
1112 		break;
1113 
1114 
1115 	case AUE_FCHFLAGS:
1116 		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1117 			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1118 			kau_write(rec, tok);
1119 		}
1120 		FD_VNODE1_TOKENS;
1121 		break;
1122 
1123 	case AUE_FLOCK:
1124 		if (ARG_IS_VALID(kar, ARG_CMD)) {
1125 			tok = au_to_arg32(2, "operation", ar->ar_arg_cmd);
1126 			kau_write(rec, tok);
1127 		}
1128 		FD_VNODE1_TOKENS;
1129 		break;
1130 
1131 	case AUE_FORK:
1132 	case AUE_VFORK:
1133 		if (ARG_IS_VALID(kar, ARG_PID)) {
1134 			tok = au_to_arg32(0, "child PID", ar->ar_arg_pid);
1135 			kau_write(rec, tok);
1136 		}
1137 		break;
1138 
1139 	case AUE_GETLCID:
1140 		if (ARG_IS_VALID(kar, ARG_PID)) {
1141 			tok = au_to_arg32(1, "pid", (u_int32_t)ar->ar_arg_pid);
1142 			kau_write(rec, tok);
1143 		}
1144 		break;
1145 
1146 	case AUE_SETLCID:
1147 		if (ARG_IS_VALID(kar, ARG_PID)) {
1148 			tok = au_to_arg32(1, "pid", (u_int32_t)ar->ar_arg_pid);
1149 			kau_write(rec, tok);
1150 		}
1151 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1152 			tok = au_to_arg32(2, "lcid",
1153 			    (u_int32_t)ar->ar_arg_value32);
1154 			kau_write(rec, tok);
1155 		}
1156 		break;
1157 
1158 	case AUE_IOCTL:
1159 		if (ARG_IS_VALID(kar, ARG_CMD)) {
1160 			tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd);
1161 			kau_write(rec, tok);
1162 		}
1163 		if (ARG_IS_VALID(kar, ARG_VALUE64)) {
1164 			tok = au_to_arg64(2, "cmd", ar->ar_arg_value64);
1165 			kau_write(rec, tok);
1166 		}
1167 		if (ARG_IS_VALID(kar, ARG_ADDR64)) {
1168 			tok = au_to_arg64(3, "arg", ar->ar_arg_addr);
1169 			kau_write(rec, tok);
1170 		} else if (ARG_IS_VALID(kar, ARG_ADDR32)) {
1171 			tok = au_to_arg32(3, "arg",
1172 			    (u_int32_t)ar->ar_arg_addr);
1173 			kau_write(rec, tok);
1174 		}
1175 		if (ARG_IS_VALID(kar, ARG_VNODE1)) {
1176 			FD_VNODE1_TOKENS;
1177 		} else {
1178 			if (ARG_IS_VALID(kar, ARG_SOCKINFO)) {
1179 				tok = au_to_socket_ex(
1180 					ar->ar_arg_sockinfo.sai_domain,
1181 					ar->ar_arg_sockinfo.sai_type,
1182 					(struct sockaddr *)
1183 					&ar->ar_arg_sockinfo.sai_laddr,
1184 					(struct sockaddr *)
1185 					&ar->ar_arg_sockinfo.sai_faddr);
1186 				kau_write(rec, tok);
1187 			} else {
1188 				if (ARG_IS_VALID(kar, ARG_FD)) {
1189 					tok = au_to_arg32(1, "fd",
1190 					    ar->ar_arg_fd);
1191 					kau_write(rec, tok);
1192 				}
1193 			}
1194 		}
1195 		break;
1196 
1197 	case AUE_KILL:
1198 		if (ARG_IS_VALID(kar, ARG_SIGNUM)) {
1199 			tok = au_to_arg32(2, "signal", ar->ar_arg_signum);
1200 			kau_write(rec, tok);
1201 		}
1202 		PROCESS_PID_TOKENS(1);
1203 		break;
1204 
1205 	case AUE_LINK:
1206 	case AUE_RENAME:
1207 		UPATH1_VNODE1_TOKENS;
1208 		UPATH2_TOKENS;
1209 		KPATH2_TOKENS;
1210 		break;
1211 
1212 	case AUE_MKDIR_EXTENDED:
1213 	case AUE_CHMOD_EXTENDED:
1214 	case AUE_MKFIFO_EXTENDED:
1215 		EXTENDED_TOKENS(2);
1216 		UPATH1_VNODE1_TOKENS;
1217 		break;
1218 
1219 	case AUE_MKDIR:
1220 		if (ARG_IS_VALID(kar, ARG_MODE)) {
1221 			tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
1222 			kau_write(rec, tok);
1223 		}
1224 		UPATH1_VNODE1_TOKENS;
1225 		break;
1226 
1227 	case AUE_MKNOD:
1228 		if (ARG_IS_VALID(kar, ARG_MODE)) {
1229 			tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
1230 			kau_write(rec, tok);
1231 		}
1232 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1233 			tok = au_to_arg32(3, "dev", ar->ar_arg_value32);
1234 			kau_write(rec, tok);
1235 		}
1236 		UPATH1_VNODE1_TOKENS;
1237 		break;
1238 
1239 	case AUE_MMAP:
1240 	case AUE_MUNMAP:
1241 	case AUE_MPROTECT:
1242 	case AUE_MLOCK:
1243 	case AUE_MUNLOCK:
1244 	case AUE_MINHERIT:
1245 		if (ARG_IS_VALID(kar, ARG_ADDR64)) {
1246 			tok = au_to_arg64(1, "addr", ar->ar_arg_addr);
1247 			kau_write(rec, tok);
1248 		} else if (ARG_IS_VALID(kar, ARG_ADDR32)) {
1249 			tok = au_to_arg32(1, "addr",
1250 			    (u_int32_t)ar->ar_arg_addr);
1251 			kau_write(rec, tok);
1252 		}
1253 		if (ARG_IS_VALID(kar, ARG_LEN)) {
1254 			tok = au_to_arg64(2, "len", ar->ar_arg_len);
1255 			kau_write(rec, tok);
1256 		}
1257 		if (ar->ar_event == AUE_MMAP) {
1258 			FD_VNODE1_TOKENS;
1259 		}
1260 		if (ar->ar_event == AUE_MPROTECT) {
1261 			if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1262 				tok = au_to_arg32(3, "protection",
1263 				    ar->ar_arg_value32);
1264 				kau_write(rec, tok);
1265 			}
1266 		}
1267 		if (ar->ar_event == AUE_MINHERIT) {
1268 			if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1269 				tok = au_to_arg32(3, "inherit",
1270 				    ar->ar_arg_value32);
1271 				kau_write(rec, tok);
1272 			}
1273 		}
1274 		break;
1275 
1276 #if CONFIG_MACF
1277 	case AUE_MAC_MOUNT:
1278 		PROCESS_MAC_TOKENS;
1279 		OS_FALLTHROUGH;
1280 #endif
1281 	case AUE_MOUNT:
1282 		/* XXX Need to handle NFS mounts */
1283 		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1284 			tok = au_to_arg32(3, "flags", ar->ar_arg_fflags);
1285 			kau_write(rec, tok);
1286 		}
1287 		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1288 			tok = au_to_text(ar->ar_arg_text);
1289 			kau_write(rec, tok);
1290 		}
1291 		OS_FALLTHROUGH;
1292 
1293 	case AUE_UMOUNT:
1294 	case AUE_UNMOUNT:
1295 		UPATH1_VNODE1_TOKENS;
1296 		break;
1297 	case AUE_FMOUNT:
1298 		if (ARG_IS_VALID(kar, ARG_FD)) {
1299 			tok = au_to_arg32(2, "dir fd", ar->ar_arg_fd);
1300 			kau_write(rec, tok);
1301 		}
1302 		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1303 			tok = au_to_arg32(3, "flags", ar->ar_arg_fflags);
1304 			kau_write(rec, tok);
1305 		}
1306 		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1307 			tok = au_to_text(ar->ar_arg_text);
1308 			kau_write(rec, tok);
1309 		}
1310 		break;
1311 	case AUE_FUNMOUNT:
1312 		if (ARG_IS_VALID(kar, ARG_FD)) {
1313 			tok = au_to_arg32(2, "dir fd", ar->ar_arg_fd);
1314 			kau_write(rec, tok);
1315 		}
1316 		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1317 			tok = au_to_arg32(3, "flags", ar->ar_arg_fflags);
1318 			kau_write(rec, tok);
1319 		}
1320 		break;
1321 
1322 	case AUE_MSGCTL:
1323 		ar->ar_event = audit_msgctl_to_event(ar->ar_arg_svipc_cmd);
1324 		OS_FALLTHROUGH;
1325 
1326 	case AUE_MSGRCV:
1327 	case AUE_MSGSND:
1328 		tok = au_to_arg32(1, "msg ID", ar->ar_arg_svipc_id);
1329 		kau_write(rec, tok);
1330 		if (ar->ar_errno != EINVAL) {
1331 			tok = au_to_ipc(AT_IPC_MSG, ar->ar_arg_svipc_id);
1332 			kau_write(rec, tok);
1333 		}
1334 		break;
1335 
1336 	case AUE_MSGGET:
1337 		if (ar->ar_errno == 0) {
1338 			if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1339 				tok = au_to_ipc(AT_IPC_MSG,
1340 				    ar->ar_arg_svipc_id);
1341 				kau_write(rec, tok);
1342 			}
1343 		}
1344 		break;
1345 
1346 	case AUE_OPEN:
1347 	case AUE_OPEN_R:
1348 	case AUE_OPEN_RT:
1349 	case AUE_OPEN_RW:
1350 	case AUE_OPEN_RWT:
1351 	case AUE_OPEN_W:
1352 	case AUE_OPEN_WT:
1353 		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1354 			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1355 			kau_write(rec, tok);
1356 		}
1357 		UPATH1_VNODE1_TOKENS;
1358 		break;
1359 
1360 	case AUE_OPEN_RC:
1361 	case AUE_OPEN_RTC:
1362 	case AUE_OPEN_RWC:
1363 	case AUE_OPEN_RWTC:
1364 	case AUE_OPEN_WC:
1365 	case AUE_OPEN_WTC:
1366 		if (ARG_IS_VALID(kar, ARG_MODE)) {
1367 			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1368 			kau_write(rec, tok);
1369 		}
1370 		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1371 			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1372 			kau_write(rec, tok);
1373 		}
1374 		UPATH1_VNODE1_TOKENS;
1375 		break;
1376 
1377 	case AUE_OPEN_EXTENDED:
1378 	case AUE_OPEN_EXTENDED_R:
1379 	case AUE_OPEN_EXTENDED_RT:
1380 	case AUE_OPEN_EXTENDED_RW:
1381 	case AUE_OPEN_EXTENDED_RWT:
1382 	case AUE_OPEN_EXTENDED_W:
1383 	case AUE_OPEN_EXTENDED_WT:
1384 		EXTENDED_TOKENS(3);
1385 		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1386 			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1387 			kau_write(rec, tok);
1388 		}
1389 		UPATH1_VNODE1_TOKENS;
1390 		break;
1391 
1392 	case AUE_OPEN_EXTENDED_RC:
1393 	case AUE_OPEN_EXTENDED_RTC:
1394 	case AUE_OPEN_EXTENDED_RWC:
1395 	case AUE_OPEN_EXTENDED_RWTC:
1396 	case AUE_OPEN_EXTENDED_WC:
1397 	case AUE_OPEN_EXTENDED_WTC:
1398 		EXTENDED_TOKENS(3);
1399 		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1400 			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1401 			kau_write(rec, tok);
1402 		}
1403 		UPATH1_VNODE1_TOKENS;
1404 		break;
1405 
1406 	case AUE_OPENAT:
1407 	case AUE_OPENAT_R:
1408 	case AUE_OPENAT_RT:
1409 	case AUE_OPENAT_RW:
1410 	case AUE_OPENAT_RWT:
1411 	case AUE_OPENAT_W:
1412 	case AUE_OPENAT_WT:
1413 		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1414 			tok = au_to_arg32(3, "flags", ar->ar_arg_fflags);
1415 			kau_write(rec, tok);
1416 		}
1417 		if (ARG_IS_VALID(kar, ARG_FD)) {
1418 			tok = au_to_arg32(1, "dir fd", ar->ar_arg_fd);
1419 			kau_write(rec, tok);
1420 		}
1421 		UPATH1_VNODE1_TOKENS;
1422 		break;
1423 
1424 	case AUE_OPENAT_RC:
1425 	case AUE_OPENAT_RTC:
1426 	case AUE_OPENAT_RWC:
1427 	case AUE_OPENAT_RWTC:
1428 	case AUE_OPENAT_WC:
1429 	case AUE_OPENAT_WTC:
1430 		if (ARG_IS_VALID(kar, ARG_MODE)) {
1431 			tok = au_to_arg32(4, "mode", ar->ar_arg_mode);
1432 			kau_write(rec, tok);
1433 		}
1434 		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1435 			tok = au_to_arg32(3, "flags", ar->ar_arg_fflags);
1436 			kau_write(rec, tok);
1437 		}
1438 		if (ARG_IS_VALID(kar, ARG_FD)) {
1439 			tok = au_to_arg32(1, "dir fd", ar->ar_arg_fd);
1440 			kau_write(rec, tok);
1441 		}
1442 		UPATH1_VNODE1_TOKENS;
1443 		break;
1444 
1445 	case AUE_OPENBYID:
1446 	case AUE_OPENBYID_R:
1447 	case AUE_OPENBYID_RT:
1448 	case AUE_OPENBYID_RW:
1449 	case AUE_OPENBYID_RWT:
1450 	case AUE_OPENBYID_W:
1451 	case AUE_OPENBYID_WT:
1452 		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1453 			tok = au_to_arg32(3, "flags", ar->ar_arg_fflags);
1454 			kau_write(rec, tok);
1455 		}
1456 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1457 			tok = au_to_arg32(1, "volfsid", ar->ar_arg_value32);
1458 			kau_write(rec, tok);
1459 		}
1460 		if (ARG_IS_VALID(kar, ARG_VALUE64)) {
1461 			tok = au_to_arg64(2, "objid", ar->ar_arg_value64);
1462 			kau_write(rec, tok);
1463 		}
1464 		break;
1465 
1466 	case AUE_RENAMEAT:
1467 	case AUE_FACCESSAT:
1468 	case AUE_FCHMODAT:
1469 	case AUE_FCHOWNAT:
1470 	case AUE_FSTATAT:
1471 	case AUE_LINKAT:
1472 	case AUE_UNLINKAT:
1473 	case AUE_READLINKAT:
1474 	case AUE_SYMLINKAT:
1475 	case AUE_MKDIRAT:
1476 	case AUE_GETATTRLISTAT:
1477 	case AUE_SETATTRLISTAT:
1478 	case AUE_MKFIFOAT:
1479 	case AUE_MKNODAT:
1480 		if (ARG_IS_VALID(kar, ARG_FD)) {
1481 			tok = au_to_arg32(1, "dir fd", ar->ar_arg_fd);
1482 			kau_write(rec, tok);
1483 		}
1484 		UPATH1_VNODE1_TOKENS;
1485 		break;
1486 
1487 	case AUE_CLONEFILEAT:
1488 		if (ARG_IS_VALID(kar, ARG_FD)) {
1489 			tok = au_to_arg32(1, "src dir fd", ar->ar_arg_fd);
1490 			kau_write(rec, tok);
1491 		}
1492 		UPATH1_VNODE1_TOKENS;
1493 		if (ARG_IS_VALID(kar, ARG_FD2)) {
1494 			tok = au_to_arg32(1, "dst dir fd", ar->ar_arg_fd2);
1495 			kau_write(rec, tok);
1496 		}
1497 		UPATH2_TOKENS;
1498 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1499 			tok = au_to_arg32(1, "flags", ar->ar_arg_value32);
1500 			kau_write(rec, tok);
1501 		}
1502 		break;
1503 
1504 	case AUE_FCLONEFILEAT:
1505 		FD_VNODE1_TOKENS;
1506 		if (ARG_IS_VALID(kar, ARG_FD2)) {
1507 			tok = au_to_arg32(1, "dst dir fd", ar->ar_arg_fd2);
1508 			kau_write(rec, tok);
1509 		}
1510 		UPATH2_TOKENS;
1511 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1512 			tok = au_to_arg32(1, "flags", ar->ar_arg_value32);
1513 			kau_write(rec, tok);
1514 		}
1515 		break;
1516 
1517 	case AUE_PTRACE:
1518 		if (ARG_IS_VALID(kar, ARG_CMD)) {
1519 			tok = au_to_arg32(1, "request", ar->ar_arg_cmd);
1520 			kau_write(rec, tok);
1521 		}
1522 		if (ARG_IS_VALID(kar, ARG_ADDR64)) {
1523 			tok = au_to_arg64(3, "addr", ar->ar_arg_addr);
1524 			kau_write(rec, tok);
1525 		} else if (ARG_IS_VALID(kar, ARG_ADDR32)) {
1526 			tok = au_to_arg32(3, "addr",
1527 			    (u_int32_t)ar->ar_arg_addr);
1528 			kau_write(rec, tok);
1529 		}
1530 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1531 			tok = au_to_arg32(4, "data", ar->ar_arg_value32);
1532 			kau_write(rec, tok);
1533 		}
1534 		PROCESS_PID_TOKENS(2);
1535 		break;
1536 
1537 	case AUE_QUOTACTL:
1538 		if (ARG_IS_VALID(kar, ARG_CMD)) {
1539 			tok = au_to_arg32(2, "command", ar->ar_arg_cmd);
1540 			kau_write(rec, tok);
1541 		}
1542 		if (ARG_IS_VALID(kar, ARG_UID)) {
1543 			tok = au_to_arg32(3, "uid", ar->ar_arg_uid);
1544 			kau_write(rec, tok);
1545 		}
1546 		UPATH1_VNODE1_TOKENS;
1547 		break;
1548 
1549 	case AUE_REBOOT:
1550 		if (ARG_IS_VALID(kar, ARG_CMD)) {
1551 			tok = au_to_arg32(1, "howto", ar->ar_arg_cmd);
1552 			kau_write(rec, tok);
1553 		}
1554 		break;
1555 
1556 	case AUE_SEMCTL:
1557 		ar->ar_event = audit_semctl_to_event(ar->ar_arg_svipc_cmd);
1558 		OS_FALLTHROUGH;
1559 
1560 	case AUE_SEMOP:
1561 		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1562 			tok = au_to_arg32(1, "sem ID", ar->ar_arg_svipc_id);
1563 			kau_write(rec, tok);
1564 			if (ar->ar_errno != EINVAL) {
1565 				tok = au_to_ipc(AT_IPC_SEM,
1566 				    ar->ar_arg_svipc_id);
1567 				kau_write(rec, tok);
1568 			}
1569 		}
1570 		break;
1571 
1572 	case AUE_SEMGET:
1573 		if (ar->ar_errno == 0) {
1574 			if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1575 				tok = au_to_ipc(AT_IPC_SEM,
1576 				    ar->ar_arg_svipc_id);
1577 				kau_write(rec, tok);
1578 			}
1579 		}
1580 		break;
1581 
1582 	case AUE_SETEGID:
1583 		if (ARG_IS_VALID(kar, ARG_EGID)) {
1584 			tok = au_to_arg32(1, "gid", ar->ar_arg_egid);
1585 			kau_write(rec, tok);
1586 		}
1587 		break;
1588 
1589 	case AUE_SETEUID:
1590 		if (ARG_IS_VALID(kar, ARG_EUID)) {
1591 			tok = au_to_arg32(1, "uid", ar->ar_arg_euid);
1592 			kau_write(rec, tok);
1593 		}
1594 		break;
1595 
1596 	case AUE_SETREGID:
1597 		if (ARG_IS_VALID(kar, ARG_RGID)) {
1598 			tok = au_to_arg32(1, "rgid", ar->ar_arg_rgid);
1599 			kau_write(rec, tok);
1600 		}
1601 		if (ARG_IS_VALID(kar, ARG_EGID)) {
1602 			tok = au_to_arg32(2, "egid", ar->ar_arg_egid);
1603 			kau_write(rec, tok);
1604 		}
1605 		break;
1606 
1607 	case AUE_SETREUID:
1608 		if (ARG_IS_VALID(kar, ARG_RUID)) {
1609 			tok = au_to_arg32(1, "ruid", ar->ar_arg_ruid);
1610 			kau_write(rec, tok);
1611 		}
1612 		if (ARG_IS_VALID(kar, ARG_EUID)) {
1613 			tok = au_to_arg32(2, "euid", ar->ar_arg_euid);
1614 			kau_write(rec, tok);
1615 		}
1616 		break;
1617 
1618 	case AUE_SETGID:
1619 		if (ARG_IS_VALID(kar, ARG_GID)) {
1620 			tok = au_to_arg32(1, "gid", ar->ar_arg_gid);
1621 			kau_write(rec, tok);
1622 		}
1623 		break;
1624 
1625 	case AUE_SETUID:
1626 		if (ARG_IS_VALID(kar, ARG_UID)) {
1627 			tok = au_to_arg32(1, "uid", ar->ar_arg_uid);
1628 			kau_write(rec, tok);
1629 		}
1630 		break;
1631 
1632 	case AUE_SETGROUPS:
1633 		if (ARG_IS_VALID(kar, ARG_GROUPSET)) {
1634 			for (uctr = 0; uctr < ar->ar_arg_groups.gidset_size;
1635 			    uctr++) {
1636 				tok = au_to_arg32(1, "setgroups",
1637 				    ar->ar_arg_groups.gidset[uctr]);
1638 				kau_write(rec, tok);
1639 			}
1640 		}
1641 		break;
1642 
1643 	case AUE_SETLOGIN:
1644 		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1645 			tok = au_to_text(ar->ar_arg_text);
1646 			kau_write(rec, tok);
1647 		}
1648 		break;
1649 
1650 	case AUE_SETPRIORITY:
1651 		if (ARG_IS_VALID(kar, ARG_CMD)) {
1652 			tok = au_to_arg32(1, "which", ar->ar_arg_cmd);
1653 			kau_write(rec, tok);
1654 		}
1655 		if (ARG_IS_VALID(kar, ARG_UID)) {
1656 			tok = au_to_arg32(2, "who", ar->ar_arg_uid);
1657 			kau_write(rec, tok);
1658 		}
1659 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1660 			tok = au_to_arg32(2, "priority", ar->ar_arg_value32);
1661 			kau_write(rec, tok);
1662 		}
1663 		break;
1664 
1665 	case AUE_SETPRIVEXEC:
1666 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1667 			tok = au_to_arg32(1, "flag", ar->ar_arg_value32);
1668 			kau_write(rec, tok);
1669 		}
1670 		break;
1671 
1672 	/* AUE_SHMAT, AUE_SHMCTL, AUE_SHMDT and AUE_SHMGET are SysV IPC */
1673 	case AUE_SHMAT:
1674 		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1675 			tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id);
1676 			kau_write(rec, tok);
1677 			/* XXXAUDIT: Does having the ipc token make sense? */
1678 			tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
1679 			kau_write(rec, tok);
1680 		}
1681 		if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) {
1682 			tok = au_to_arg64(2, "shmaddr", ar->ar_arg_svipc_addr);
1683 			kau_write(rec, tok);
1684 		}
1685 		if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) {
1686 			tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
1687 			kau_write(rec, tok);
1688 		}
1689 		break;
1690 
1691 	case AUE_SHMCTL:
1692 		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1693 			tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id);
1694 			kau_write(rec, tok);
1695 			/* XXXAUDIT: Does having the ipc token make sense? */
1696 			tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
1697 			kau_write(rec, tok);
1698 		}
1699 		switch (ar->ar_arg_svipc_cmd) {
1700 		case IPC_STAT:
1701 			ar->ar_event = AUE_SHMCTL_STAT;
1702 			break;
1703 		case IPC_RMID:
1704 			ar->ar_event = AUE_SHMCTL_RMID;
1705 			break;
1706 		case IPC_SET:
1707 			ar->ar_event = AUE_SHMCTL_SET;
1708 			if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) {
1709 				tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
1710 				kau_write(rec, tok);
1711 			}
1712 			break;
1713 		default:
1714 			break;  /* We will audit a bad command */
1715 		}
1716 		break;
1717 
1718 	case AUE_SHMDT:
1719 		if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) {
1720 			tok = au_to_arg64(1, "shmaddr",
1721 			    (int)(uintptr_t)ar->ar_arg_svipc_addr);
1722 			kau_write(rec, tok);
1723 		}
1724 		break;
1725 
1726 	case AUE_SHMGET:
1727 		/* This is unusual; the return value is in an argument token */
1728 		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1729 			tok = au_to_arg32(0, "shmid", ar->ar_arg_svipc_id);
1730 			kau_write(rec, tok);
1731 			tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
1732 			kau_write(rec, tok);
1733 		}
1734 		if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) {
1735 			tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
1736 			kau_write(rec, tok);
1737 		}
1738 		break;
1739 
1740 	/* AUE_SHMOPEN, AUE_SHMUNLINK, AUE_SEMOPEN, AUE_SEMCLOSE
1741 	 * and AUE_SEMUNLINK are Posix IPC */
1742 	case AUE_SHMOPEN:
1743 		if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) {
1744 			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1745 			kau_write(rec, tok);
1746 		}
1747 		if (ARG_IS_VALID(kar, ARG_MODE)) {
1748 			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1749 			kau_write(rec, tok);
1750 		}
1751 		OS_FALLTHROUGH;
1752 
1753 	case AUE_SHMUNLINK:
1754 		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1755 			tok = au_to_text(ar->ar_arg_text);
1756 			kau_write(rec, tok);
1757 		}
1758 		if (ARG_IS_VALID(kar, ARG_POSIX_IPC_PERM)) {
1759 			struct ipc_perm perm;
1760 
1761 			perm.uid = ar->ar_arg_pipc_perm.pipc_uid;
1762 			perm.gid = ar->ar_arg_pipc_perm.pipc_gid;
1763 			perm.cuid = ar->ar_arg_pipc_perm.pipc_uid;
1764 			perm.cgid = ar->ar_arg_pipc_perm.pipc_gid;
1765 			perm.mode = ar->ar_arg_pipc_perm.pipc_mode;
1766 			perm._seq = 0;
1767 			perm._key = 0;
1768 			tok = au_to_ipc_perm(&perm);
1769 			kau_write(rec, tok);
1770 		}
1771 		break;
1772 
1773 	case AUE_SEMOPEN:
1774 		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1775 			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1776 			kau_write(rec, tok);
1777 		}
1778 		if (ARG_IS_VALID(kar, ARG_MODE)) {
1779 			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1780 			kau_write(rec, tok);
1781 		}
1782 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1783 			tok = au_to_arg32(4, "value", ar->ar_arg_value32);
1784 			kau_write(rec, tok);
1785 		}
1786 		OS_FALLTHROUGH;
1787 
1788 	case AUE_SEMUNLINK:
1789 		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1790 			tok = au_to_text(ar->ar_arg_text);
1791 			kau_write(rec, tok);
1792 		}
1793 		if (ARG_IS_VALID(kar, ARG_POSIX_IPC_PERM)) {
1794 			struct ipc_perm perm;
1795 
1796 			perm.uid = ar->ar_arg_pipc_perm.pipc_uid;
1797 			perm.gid = ar->ar_arg_pipc_perm.pipc_gid;
1798 			perm.cuid = ar->ar_arg_pipc_perm.pipc_uid;
1799 			perm.cgid = ar->ar_arg_pipc_perm.pipc_gid;
1800 			perm.mode = ar->ar_arg_pipc_perm.pipc_mode;
1801 			perm._seq = 0;
1802 			perm._key = 0;
1803 			tok = au_to_ipc_perm(&perm);
1804 			kau_write(rec, tok);
1805 		}
1806 		break;
1807 
1808 	case AUE_SEMCLOSE:
1809 		if (ARG_IS_VALID(kar, ARG_FD)) {
1810 			tok = au_to_arg32(1, "sem", ar->ar_arg_fd);
1811 			kau_write(rec, tok);
1812 		}
1813 		break;
1814 
1815 	case AUE_SYMLINK:
1816 		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1817 			tok = au_to_text(ar->ar_arg_text);
1818 			kau_write(rec, tok);
1819 		}
1820 		UPATH1_VNODE1_TOKENS;
1821 		break;
1822 
1823 	case AUE_SYSCTL:
1824 	case AUE_SYSCTL_NONADMIN:
1825 		if (ARG_IS_VALID(kar, ARG_CTLNAME | ARG_LEN)) {
1826 			for (ctr = 0; ctr < (int)ar->ar_arg_len; ctr++) {
1827 				tok = au_to_arg32(1, "name",
1828 				    ar->ar_arg_ctlname[ctr]);
1829 				kau_write(rec, tok);
1830 			}
1831 		}
1832 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1833 			tok = au_to_arg32(5, "newval", ar->ar_arg_value32);
1834 			kau_write(rec, tok);
1835 		}
1836 		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1837 			tok = au_to_text(ar->ar_arg_text);
1838 			kau_write(rec, tok);
1839 		}
1840 		break;
1841 
1842 	case AUE_UMASK_EXTENDED:
1843 		/* ACL data */
1844 		if (ARG_IS_VALID(kar, ARG_OPAQUE)) {
1845 			tok = au_to_opaque(ar->ar_arg_opaque,
1846 			    ar->ar_arg_opq_size);
1847 			kau_write(rec, tok);
1848 		}
1849 		OS_FALLTHROUGH;
1850 
1851 	case AUE_UMASK:
1852 		if (ARG_IS_VALID(kar, ARG_MASK)) {
1853 			tok = au_to_arg32(1, "new mask", ar->ar_arg_mask);
1854 			kau_write(rec, tok);
1855 		}
1856 		tok = au_to_arg32(0, "prev mask", ar->ar_retval);
1857 		kau_write(rec, tok);
1858 		break;
1859 
1860 	case AUE_WAIT4:
1861 #if 0 /* XXXss - new  */
1862 	case AUE_WAITID:
1863 #endif
1864 		if (ARG_IS_VALID(kar, ARG_PID)) {
1865 			tok = au_to_arg32(0, "pid", ar->ar_arg_pid);
1866 			kau_write(rec, tok);
1867 		}
1868 		break;
1869 
1870 	case AUE_FSGETPATH_EXTENDED:
1871 	case AUE_FSGETPATH:
1872 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1873 			tok = au_to_arg32(3, "volfsid", ar->ar_arg_value32);
1874 			kau_write(rec, tok);
1875 		}
1876 		if (ARG_IS_VALID(kar, ARG_VALUE64)) {
1877 			tok = au_to_arg64(4, "objid", ar->ar_arg_value64);
1878 			kau_write(rec, tok);
1879 		}
1880 		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1881 			tok = au_to_text(ar->ar_arg_text);
1882 			kau_write(rec, tok);
1883 		}
1884 		break;
1885 
1886 	case AUE_SESSION_START:
1887 	case AUE_SESSION_UPDATE:
1888 	case AUE_SESSION_END:
1889 	case AUE_SESSION_CLOSE:
1890 		if (ARG_IS_VALID(kar, ARG_VALUE64)) {
1891 			tok = au_to_arg64(1, "sflags", ar->ar_arg_value64);
1892 			kau_write(rec, tok);
1893 		}
1894 		if (ARG_IS_VALID(kar, ARG_AMASK)) {
1895 			tok = au_to_arg32(2, "am_success",
1896 			    ar->ar_arg_amask.am_success);
1897 			kau_write(rec, tok);
1898 			tok = au_to_arg32(3, "am_failure",
1899 			    ar->ar_arg_amask.am_failure);
1900 			kau_write(rec, tok);
1901 		}
1902 		break;
1903 
1904 	/************************
1905 	* Mach system calls    *
1906 	************************/
1907 	case AUE_INITPROCESS:
1908 		break;
1909 
1910 	case AUE_PIDFORTASK:
1911 		if (ARG_IS_VALID(kar, ARG_MACHPORT1)) {
1912 			tok = au_to_arg32(1, "port",
1913 			    (u_int32_t)ar->ar_arg_mach_port1);
1914 			kau_write(rec, tok);
1915 		}
1916 		if (ARG_IS_VALID(kar, ARG_PID)) {
1917 			tok = au_to_arg32(2, "pid", (u_int32_t)ar->ar_arg_pid);
1918 			kau_write(rec, tok);
1919 		}
1920 		break;
1921 
1922 	case AUE_TASKFORPID:
1923 	case AUE_TASKNAMEFORPID:
1924 		if (ARG_IS_VALID(kar, ARG_MACHPORT1)) {
1925 			tok = au_to_arg32(1, "target port",
1926 			    (u_int32_t)ar->ar_arg_mach_port1);
1927 			kau_write(rec, tok);
1928 		}
1929 		if (ARG_IS_VALID(kar, ARG_MACHPORT2)) {
1930 			tok = au_to_arg32(3, "task port",
1931 			    (u_int32_t)ar->ar_arg_mach_port2);
1932 			kau_write(rec, tok);
1933 		}
1934 		PROCESS_PID_TOKENS(2);
1935 		break;
1936 
1937 	case AUE_SWAPON:
1938 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1939 			tok = au_to_arg32(4, "priority",
1940 			    (u_int32_t)ar->ar_arg_value32);
1941 			kau_write(rec, tok);
1942 		}
1943 		UPATH1_VNODE1_TOKENS;
1944 		break;
1945 
1946 	case AUE_SWAPOFF:
1947 		UPATH1_VNODE1_TOKENS;
1948 		break;
1949 
1950 	case AUE_MAPFD:
1951 		if (ARG_IS_VALID(kar, ARG_ADDR64)) {
1952 			tok = au_to_arg64(3, "va", ar->ar_arg_addr);
1953 			kau_write(rec, tok);
1954 		} else if (ARG_IS_VALID(kar, ARG_ADDR32)) {
1955 			tok = au_to_arg32(3, "va",
1956 			    (u_int32_t)ar->ar_arg_addr);
1957 			kau_write(rec, tok);
1958 		}
1959 		FD_VNODE1_TOKENS;
1960 		break;
1961 
1962 #if CONFIG_MACF
1963 	case AUE_MAC_GET_FILE:
1964 	case AUE_MAC_SET_FILE:
1965 	case AUE_MAC_GET_LINK:
1966 	case AUE_MAC_SET_LINK:
1967 	case AUE_MAC_GET_MOUNT:
1968 		UPATH1_VNODE1_TOKENS;
1969 		PROCESS_MAC_TOKENS;
1970 		break;
1971 
1972 	case AUE_MAC_GET_FD:
1973 	case AUE_MAC_SET_FD:
1974 		FD_VNODE1_TOKENS;
1975 		PROCESS_MAC_TOKENS;
1976 		break;
1977 
1978 	case AUE_MAC_SYSCALL:
1979 		PROCESS_MAC_TOKENS;
1980 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1981 			tok = au_to_arg32(3, "call", ar->ar_arg_value32);
1982 			kau_write(rec, tok);
1983 		}
1984 		break;
1985 
1986 	case AUE_MAC_EXECVE:
1987 		UPATH1_VNODE1_TOKENS;
1988 		PROCESS_MAC_TOKENS;
1989 		break;
1990 
1991 	case AUE_MAC_GET_PID:
1992 		if (ARG_IS_VALID(kar, ARG_PID)) {
1993 			tok = au_to_arg32(1, "pid", (u_int32_t)ar->ar_arg_pid);
1994 			kau_write(rec, tok);
1995 		}
1996 		PROCESS_MAC_TOKENS;
1997 		break;
1998 
1999 	case AUE_MAC_GET_LCID:
2000 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
2001 			tok = au_to_arg32(1, "lcid",
2002 			    (u_int32_t)ar->ar_arg_value32);
2003 			kau_write(rec, tok);
2004 		}
2005 		PROCESS_MAC_TOKENS;
2006 		break;
2007 
2008 	case AUE_MAC_GET_PROC:
2009 	case AUE_MAC_SET_PROC:
2010 		PROCESS_MAC_TOKENS;
2011 		break;
2012 #endif
2013 	case AUE_NULL:
2014 	default:
2015 #if DIAGNOSTIC
2016 		printf("BSM conversion requested for unknown event %d\n",
2017 		    ar->ar_event);
2018 #endif
2019 
2020 		/*
2021 		 * Write the subject token so it is properly freed here.
2022 		 */
2023 		kau_write(rec, subj_tok);
2024 		kau_free(rec);
2025 		return BSM_NOAUDIT;
2026 	}
2027 
2028 #if CONFIG_MACF
2029 	if (NULL != ar->ar_mac_records) {
2030 		/* Convert the audit data from the MAC policies */
2031 		struct mac_audit_record *mar;
2032 
2033 		LIST_FOREACH(mar, ar->ar_mac_records, records) {
2034 			switch (mar->type) {
2035 			case MAC_AUDIT_DATA_TYPE:
2036 				tok = au_to_data(AUP_BINARY, AUR_BYTE,
2037 				    mar->length,
2038 				    (const char *)mar->data);
2039 				break;
2040 			case MAC_AUDIT_TEXT_TYPE:
2041 				tok = au_to_text((char*) mar->data);
2042 				break;
2043 			default:
2044 				/*
2045 				 * XXX: we can either continue,
2046 				 * skipping this particular entry,
2047 				 * or we can pre-verify the list and
2048 				 * abort before writing any records
2049 				 */
2050 				printf("kaudit_to_bsm(): "
2051 				    "BSM conversion requested for"
2052 				    "unknown mac_audit data type %d\n",
2053 				    mar->type);
2054 			}
2055 
2056 			kau_write(rec, tok);
2057 		}
2058 	}
2059 #endif
2060 
2061 	kau_write(rec, subj_tok);
2062 
2063 #if CONFIG_MACF
2064 	if (ar->ar_cred_mac_labels != NULL &&
2065 	    strlen(ar->ar_cred_mac_labels) != 0) {
2066 		tok = au_to_text(ar->ar_cred_mac_labels);
2067 		kau_write(rec, tok);
2068 	}
2069 #endif
2070 
2071 	tok = au_to_return32(au_errno_to_bsm(ar->ar_errno), ar->ar_retval);
2072 	kau_write(rec, tok);  /* Every record gets a return token */
2073 
2074 	if (ARG_IS_VALID(kar, ARG_IDENTITY)) {
2075 		struct au_identity_info *id = &ar->ar_arg_identity;
2076 		tok = au_to_identity(id->signer_type, id->signing_id,
2077 		    id->signing_id_trunc, id->team_id, id->team_id_trunc,
2078 		    id->cdhash, id->cdhash_len);
2079 		kau_write(rec, tok);
2080 	}
2081 
2082 	rv = kau_close(rec, &ar->ar_endtime, ar->ar_event);
2083 	if (rv != 0) {
2084 		kau_free(rec);
2085 		return BSM_FAILURE;
2086 	}
2087 
2088 	*pau = rec;
2089 	return BSM_SUCCESS;
2090 }
2091 
2092 /*
2093  * Verify that a record is a valid BSM record. Return 1 if the
2094  * record is good, 0 otherwise.
2095  */
2096 int
bsm_rec_verify(void * rec,int length,boolean_t kern_events_allowed)2097 bsm_rec_verify(void *rec, int length, boolean_t kern_events_allowed)
2098 {
2099 	/* Used to partially deserialize the buffer */
2100 	struct hdr_tok_partial *hdr;
2101 	struct trl_tok_partial *trl;
2102 
2103 	/* A record requires a complete header and trailer token */
2104 	if (length < (AUDIT_HEADER_SIZE + AUDIT_TRAILER_SIZE)) {
2105 		return 0;
2106 	}
2107 
2108 	hdr = (struct hdr_tok_partial*)rec;
2109 
2110 	/* Ensure the provided length matches what the record shows */
2111 	if ((uint32_t)length != ntohl(hdr->len)) {
2112 		return 0;
2113 	}
2114 
2115 	trl = (struct trl_tok_partial*)((uintptr_t)rec + (length - AUDIT_TRAILER_SIZE));
2116 
2117 	/* Ensure the buffer contains what look like header and trailer tokens */
2118 	if (((hdr->type != AUT_HEADER32) && (hdr->type != AUT_HEADER32_EX) &&
2119 	    (hdr->type != AUT_HEADER64) && (hdr->type != AUT_HEADER64_EX)) ||
2120 	    (trl->type != AUT_TRAILER)) {
2121 		return 0;
2122 	}
2123 
2124 	/* Ensure the header and trailer agree on the length */
2125 	if (hdr->len != trl->len) {
2126 		return 0;
2127 	}
2128 
2129 	/* Ensure the trailer token has a proper magic value */
2130 	if (ntohs(trl->magic) != AUT_TRAILER_MAGIC) {
2131 		return 0;
2132 	}
2133 
2134 	if (!kern_events_allowed && AUE_IS_A_KEVENT(ntohs(hdr->e_type))) {
2135 		return 0;
2136 	}
2137 
2138 	return 1;
2139 }
2140 #endif /* CONFIG_AUDIT */
2141