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