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