xref: /xnu-8796.101.5/bsd/security/audit/audit_bsm.c (revision aca3beaa3dfbd42498b42c5e5ce20a938e6554e5) !
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 
1312 	case AUE_MSGCTL:
1313 		ar->ar_event = audit_msgctl_to_event(ar->ar_arg_svipc_cmd);
1314 		OS_FALLTHROUGH;
1315 
1316 	case AUE_MSGRCV:
1317 	case AUE_MSGSND:
1318 		tok = au_to_arg32(1, "msg ID", ar->ar_arg_svipc_id);
1319 		kau_write(rec, tok);
1320 		if (ar->ar_errno != EINVAL) {
1321 			tok = au_to_ipc(AT_IPC_MSG, ar->ar_arg_svipc_id);
1322 			kau_write(rec, tok);
1323 		}
1324 		break;
1325 
1326 	case AUE_MSGGET:
1327 		if (ar->ar_errno == 0) {
1328 			if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1329 				tok = au_to_ipc(AT_IPC_MSG,
1330 				    ar->ar_arg_svipc_id);
1331 				kau_write(rec, tok);
1332 			}
1333 		}
1334 		break;
1335 
1336 	case AUE_OPEN:
1337 	case AUE_OPEN_R:
1338 	case AUE_OPEN_RT:
1339 	case AUE_OPEN_RW:
1340 	case AUE_OPEN_RWT:
1341 	case AUE_OPEN_W:
1342 	case AUE_OPEN_WT:
1343 		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1344 			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1345 			kau_write(rec, tok);
1346 		}
1347 		UPATH1_VNODE1_TOKENS;
1348 		break;
1349 
1350 	case AUE_OPEN_RC:
1351 	case AUE_OPEN_RTC:
1352 	case AUE_OPEN_RWC:
1353 	case AUE_OPEN_RWTC:
1354 	case AUE_OPEN_WC:
1355 	case AUE_OPEN_WTC:
1356 		if (ARG_IS_VALID(kar, ARG_MODE)) {
1357 			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1358 			kau_write(rec, tok);
1359 		}
1360 		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1361 			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1362 			kau_write(rec, tok);
1363 		}
1364 		UPATH1_VNODE1_TOKENS;
1365 		break;
1366 
1367 	case AUE_OPEN_EXTENDED:
1368 	case AUE_OPEN_EXTENDED_R:
1369 	case AUE_OPEN_EXTENDED_RT:
1370 	case AUE_OPEN_EXTENDED_RW:
1371 	case AUE_OPEN_EXTENDED_RWT:
1372 	case AUE_OPEN_EXTENDED_W:
1373 	case AUE_OPEN_EXTENDED_WT:
1374 		EXTENDED_TOKENS(3);
1375 		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1376 			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1377 			kau_write(rec, tok);
1378 		}
1379 		UPATH1_VNODE1_TOKENS;
1380 		break;
1381 
1382 	case AUE_OPEN_EXTENDED_RC:
1383 	case AUE_OPEN_EXTENDED_RTC:
1384 	case AUE_OPEN_EXTENDED_RWC:
1385 	case AUE_OPEN_EXTENDED_RWTC:
1386 	case AUE_OPEN_EXTENDED_WC:
1387 	case AUE_OPEN_EXTENDED_WTC:
1388 		EXTENDED_TOKENS(3);
1389 		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1390 			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1391 			kau_write(rec, tok);
1392 		}
1393 		UPATH1_VNODE1_TOKENS;
1394 		break;
1395 
1396 	case AUE_OPENAT:
1397 	case AUE_OPENAT_R:
1398 	case AUE_OPENAT_RT:
1399 	case AUE_OPENAT_RW:
1400 	case AUE_OPENAT_RWT:
1401 	case AUE_OPENAT_W:
1402 	case AUE_OPENAT_WT:
1403 		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1404 			tok = au_to_arg32(3, "flags", ar->ar_arg_fflags);
1405 			kau_write(rec, tok);
1406 		}
1407 		if (ARG_IS_VALID(kar, ARG_FD)) {
1408 			tok = au_to_arg32(1, "dir fd", ar->ar_arg_fd);
1409 			kau_write(rec, tok);
1410 		}
1411 		UPATH1_VNODE1_TOKENS;
1412 		break;
1413 
1414 	case AUE_OPENAT_RC:
1415 	case AUE_OPENAT_RTC:
1416 	case AUE_OPENAT_RWC:
1417 	case AUE_OPENAT_RWTC:
1418 	case AUE_OPENAT_WC:
1419 	case AUE_OPENAT_WTC:
1420 		if (ARG_IS_VALID(kar, ARG_MODE)) {
1421 			tok = au_to_arg32(4, "mode", ar->ar_arg_mode);
1422 			kau_write(rec, tok);
1423 		}
1424 		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1425 			tok = au_to_arg32(3, "flags", ar->ar_arg_fflags);
1426 			kau_write(rec, tok);
1427 		}
1428 		if (ARG_IS_VALID(kar, ARG_FD)) {
1429 			tok = au_to_arg32(1, "dir fd", ar->ar_arg_fd);
1430 			kau_write(rec, tok);
1431 		}
1432 		UPATH1_VNODE1_TOKENS;
1433 		break;
1434 
1435 	case AUE_OPENBYID:
1436 	case AUE_OPENBYID_R:
1437 	case AUE_OPENBYID_RT:
1438 	case AUE_OPENBYID_RW:
1439 	case AUE_OPENBYID_RWT:
1440 	case AUE_OPENBYID_W:
1441 	case AUE_OPENBYID_WT:
1442 		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1443 			tok = au_to_arg32(3, "flags", ar->ar_arg_fflags);
1444 			kau_write(rec, tok);
1445 		}
1446 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1447 			tok = au_to_arg32(1, "volfsid", ar->ar_arg_value32);
1448 			kau_write(rec, tok);
1449 		}
1450 		if (ARG_IS_VALID(kar, ARG_VALUE64)) {
1451 			tok = au_to_arg64(2, "objid", ar->ar_arg_value64);
1452 			kau_write(rec, tok);
1453 		}
1454 		break;
1455 
1456 	case AUE_RENAMEAT:
1457 	case AUE_FACCESSAT:
1458 	case AUE_FCHMODAT:
1459 	case AUE_FCHOWNAT:
1460 	case AUE_FSTATAT:
1461 	case AUE_LINKAT:
1462 	case AUE_UNLINKAT:
1463 	case AUE_READLINKAT:
1464 	case AUE_SYMLINKAT:
1465 	case AUE_MKDIRAT:
1466 	case AUE_GETATTRLISTAT:
1467 	case AUE_SETATTRLISTAT:
1468 	case AUE_MKFIFOAT:
1469 	case AUE_MKNODAT:
1470 		if (ARG_IS_VALID(kar, ARG_FD)) {
1471 			tok = au_to_arg32(1, "dir fd", ar->ar_arg_fd);
1472 			kau_write(rec, tok);
1473 		}
1474 		UPATH1_VNODE1_TOKENS;
1475 		break;
1476 
1477 	case AUE_CLONEFILEAT:
1478 		if (ARG_IS_VALID(kar, ARG_FD)) {
1479 			tok = au_to_arg32(1, "src dir fd", ar->ar_arg_fd);
1480 			kau_write(rec, tok);
1481 		}
1482 		UPATH1_VNODE1_TOKENS;
1483 		if (ARG_IS_VALID(kar, ARG_FD2)) {
1484 			tok = au_to_arg32(1, "dst dir fd", ar->ar_arg_fd2);
1485 			kau_write(rec, tok);
1486 		}
1487 		UPATH2_TOKENS;
1488 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1489 			tok = au_to_arg32(1, "flags", ar->ar_arg_value32);
1490 			kau_write(rec, tok);
1491 		}
1492 		break;
1493 
1494 	case AUE_FCLONEFILEAT:
1495 		FD_VNODE1_TOKENS;
1496 		if (ARG_IS_VALID(kar, ARG_FD2)) {
1497 			tok = au_to_arg32(1, "dst dir fd", ar->ar_arg_fd2);
1498 			kau_write(rec, tok);
1499 		}
1500 		UPATH2_TOKENS;
1501 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1502 			tok = au_to_arg32(1, "flags", ar->ar_arg_value32);
1503 			kau_write(rec, tok);
1504 		}
1505 		break;
1506 
1507 	case AUE_PTRACE:
1508 		if (ARG_IS_VALID(kar, ARG_CMD)) {
1509 			tok = au_to_arg32(1, "request", ar->ar_arg_cmd);
1510 			kau_write(rec, tok);
1511 		}
1512 		if (ARG_IS_VALID(kar, ARG_ADDR64)) {
1513 			tok = au_to_arg64(3, "addr", ar->ar_arg_addr);
1514 			kau_write(rec, tok);
1515 		} else if (ARG_IS_VALID(kar, ARG_ADDR32)) {
1516 			tok = au_to_arg32(3, "addr",
1517 			    (u_int32_t)ar->ar_arg_addr);
1518 			kau_write(rec, tok);
1519 		}
1520 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1521 			tok = au_to_arg32(4, "data", ar->ar_arg_value32);
1522 			kau_write(rec, tok);
1523 		}
1524 		PROCESS_PID_TOKENS(2);
1525 		break;
1526 
1527 	case AUE_QUOTACTL:
1528 		if (ARG_IS_VALID(kar, ARG_CMD)) {
1529 			tok = au_to_arg32(2, "command", ar->ar_arg_cmd);
1530 			kau_write(rec, tok);
1531 		}
1532 		if (ARG_IS_VALID(kar, ARG_UID)) {
1533 			tok = au_to_arg32(3, "uid", ar->ar_arg_uid);
1534 			kau_write(rec, tok);
1535 		}
1536 		UPATH1_VNODE1_TOKENS;
1537 		break;
1538 
1539 	case AUE_REBOOT:
1540 		if (ARG_IS_VALID(kar, ARG_CMD)) {
1541 			tok = au_to_arg32(1, "howto", ar->ar_arg_cmd);
1542 			kau_write(rec, tok);
1543 		}
1544 		break;
1545 
1546 	case AUE_SEMCTL:
1547 		ar->ar_event = audit_semctl_to_event(ar->ar_arg_svipc_cmd);
1548 		OS_FALLTHROUGH;
1549 
1550 	case AUE_SEMOP:
1551 		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1552 			tok = au_to_arg32(1, "sem ID", ar->ar_arg_svipc_id);
1553 			kau_write(rec, tok);
1554 			if (ar->ar_errno != EINVAL) {
1555 				tok = au_to_ipc(AT_IPC_SEM,
1556 				    ar->ar_arg_svipc_id);
1557 				kau_write(rec, tok);
1558 			}
1559 		}
1560 		break;
1561 
1562 	case AUE_SEMGET:
1563 		if (ar->ar_errno == 0) {
1564 			if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
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_SETEGID:
1573 		if (ARG_IS_VALID(kar, ARG_EGID)) {
1574 			tok = au_to_arg32(1, "gid", ar->ar_arg_egid);
1575 			kau_write(rec, tok);
1576 		}
1577 		break;
1578 
1579 	case AUE_SETEUID:
1580 		if (ARG_IS_VALID(kar, ARG_EUID)) {
1581 			tok = au_to_arg32(1, "uid", ar->ar_arg_euid);
1582 			kau_write(rec, tok);
1583 		}
1584 		break;
1585 
1586 	case AUE_SETREGID:
1587 		if (ARG_IS_VALID(kar, ARG_RGID)) {
1588 			tok = au_to_arg32(1, "rgid", ar->ar_arg_rgid);
1589 			kau_write(rec, tok);
1590 		}
1591 		if (ARG_IS_VALID(kar, ARG_EGID)) {
1592 			tok = au_to_arg32(2, "egid", ar->ar_arg_egid);
1593 			kau_write(rec, tok);
1594 		}
1595 		break;
1596 
1597 	case AUE_SETREUID:
1598 		if (ARG_IS_VALID(kar, ARG_RUID)) {
1599 			tok = au_to_arg32(1, "ruid", ar->ar_arg_ruid);
1600 			kau_write(rec, tok);
1601 		}
1602 		if (ARG_IS_VALID(kar, ARG_EUID)) {
1603 			tok = au_to_arg32(2, "euid", ar->ar_arg_euid);
1604 			kau_write(rec, tok);
1605 		}
1606 		break;
1607 
1608 	case AUE_SETGID:
1609 		if (ARG_IS_VALID(kar, ARG_GID)) {
1610 			tok = au_to_arg32(1, "gid", ar->ar_arg_gid);
1611 			kau_write(rec, tok);
1612 		}
1613 		break;
1614 
1615 	case AUE_SETUID:
1616 		if (ARG_IS_VALID(kar, ARG_UID)) {
1617 			tok = au_to_arg32(1, "uid", ar->ar_arg_uid);
1618 			kau_write(rec, tok);
1619 		}
1620 		break;
1621 
1622 	case AUE_SETGROUPS:
1623 		if (ARG_IS_VALID(kar, ARG_GROUPSET)) {
1624 			for (uctr = 0; uctr < ar->ar_arg_groups.gidset_size;
1625 			    uctr++) {
1626 				tok = au_to_arg32(1, "setgroups",
1627 				    ar->ar_arg_groups.gidset[uctr]);
1628 				kau_write(rec, tok);
1629 			}
1630 		}
1631 		break;
1632 
1633 	case AUE_SETLOGIN:
1634 		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1635 			tok = au_to_text(ar->ar_arg_text);
1636 			kau_write(rec, tok);
1637 		}
1638 		break;
1639 
1640 	case AUE_SETPRIORITY:
1641 		if (ARG_IS_VALID(kar, ARG_CMD)) {
1642 			tok = au_to_arg32(1, "which", ar->ar_arg_cmd);
1643 			kau_write(rec, tok);
1644 		}
1645 		if (ARG_IS_VALID(kar, ARG_UID)) {
1646 			tok = au_to_arg32(2, "who", ar->ar_arg_uid);
1647 			kau_write(rec, tok);
1648 		}
1649 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1650 			tok = au_to_arg32(2, "priority", ar->ar_arg_value32);
1651 			kau_write(rec, tok);
1652 		}
1653 		break;
1654 
1655 	case AUE_SETPRIVEXEC:
1656 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1657 			tok = au_to_arg32(1, "flag", ar->ar_arg_value32);
1658 			kau_write(rec, tok);
1659 		}
1660 		break;
1661 
1662 	/* AUE_SHMAT, AUE_SHMCTL, AUE_SHMDT and AUE_SHMGET are SysV IPC */
1663 	case AUE_SHMAT:
1664 		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1665 			tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id);
1666 			kau_write(rec, tok);
1667 			/* XXXAUDIT: Does having the ipc token make sense? */
1668 			tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
1669 			kau_write(rec, tok);
1670 		}
1671 		if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) {
1672 			tok = au_to_arg64(2, "shmaddr", ar->ar_arg_svipc_addr);
1673 			kau_write(rec, tok);
1674 		}
1675 		if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) {
1676 			tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
1677 			kau_write(rec, tok);
1678 		}
1679 		break;
1680 
1681 	case AUE_SHMCTL:
1682 		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1683 			tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id);
1684 			kau_write(rec, tok);
1685 			/* XXXAUDIT: Does having the ipc token make sense? */
1686 			tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
1687 			kau_write(rec, tok);
1688 		}
1689 		switch (ar->ar_arg_svipc_cmd) {
1690 		case IPC_STAT:
1691 			ar->ar_event = AUE_SHMCTL_STAT;
1692 			break;
1693 		case IPC_RMID:
1694 			ar->ar_event = AUE_SHMCTL_RMID;
1695 			break;
1696 		case IPC_SET:
1697 			ar->ar_event = AUE_SHMCTL_SET;
1698 			if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) {
1699 				tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
1700 				kau_write(rec, tok);
1701 			}
1702 			break;
1703 		default:
1704 			break;  /* We will audit a bad command */
1705 		}
1706 		break;
1707 
1708 	case AUE_SHMDT:
1709 		if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) {
1710 			tok = au_to_arg64(1, "shmaddr",
1711 			    (int)(uintptr_t)ar->ar_arg_svipc_addr);
1712 			kau_write(rec, tok);
1713 		}
1714 		break;
1715 
1716 	case AUE_SHMGET:
1717 		/* This is unusual; the return value is in an argument token */
1718 		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1719 			tok = au_to_arg32(0, "shmid", ar->ar_arg_svipc_id);
1720 			kau_write(rec, tok);
1721 			tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
1722 			kau_write(rec, tok);
1723 		}
1724 		if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) {
1725 			tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
1726 			kau_write(rec, tok);
1727 		}
1728 		break;
1729 
1730 	/* AUE_SHMOPEN, AUE_SHMUNLINK, AUE_SEMOPEN, AUE_SEMCLOSE
1731 	 * and AUE_SEMUNLINK are Posix IPC */
1732 	case AUE_SHMOPEN:
1733 		if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) {
1734 			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1735 			kau_write(rec, tok);
1736 		}
1737 		if (ARG_IS_VALID(kar, ARG_MODE)) {
1738 			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1739 			kau_write(rec, tok);
1740 		}
1741 		OS_FALLTHROUGH;
1742 
1743 	case AUE_SHMUNLINK:
1744 		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1745 			tok = au_to_text(ar->ar_arg_text);
1746 			kau_write(rec, tok);
1747 		}
1748 		if (ARG_IS_VALID(kar, ARG_POSIX_IPC_PERM)) {
1749 			struct ipc_perm perm;
1750 
1751 			perm.uid = ar->ar_arg_pipc_perm.pipc_uid;
1752 			perm.gid = ar->ar_arg_pipc_perm.pipc_gid;
1753 			perm.cuid = ar->ar_arg_pipc_perm.pipc_uid;
1754 			perm.cgid = ar->ar_arg_pipc_perm.pipc_gid;
1755 			perm.mode = ar->ar_arg_pipc_perm.pipc_mode;
1756 			perm._seq = 0;
1757 			perm._key = 0;
1758 			tok = au_to_ipc_perm(&perm);
1759 			kau_write(rec, tok);
1760 		}
1761 		break;
1762 
1763 	case AUE_SEMOPEN:
1764 		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1765 			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1766 			kau_write(rec, tok);
1767 		}
1768 		if (ARG_IS_VALID(kar, ARG_MODE)) {
1769 			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1770 			kau_write(rec, tok);
1771 		}
1772 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1773 			tok = au_to_arg32(4, "value", ar->ar_arg_value32);
1774 			kau_write(rec, tok);
1775 		}
1776 		OS_FALLTHROUGH;
1777 
1778 	case AUE_SEMUNLINK:
1779 		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1780 			tok = au_to_text(ar->ar_arg_text);
1781 			kau_write(rec, tok);
1782 		}
1783 		if (ARG_IS_VALID(kar, ARG_POSIX_IPC_PERM)) {
1784 			struct ipc_perm perm;
1785 
1786 			perm.uid = ar->ar_arg_pipc_perm.pipc_uid;
1787 			perm.gid = ar->ar_arg_pipc_perm.pipc_gid;
1788 			perm.cuid = ar->ar_arg_pipc_perm.pipc_uid;
1789 			perm.cgid = ar->ar_arg_pipc_perm.pipc_gid;
1790 			perm.mode = ar->ar_arg_pipc_perm.pipc_mode;
1791 			perm._seq = 0;
1792 			perm._key = 0;
1793 			tok = au_to_ipc_perm(&perm);
1794 			kau_write(rec, tok);
1795 		}
1796 		break;
1797 
1798 	case AUE_SEMCLOSE:
1799 		if (ARG_IS_VALID(kar, ARG_FD)) {
1800 			tok = au_to_arg32(1, "sem", ar->ar_arg_fd);
1801 			kau_write(rec, tok);
1802 		}
1803 		break;
1804 
1805 	case AUE_SYMLINK:
1806 		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1807 			tok = au_to_text(ar->ar_arg_text);
1808 			kau_write(rec, tok);
1809 		}
1810 		UPATH1_VNODE1_TOKENS;
1811 		break;
1812 
1813 	case AUE_SYSCTL:
1814 	case AUE_SYSCTL_NONADMIN:
1815 		if (ARG_IS_VALID(kar, ARG_CTLNAME | ARG_LEN)) {
1816 			for (ctr = 0; ctr < (int)ar->ar_arg_len; ctr++) {
1817 				tok = au_to_arg32(1, "name",
1818 				    ar->ar_arg_ctlname[ctr]);
1819 				kau_write(rec, tok);
1820 			}
1821 		}
1822 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1823 			tok = au_to_arg32(5, "newval", ar->ar_arg_value32);
1824 			kau_write(rec, tok);
1825 		}
1826 		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1827 			tok = au_to_text(ar->ar_arg_text);
1828 			kau_write(rec, tok);
1829 		}
1830 		break;
1831 
1832 	case AUE_UMASK_EXTENDED:
1833 		/* ACL data */
1834 		if (ARG_IS_VALID(kar, ARG_OPAQUE)) {
1835 			tok = au_to_opaque(ar->ar_arg_opaque,
1836 			    ar->ar_arg_opq_size);
1837 			kau_write(rec, tok);
1838 		}
1839 		OS_FALLTHROUGH;
1840 
1841 	case AUE_UMASK:
1842 		if (ARG_IS_VALID(kar, ARG_MASK)) {
1843 			tok = au_to_arg32(1, "new mask", ar->ar_arg_mask);
1844 			kau_write(rec, tok);
1845 		}
1846 		tok = au_to_arg32(0, "prev mask", ar->ar_retval);
1847 		kau_write(rec, tok);
1848 		break;
1849 
1850 	case AUE_WAIT4:
1851 #if 0 /* XXXss - new  */
1852 	case AUE_WAITID:
1853 #endif
1854 		if (ARG_IS_VALID(kar, ARG_PID)) {
1855 			tok = au_to_arg32(0, "pid", ar->ar_arg_pid);
1856 			kau_write(rec, tok);
1857 		}
1858 		break;
1859 
1860 	case AUE_FSGETPATH_EXTENDED:
1861 	case AUE_FSGETPATH:
1862 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1863 			tok = au_to_arg32(3, "volfsid", ar->ar_arg_value32);
1864 			kau_write(rec, tok);
1865 		}
1866 		if (ARG_IS_VALID(kar, ARG_VALUE64)) {
1867 			tok = au_to_arg64(4, "objid", ar->ar_arg_value64);
1868 			kau_write(rec, tok);
1869 		}
1870 		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1871 			tok = au_to_text(ar->ar_arg_text);
1872 			kau_write(rec, tok);
1873 		}
1874 		break;
1875 
1876 	case AUE_SESSION_START:
1877 	case AUE_SESSION_UPDATE:
1878 	case AUE_SESSION_END:
1879 	case AUE_SESSION_CLOSE:
1880 		if (ARG_IS_VALID(kar, ARG_VALUE64)) {
1881 			tok = au_to_arg64(1, "sflags", ar->ar_arg_value64);
1882 			kau_write(rec, tok);
1883 		}
1884 		if (ARG_IS_VALID(kar, ARG_AMASK)) {
1885 			tok = au_to_arg32(2, "am_success",
1886 			    ar->ar_arg_amask.am_success);
1887 			kau_write(rec, tok);
1888 			tok = au_to_arg32(3, "am_failure",
1889 			    ar->ar_arg_amask.am_failure);
1890 			kau_write(rec, tok);
1891 		}
1892 		break;
1893 
1894 	/************************
1895 	* Mach system calls    *
1896 	************************/
1897 	case AUE_INITPROCESS:
1898 		break;
1899 
1900 	case AUE_PIDFORTASK:
1901 		if (ARG_IS_VALID(kar, ARG_MACHPORT1)) {
1902 			tok = au_to_arg32(1, "port",
1903 			    (u_int32_t)ar->ar_arg_mach_port1);
1904 			kau_write(rec, tok);
1905 		}
1906 		if (ARG_IS_VALID(kar, ARG_PID)) {
1907 			tok = au_to_arg32(2, "pid", (u_int32_t)ar->ar_arg_pid);
1908 			kau_write(rec, tok);
1909 		}
1910 		break;
1911 
1912 	case AUE_TASKFORPID:
1913 	case AUE_TASKNAMEFORPID:
1914 		if (ARG_IS_VALID(kar, ARG_MACHPORT1)) {
1915 			tok = au_to_arg32(1, "target port",
1916 			    (u_int32_t)ar->ar_arg_mach_port1);
1917 			kau_write(rec, tok);
1918 		}
1919 		if (ARG_IS_VALID(kar, ARG_MACHPORT2)) {
1920 			tok = au_to_arg32(3, "task port",
1921 			    (u_int32_t)ar->ar_arg_mach_port2);
1922 			kau_write(rec, tok);
1923 		}
1924 		PROCESS_PID_TOKENS(2);
1925 		break;
1926 
1927 	case AUE_SWAPON:
1928 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1929 			tok = au_to_arg32(4, "priority",
1930 			    (u_int32_t)ar->ar_arg_value32);
1931 			kau_write(rec, tok);
1932 		}
1933 		UPATH1_VNODE1_TOKENS;
1934 		break;
1935 
1936 	case AUE_SWAPOFF:
1937 		UPATH1_VNODE1_TOKENS;
1938 		break;
1939 
1940 	case AUE_MAPFD:
1941 		if (ARG_IS_VALID(kar, ARG_ADDR64)) {
1942 			tok = au_to_arg64(3, "va", ar->ar_arg_addr);
1943 			kau_write(rec, tok);
1944 		} else if (ARG_IS_VALID(kar, ARG_ADDR32)) {
1945 			tok = au_to_arg32(3, "va",
1946 			    (u_int32_t)ar->ar_arg_addr);
1947 			kau_write(rec, tok);
1948 		}
1949 		FD_VNODE1_TOKENS;
1950 		break;
1951 
1952 #if CONFIG_MACF
1953 	case AUE_MAC_GET_FILE:
1954 	case AUE_MAC_SET_FILE:
1955 	case AUE_MAC_GET_LINK:
1956 	case AUE_MAC_SET_LINK:
1957 	case AUE_MAC_GET_MOUNT:
1958 		UPATH1_VNODE1_TOKENS;
1959 		PROCESS_MAC_TOKENS;
1960 		break;
1961 
1962 	case AUE_MAC_GET_FD:
1963 	case AUE_MAC_SET_FD:
1964 		FD_VNODE1_TOKENS;
1965 		PROCESS_MAC_TOKENS;
1966 		break;
1967 
1968 	case AUE_MAC_SYSCALL:
1969 		PROCESS_MAC_TOKENS;
1970 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1971 			tok = au_to_arg32(3, "call", ar->ar_arg_value32);
1972 			kau_write(rec, tok);
1973 		}
1974 		break;
1975 
1976 	case AUE_MAC_EXECVE:
1977 		UPATH1_VNODE1_TOKENS;
1978 		PROCESS_MAC_TOKENS;
1979 		break;
1980 
1981 	case AUE_MAC_GET_PID:
1982 		if (ARG_IS_VALID(kar, ARG_PID)) {
1983 			tok = au_to_arg32(1, "pid", (u_int32_t)ar->ar_arg_pid);
1984 			kau_write(rec, tok);
1985 		}
1986 		PROCESS_MAC_TOKENS;
1987 		break;
1988 
1989 	case AUE_MAC_GET_LCID:
1990 		if (ARG_IS_VALID(kar, ARG_VALUE32)) {
1991 			tok = au_to_arg32(1, "lcid",
1992 			    (u_int32_t)ar->ar_arg_value32);
1993 			kau_write(rec, tok);
1994 		}
1995 		PROCESS_MAC_TOKENS;
1996 		break;
1997 
1998 	case AUE_MAC_GET_PROC:
1999 	case AUE_MAC_SET_PROC:
2000 		PROCESS_MAC_TOKENS;
2001 		break;
2002 #endif
2003 	case AUE_NULL:
2004 	default:
2005 #if DIAGNOSTIC
2006 		printf("BSM conversion requested for unknown event %d\n",
2007 		    ar->ar_event);
2008 #endif
2009 
2010 		/*
2011 		 * Write the subject token so it is properly freed here.
2012 		 */
2013 		kau_write(rec, subj_tok);
2014 		kau_free(rec);
2015 		return BSM_NOAUDIT;
2016 	}
2017 
2018 #if CONFIG_MACF
2019 	if (NULL != ar->ar_mac_records) {
2020 		/* Convert the audit data from the MAC policies */
2021 		struct mac_audit_record *mar;
2022 
2023 		LIST_FOREACH(mar, ar->ar_mac_records, records) {
2024 			switch (mar->type) {
2025 			case MAC_AUDIT_DATA_TYPE:
2026 				tok = au_to_data(AUP_BINARY, AUR_BYTE,
2027 				    mar->length,
2028 				    (const char *)mar->data);
2029 				break;
2030 			case MAC_AUDIT_TEXT_TYPE:
2031 				tok = au_to_text((char*) mar->data);
2032 				break;
2033 			default:
2034 				/*
2035 				 * XXX: we can either continue,
2036 				 * skipping this particular entry,
2037 				 * or we can pre-verify the list and
2038 				 * abort before writing any records
2039 				 */
2040 				printf("kaudit_to_bsm(): "
2041 				    "BSM conversion requested for"
2042 				    "unknown mac_audit data type %d\n",
2043 				    mar->type);
2044 			}
2045 
2046 			kau_write(rec, tok);
2047 		}
2048 	}
2049 #endif
2050 
2051 	kau_write(rec, subj_tok);
2052 
2053 #if CONFIG_MACF
2054 	if (ar->ar_cred_mac_labels != NULL &&
2055 	    strlen(ar->ar_cred_mac_labels) != 0) {
2056 		tok = au_to_text(ar->ar_cred_mac_labels);
2057 		kau_write(rec, tok);
2058 	}
2059 #endif
2060 
2061 	tok = au_to_return32(au_errno_to_bsm(ar->ar_errno), ar->ar_retval);
2062 	kau_write(rec, tok);  /* Every record gets a return token */
2063 
2064 	if (ARG_IS_VALID(kar, ARG_IDENTITY)) {
2065 		struct au_identity_info *id = &ar->ar_arg_identity;
2066 		tok = au_to_identity(id->signer_type, id->signing_id,
2067 		    id->signing_id_trunc, id->team_id, id->team_id_trunc,
2068 		    id->cdhash, id->cdhash_len);
2069 		kau_write(rec, tok);
2070 	}
2071 
2072 	rv = kau_close(rec, &ar->ar_endtime, ar->ar_event);
2073 	if (rv != 0) {
2074 		kau_free(rec);
2075 		return BSM_FAILURE;
2076 	}
2077 
2078 	*pau = rec;
2079 	return BSM_SUCCESS;
2080 }
2081 
2082 /*
2083  * Verify that a record is a valid BSM record. Return 1 if the
2084  * record is good, 0 otherwise.
2085  */
2086 int
bsm_rec_verify(void * rec,int length,boolean_t kern_events_allowed)2087 bsm_rec_verify(void *rec, int length, boolean_t kern_events_allowed)
2088 {
2089 	/* Used to partially deserialize the buffer */
2090 	struct hdr_tok_partial *hdr;
2091 	struct trl_tok_partial *trl;
2092 
2093 	/* A record requires a complete header and trailer token */
2094 	if (length < (AUDIT_HEADER_SIZE + AUDIT_TRAILER_SIZE)) {
2095 		return 0;
2096 	}
2097 
2098 	hdr = (struct hdr_tok_partial*)rec;
2099 
2100 	/* Ensure the provided length matches what the record shows */
2101 	if ((uint32_t)length != ntohl(hdr->len)) {
2102 		return 0;
2103 	}
2104 
2105 	trl = (struct trl_tok_partial*)((uintptr_t)rec + (length - AUDIT_TRAILER_SIZE));
2106 
2107 	/* Ensure the buffer contains what look like header and trailer tokens */
2108 	if (((hdr->type != AUT_HEADER32) && (hdr->type != AUT_HEADER32_EX) &&
2109 	    (hdr->type != AUT_HEADER64) && (hdr->type != AUT_HEADER64_EX)) ||
2110 	    (trl->type != AUT_TRAILER)) {
2111 		return 0;
2112 	}
2113 
2114 	/* Ensure the header and trailer agree on the length */
2115 	if (hdr->len != trl->len) {
2116 		return 0;
2117 	}
2118 
2119 	/* Ensure the trailer token has a proper magic value */
2120 	if (ntohs(trl->magic) != AUT_TRAILER_MAGIC) {
2121 		return 0;
2122 	}
2123 
2124 	if (!kern_events_allowed && AUE_IS_A_KEVENT(ntohs(hdr->e_type))) {
2125 		return 0;
2126 	}
2127 
2128 	return 1;
2129 }
2130 #endif /* CONFIG_AUDIT */
2131