]> git.saurik.com Git - apple/xnu.git/blob - bsd/kern/kern_bsm_audit.c
xnu-517.7.7.tar.gz
[apple/xnu.git] / bsd / kern / kern_bsm_audit.c
1 /*
2 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23 #include <sys/types.h>
24 #include <sys/vnode.h>
25 #include <sys/ipc.h>
26 #include <sys/sem.h>
27 #include <sys/socketvar.h>
28 #include <sys/socket.h>
29 #include <sys/queue.h>
30 #include <sys/fcntl.h>
31 #include <sys/user.h>
32
33 #include <bsm/audit.h>
34 #include <bsm/audit_record.h>
35 #include <bsm/audit_kernel.h>
36 #include <bsm/audit_kevents.h>
37 #include <bsm/audit_klib.h>
38
39 #include <netinet/in_systm.h>
40 #include <netinet/in.h>
41 #include <netinet/ip.h>
42
43 #include <kern/lock.h>
44
45 /* The number of BSM records allocated. */
46 static int bsm_rec_count = 0;
47
48 /*
49 * Records that can be recycled are maintained in the list given below
50 * The maximum number of elements that can be present in this list is
51 * bounded by MAX_AUDIT_RECORDS. Memory allocated for these records are never
52 * freed
53 */
54 LIST_HEAD(, au_record) bsm_free_q;
55
56 /*
57 * Lock for serializing access to the list of audit records.
58 */
59 static mutex_t *bsm_audit_mutex;
60
61 /*
62 * Initialize the BSM auditing subsystem.
63 */
64 void
65 kau_init(void)
66 {
67 printf("BSM auditing present\n");
68 LIST_INIT(&bsm_free_q);
69 bsm_audit_mutex = mutex_alloc(ETAP_NO_TRACE);
70 au_evclassmap_init();
71 }
72
73 /*
74 * This call reserves memory for the audit record.
75 * Memory must be guaranteed before any auditable event can be
76 * generated.
77 * The au_record structure maintains a reference to the
78 * memory allocated above and also the list of tokens associated
79 * with this record
80 */
81 struct au_record *
82 kau_open(void)
83 {
84 struct au_record *rec = NULL;
85
86 /*
87 * Find an unused record, remove it from the free list, mark as used
88 */
89 mutex_lock(bsm_audit_mutex);
90 if (!LIST_EMPTY(&bsm_free_q)) {
91 rec = LIST_FIRST(&bsm_free_q);
92 LIST_REMOVE(rec, au_rec_q);
93 }
94 mutex_unlock(bsm_audit_mutex);
95
96 if (rec == NULL) {
97 mutex_lock(bsm_audit_mutex);
98 if (bsm_rec_count >= MAX_AUDIT_RECORDS) {
99 /* XXX We need to increase size of MAX_AUDIT_RECORDS */
100 mutex_unlock(bsm_audit_mutex);
101 return NULL;
102 }
103 mutex_unlock(bsm_audit_mutex);
104
105 /*
106 * Create a new BSM kernel record.
107 */
108 rec = (struct au_record *)kalloc(sizeof(*rec));
109 if(rec == NULL) {
110 return NULL;
111 }
112 rec->data = (u_char *)kalloc(MAX_AUDIT_RECORD_SIZE * sizeof(u_char));
113 if((rec->data) == NULL) {
114 kfree((vm_offset_t)rec, (vm_size_t)sizeof(*rec));
115 return NULL;
116 }
117 mutex_lock(bsm_audit_mutex);
118 bsm_rec_count++;
119 mutex_unlock(bsm_audit_mutex);
120 }
121 memset(rec->data, 0, MAX_AUDIT_RECORD_SIZE);
122
123 TAILQ_INIT(&rec->token_q);
124 rec->len = 0;
125 rec->used = 1;
126
127 return rec;
128 }
129
130 /*
131 * Store the token with the record descriptor
132 *
133 */
134 int kau_write(struct au_record *rec, struct au_token *tok)
135 {
136 if(tok == NULL) {
137 return -1; /* Invalid Token */
138 }
139
140 /* Add the token to the tail */
141 /*
142 * XXX Not locking here -- we should not be writing to
143 * XXX the same audit record from different threads
144 */
145 TAILQ_INSERT_TAIL(&rec->token_q, tok, tokens);
146
147 rec->len += tok->len; /* grow record length by token size bytes */
148
149 return 0;
150 }
151
152 /*
153 * Close out the audit record by adding the header token, identifying
154 * any missing tokens. Write out the tokens to the record memory.
155 */
156 int kau_close(struct au_record *rec, struct timespec *ctime, short event)
157 {
158 u_char *dptr;
159 size_t tot_rec_size;
160 token_t *cur, *hdr, *trail;
161 int retval = 0;
162
163 tot_rec_size = rec->len + HEADER_SIZE + TRAILER_SIZE;
164 if(tot_rec_size <= MAX_AUDIT_RECORD_SIZE) {
165 /* Create the header token */
166 hdr = kau_to_header32(ctime, tot_rec_size, event, 0);
167
168 if(hdr != NULL) {
169 /* Add to head of list */
170 TAILQ_INSERT_HEAD(&rec->token_q, hdr, tokens);
171
172 trail = au_to_trailer(tot_rec_size);
173 if(trail != NULL) {
174 TAILQ_INSERT_TAIL(&rec->token_q, trail, tokens);
175 }
176 }
177 /* Serialize token data to the record */
178
179 rec->len = tot_rec_size;
180 dptr = rec->data;
181 TAILQ_FOREACH(cur, &rec->token_q, tokens) {
182 memcpy(dptr, cur->t_data, cur->len);
183 dptr += cur->len;
184 }
185 }
186 }
187
188 /*
189 * Free a BSM audit record by releasing all the tokens and clearing the
190 * audit record information.
191 */
192 void kau_free(struct au_record *rec)
193 {
194 struct au_token *tok;
195
196 /* Free the token list */
197 while ((tok = TAILQ_FIRST(&rec->token_q))) {
198 TAILQ_REMOVE(&rec->token_q, tok, tokens);
199 kfree((vm_offset_t)tok, sizeof(*tok) + tok->len);
200 }
201
202 rec->used = 0;
203 rec->len = 0;
204
205 mutex_lock(bsm_audit_mutex);
206
207 /* Add the record to the freelist */
208 LIST_INSERT_HEAD(&bsm_free_q, rec, au_rec_q);
209
210 mutex_unlock(bsm_audit_mutex);
211
212 }
213
214 /*
215 * XXX May want turn some (or all) of these macros into functions in order
216 * to reduce the generated code sized.
217 */
218 #define UPATH1_TOKENS \
219 do { \
220 if (ar->ar_valid_arg & ARG_UPATH1) { \
221 tok = au_to_path(ar->ar_arg_upath1); \
222 kau_write(rec, tok); \
223 } \
224 } while (0)
225
226 #define UPATH2_TOKENS \
227 do { \
228 if (ar->ar_valid_arg & ARG_UPATH2) { \
229 tok = au_to_path(ar->ar_arg_upath2); \
230 kau_write(rec, tok); \
231 } \
232 } while (0)
233
234 #define KPATH1_VNODE1_TOKENS \
235 do { \
236 if (ar->ar_valid_arg & ARG_KPATH1) { \
237 tok = au_to_path(ar->ar_arg_kpath1); \
238 kau_write(rec, tok); \
239 } \
240 if (ar->ar_valid_arg & ARG_VNODE1) { \
241 tok = kau_to_attr32(&ar->ar_arg_vnode1);\
242 kau_write(rec, tok); \
243 } \
244 } while (0)
245
246 #define KPATH1_VNODE1_OR_UPATH1_TOKENS \
247 do { \
248 if (ar->ar_valid_arg & ARG_KPATH1) { \
249 tok = au_to_path(ar->ar_arg_kpath1); \
250 kau_write(rec, tok); \
251 } else { \
252 UPATH1_TOKENS; \
253 } \
254 if (ar->ar_valid_arg & ARG_VNODE1) { \
255 tok = kau_to_attr32(&ar->ar_arg_vnode1);\
256 kau_write(rec, tok); \
257 } \
258 } while (0)
259
260 #define KPATH2_VNODE2_TOKENS \
261 do { \
262 if (ar->ar_valid_arg & ARG_KPATH2) { \
263 tok = au_to_path(ar->ar_arg_kpath2); \
264 kau_write(rec, tok); \
265 } \
266 if (ar->ar_valid_arg & ARG_VNODE2) { \
267 tok = kau_to_attr32(&ar->ar_arg_vnode1);\
268 kau_write(rec, tok); \
269 } \
270 } while (0)
271
272 #define FD_KPATH1_VNODE1_TOKENS \
273 do { \
274 if (ar->ar_valid_arg & ARG_KPATH1) { \
275 tok = au_to_path(ar->ar_arg_kpath1); \
276 kau_write(rec, tok); \
277 if (ar->ar_valid_arg & ARG_VNODE1) { \
278 tok = kau_to_attr32(&ar->ar_arg_vnode1);\
279 kau_write(rec, tok); \
280 } \
281 } else { \
282 tok = au_to_arg32(1, "no path: fd", ar->ar_arg_fd); \
283 kau_write(rec, tok); \
284 } \
285 } while (0)
286
287 #define PROCESS_PID_TOKENS(argn) \
288 do { \
289 if ((ar->ar_arg_pid > 0) /* Kill a single process */ \
290 && (ar->ar_valid_arg & ARG_PROCESS)) { \
291 tok = au_to_process(ar->ar_arg_auid, ar->ar_arg_euid, \
292 ar->ar_arg_egid, ar->ar_arg_ruid, \
293 ar->ar_arg_rgid, ar->ar_arg_pid, \
294 ar->ar_arg_asid, &ar->ar_arg_termid); \
295 kau_write(rec, tok); \
296 } else { \
297 tok = au_to_arg32(argn, "process", ar->ar_arg_pid);\
298 kau_write(rec, tok); \
299 } \
300 } while (0) \
301
302 /*
303 * Implement auditing for the auditon() system call. The audit tokens
304 * that are generated depend on the command that was sent into the
305 * auditon() system call.
306 *
307 */
308 void
309 audit_sys_auditon(struct audit_record *ar, struct au_record *rec)
310 {
311 struct au_token *tok;
312
313 switch (ar->ar_arg_cmd) {
314 case A_SETPOLICY:
315 if (sizeof(ar->ar_arg_auditon.au_flags) > 4)
316 tok = au_to_arg64(1, "policy",
317 ar->ar_arg_auditon.au_flags);
318 else
319 tok = au_to_arg32(1, "policy",
320 ar->ar_arg_auditon.au_flags);
321 kau_write(rec, tok);
322 break;
323 case A_SETKMASK:
324 tok = au_to_arg32(2, "setkmask:as_success",
325 ar->ar_arg_auditon.au_mask.am_success);
326 kau_write(rec, tok);
327 tok = au_to_arg32(2, "setkmask:as_failure",
328 ar->ar_arg_auditon.au_mask.am_failure);
329 kau_write(rec, tok);
330 break;
331 case A_SETQCTRL:
332 tok = au_to_arg32(3, "setqctrl:aq_hiwater",
333 ar->ar_arg_auditon.au_qctrl.aq_hiwater);
334 kau_write(rec, tok);
335 tok = au_to_arg32(3, "setqctrl:aq_lowater",
336 ar->ar_arg_auditon.au_qctrl.aq_lowater);
337 kau_write(rec, tok);
338 tok = au_to_arg32(3, "setqctrl:aq_bufsz",
339 ar->ar_arg_auditon.au_qctrl.aq_bufsz);
340 kau_write(rec, tok);
341 tok = au_to_arg32(3, "setqctrl:aq_delay",
342 ar->ar_arg_auditon.au_qctrl.aq_delay);
343 kau_write(rec, tok);
344 tok = au_to_arg32(3, "setqctrl:aq_minfree",
345 ar->ar_arg_auditon.au_qctrl.aq_minfree);
346 kau_write(rec, tok);
347 break;
348 case A_SETUMASK:
349 tok = au_to_arg32(3, "setumask:as_success",
350 ar->ar_arg_auditon.au_auinfo.ai_mask.am_success);
351 kau_write(rec, tok);
352 tok = au_to_arg32(3, "setumask:as_failure",
353 ar->ar_arg_auditon.au_auinfo.ai_mask.am_failure);
354 kau_write(rec, tok);
355 break;
356 case A_SETSMASK:
357 tok = au_to_arg32(3, "setsmask:as_success",
358 ar->ar_arg_auditon.au_auinfo.ai_mask.am_success);
359 kau_write(rec, tok);
360 tok = au_to_arg32(3, "setsmask:as_failure",
361 ar->ar_arg_auditon.au_auinfo.ai_mask.am_failure);
362 kau_write(rec, tok);
363 break;
364 case A_SETCOND:
365 if (sizeof(ar->ar_arg_auditon.au_cond) > 4)
366 tok = au_to_arg64(3, "setcond",
367 ar->ar_arg_auditon.au_cond);
368 else
369 tok = au_to_arg32(3, "setcond",
370 ar->ar_arg_auditon.au_cond);
371 kau_write(rec, tok);
372 break;
373 case A_SETCLASS:
374 tok = au_to_arg32(2, "setclass:ec_event",
375 ar->ar_arg_auditon.au_evclass.ec_number);
376 kau_write(rec, tok);
377 tok = au_to_arg32(3, "setclass:ec_class",
378 ar->ar_arg_auditon.au_evclass.ec_class);
379 kau_write(rec, tok);
380 break;
381 case A_SETPMASK:
382 tok = au_to_arg32(2, "setpmask:as_success",
383 ar->ar_arg_auditon.au_aupinfo.ap_mask.am_success);
384 kau_write(rec, tok);
385 tok = au_to_arg32(2, "setpmask:as_failure",
386 ar->ar_arg_auditon.au_aupinfo.ap_mask.am_failure);
387 kau_write(rec, tok);
388 break;
389 case A_SETFSIZE:
390 tok = au_to_arg32(2, "setfsize:filesize",
391 ar->ar_arg_auditon.au_fstat.af_filesz);
392 kau_write(rec, tok);
393 break;
394 default:
395 break;
396 }
397 }
398
399 /*
400 * Convert an internal kernel audit record to a BSM record and return
401 * a success/failure indicator. The BSM record is passed as an out
402 * parameter to this function.
403 * Return conditions:
404 * BSM_SUCCESS: The BSM record is valid
405 * BSM_FAILURE: Failure; the BSM record is NULL.
406 * BSM_NOAUDIT: The event is not auditable for BSM; the BSM record is NULL.
407 */
408 int
409 kaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau)
410 {
411 struct au_token *tok, *subj_tok;
412 struct au_record *rec;
413 au_tid_t tid;
414 struct audit_record *ar;
415 int ctr;
416
417 *pau = NULL;
418 if (kar == NULL)
419 return (BSM_FAILURE);
420
421 ar = &kar->k_ar;
422
423 rec = kau_open();
424 if (rec == NULL)
425 return (BSM_FAILURE);
426
427 /* Create the subject token */
428 tid.port = ar->ar_subj_term.port;
429 tid.machine = ar->ar_subj_term.machine;
430 subj_tok = au_to_subject32(ar->ar_subj_auid, /* audit ID */
431 ar->ar_subj_cred.cr_uid, /* eff uid */
432 ar->ar_subj_egid, /* eff group id */
433 ar->ar_subj_ruid, /* real uid */
434 ar->ar_subj_rgid, /* real group id */
435 ar->ar_subj_pid, /* process id */
436 ar->ar_subj_asid, /* session ID */
437 &tid);
438
439 /* The logic inside each case fills in the tokens required for the
440 * event, except for the header, trailer, and return tokens. The
441 * header and trailer tokens are added by the kau_close() function.
442 * The return token is added outside of the switch statement.
443 */
444 switch(ar->ar_event) {
445
446 /*
447 * Socket-related events.
448 */
449 case AUE_ACCEPT:
450 case AUE_BIND:
451 case AUE_CONNECT:
452 case AUE_RECVFROM:
453 case AUE_RECVMSG:
454 case AUE_SENDMSG:
455 case AUE_SENDTO:
456 tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
457 kau_write(rec, tok);
458 if (ar->ar_valid_arg & ARG_SADDRINET) {
459 tok = au_to_sock_inet(
460 (struct sockaddr_in *)&ar->ar_arg_sockaddr);
461 kau_write(rec, tok);
462 }
463 if (ar->ar_valid_arg & ARG_SADDRUNIX) {
464 tok = au_to_sock_unix(
465 (struct sockaddr_un *)&ar->ar_arg_sockaddr);
466 kau_write(rec, tok);
467 UPATH1_TOKENS;
468 }
469 /* XXX Need to handle ARG_SADDRINET6 */
470 break;
471
472 case AUE_SOCKET:
473 case AUE_SOCKETPAIR:
474 tok = au_to_arg32(1,"domain", ar->ar_arg_sockinfo.so_domain);
475 kau_write(rec, tok);
476 tok = au_to_arg32(2,"type", ar->ar_arg_sockinfo.so_type);
477 kau_write(rec, tok);
478 tok = au_to_arg32(3,"protocol",ar->ar_arg_sockinfo.so_protocol);
479 kau_write(rec, tok);
480 break;
481
482 case AUE_SETSOCKOPT:
483 case AUE_SHUTDOWN:
484 tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
485 kau_write(rec, tok);
486 break;
487
488 case AUE_ACCT:
489 if (ar->ar_valid_arg & (ARG_KPATH1 | ARG_UPATH1)) {
490 KPATH1_VNODE1_OR_UPATH1_TOKENS;
491 } else {
492 tok = au_to_arg32(1, "accounting off", 0);
493 kau_write(rec, tok);
494 }
495 break;
496
497 case AUE_SETAUID:
498 tok = au_to_arg32(2, "setauid", ar->ar_arg_auid);
499 kau_write(rec, tok);
500 break;
501
502 case AUE_SETAUDIT:
503 if (ar->ar_valid_arg & ARG_AUID) {
504 tok = au_to_arg32(1, "setaudit:auid", ar->ar_arg_auid);
505 kau_write(rec, tok);
506 tok = au_to_arg32(1, "setaudit:port",
507 ar->ar_arg_termid.port);
508 kau_write(rec, tok);
509 tok = au_to_arg32(1, "setaudit:machine",
510 ar->ar_arg_termid.machine);
511 kau_write(rec, tok);
512 tok = au_to_arg32(1, "setaudit:as_success",
513 ar->ar_arg_amask.am_success);
514 kau_write(rec, tok);
515 tok = au_to_arg32(1, "setaudit:as_failure",
516 ar->ar_arg_amask.am_failure);
517 kau_write(rec, tok);
518 tok = au_to_arg32(1, "setaudit:asid", ar->ar_arg_asid);
519 kau_write(rec, tok);
520 }
521 break;
522
523 case AUE_SETAUDIT_ADDR:
524 break; /* XXX need to add arguments */
525
526 case AUE_AUDITON:
527 /* For AUDITON commands without own event, audit the cmd */
528 tok = au_to_arg32(1, "cmd", ar->ar_arg_cmd);
529 kau_write(rec, tok);
530 /* fall thru */
531
532 case AUE_AUDITON_GETCAR:
533 case AUE_AUDITON_GETCLASS:
534 case AUE_AUDITON_GETCOND:
535 case AUE_AUDITON_GETCWD:
536 case AUE_AUDITON_GETKMASK:
537 case AUE_AUDITON_GETSTAT:
538 case AUE_AUDITON_GPOLICY:
539 case AUE_AUDITON_GQCTRL:
540 case AUE_AUDITON_SETCLASS:
541 case AUE_AUDITON_SETCOND:
542 case AUE_AUDITON_SETKMASK:
543 case AUE_AUDITON_SETSMASK:
544 case AUE_AUDITON_SETSTAT:
545 case AUE_AUDITON_SETUMASK:
546 case AUE_AUDITON_SPOLICY:
547 case AUE_AUDITON_SQCTRL:
548 if (ar->ar_valid_arg & ARG_AUDITON) {
549 audit_sys_auditon(ar, rec);
550 }
551 break;
552
553 case AUE_AUDITCTL:
554 KPATH1_VNODE1_OR_UPATH1_TOKENS;
555 break;
556
557 case AUE_ADJTIME:
558 case AUE_AUDIT:
559 case AUE_EXIT:
560 case AUE_GETAUDIT:
561 case AUE_GETAUDIT_ADDR:
562 case AUE_GETAUID:
563 case AUE_GETFSSTAT:
564 case AUE_PIPE:
565 case AUE_SETPGRP:
566 case AUE_SETRLIMIT:
567 case AUE_SETSID:
568 case AUE_SETTIMEOFDAY:
569 case AUE_NEWSYSTEMSHREG:
570 /* Header, subject, and return tokens added at end */
571 break;
572
573 case AUE_ACCESS:
574 case AUE_CHDIR:
575 case AUE_CHROOT:
576 case AUE_EXECVE:
577 case AUE_GETATTRLIST:
578 case AUE_GETFH:
579 case AUE_LSTAT:
580 case AUE_MKFIFO:
581 case AUE_PATHCONF:
582 case AUE_READLINK:
583 case AUE_REVOKE:
584 case AUE_RMDIR:
585 case AUE_SEARCHFS:
586 case AUE_SETATTRLIST:
587 case AUE_STAT:
588 case AUE_STATFS:
589 case AUE_TRUNCATE:
590 case AUE_UNDELETE:
591 case AUE_UNLINK:
592 case AUE_UTIMES:
593 KPATH1_VNODE1_OR_UPATH1_TOKENS;
594 break;
595
596 case AUE_CHFLAGS:
597 tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
598 kau_write(rec, tok);
599 KPATH1_VNODE1_OR_UPATH1_TOKENS;
600 break;
601
602 case AUE_CHMOD:
603 tok = au_to_arg32(2, "new file mode", ar->ar_arg_mode);
604 kau_write(rec, tok);
605 KPATH1_VNODE1_OR_UPATH1_TOKENS;
606 break;
607
608 case AUE_CHOWN:
609 tok = au_to_arg32(2, "new file uid", ar->ar_arg_uid);
610 kau_write(rec, tok);
611 tok = au_to_arg32(3, "new file gid", ar->ar_arg_gid);
612 kau_write(rec, tok);
613 KPATH1_VNODE1_OR_UPATH1_TOKENS;
614 break;
615
616 case AUE_EXCHANGEDATA:
617 KPATH1_VNODE1_OR_UPATH1_TOKENS;
618 KPATH2_VNODE2_TOKENS;
619 break;
620
621 case AUE_CLOSE:
622 tok = au_to_arg32(2, "fd", ar->ar_arg_fd);
623 kau_write(rec, tok);
624 KPATH1_VNODE1_OR_UPATH1_TOKENS;
625 break;
626
627 case AUE_FCHMOD:
628 tok = au_to_arg32(2, "new file mode", ar->ar_arg_mode);
629 kau_write(rec, tok);
630 FD_KPATH1_VNODE1_TOKENS;
631 break;
632
633 case AUE_FCHDIR:
634 case AUE_FPATHCONF:
635 case AUE_FSTAT: /* XXX Need to handle sockets and shm */
636 case AUE_FSTATFS:
637 case AUE_FTRUNCATE:
638 case AUE_FUTIMES:
639 case AUE_GETDIRENTRIES:
640 case AUE_GETDIRENTRIESATTR:
641 FD_KPATH1_VNODE1_TOKENS;
642 break;
643
644 case AUE_FCHOWN:
645 tok = au_to_arg32(2, "new file uid", ar->ar_arg_uid);
646 kau_write(rec, tok);
647 tok = au_to_arg32(3, "new file gid", ar->ar_arg_gid);
648 kau_write(rec, tok);
649 FD_KPATH1_VNODE1_TOKENS;
650 break;
651
652 case AUE_FCNTL:
653 if (ar->ar_arg_cmd == F_GETLK || ar->ar_arg_cmd == F_SETLK ||
654 ar->ar_arg_cmd == F_SETLKW) {
655 tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd);
656 kau_write(rec, tok);
657 FD_KPATH1_VNODE1_TOKENS;
658 }
659 break;
660
661 case AUE_FCHFLAGS:
662 tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
663 kau_write(rec, tok);
664 FD_KPATH1_VNODE1_TOKENS;
665 break;
666
667 case AUE_FLOCK:
668 tok = au_to_arg32(2, "operation", ar->ar_arg_cmd);
669 kau_write(rec, tok);
670 FD_KPATH1_VNODE1_TOKENS;
671 break;
672
673 case AUE_FORK:
674 case AUE_VFORK:
675 tok = au_to_arg32(0, "child PID", ar->ar_arg_pid);
676 kau_write(rec, tok);
677 break;
678
679 case AUE_IOCTL:
680 tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd);
681 kau_write(rec, tok);
682 tok = au_to_arg32(1, "arg", (u_int32_t)ar->ar_arg_addr);
683 kau_write(rec, tok);
684 if (ar->ar_valid_arg & ARG_VNODE1) {
685 FD_KPATH1_VNODE1_TOKENS;
686 } else {
687 if (ar->ar_valid_arg & ARG_SOCKINFO) {
688 tok = kau_to_socket(&ar->ar_arg_sockinfo);
689 kau_write(rec, tok);
690 } else {
691 tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
692 kau_write(rec, tok);
693 }
694 }
695 break;
696
697 case AUE_KILL:
698 tok = au_to_arg32(2, "signal", ar->ar_arg_signum);
699 kau_write(rec, tok);
700 PROCESS_PID_TOKENS(1);
701 break;
702
703 case AUE_KTRACE:
704 tok = au_to_arg32(2, "ops", ar->ar_arg_cmd);
705 kau_write(rec, tok);
706 tok = au_to_arg32(3, "trpoints", ar->ar_arg_value);
707 kau_write(rec, tok);
708 PROCESS_PID_TOKENS(4);
709 KPATH1_VNODE1_OR_UPATH1_TOKENS;
710 break;
711
712 case AUE_LINK:
713 case AUE_RENAME:
714 KPATH1_VNODE1_OR_UPATH1_TOKENS;
715 UPATH2_TOKENS;
716 break;
717
718 case AUE_LOADSHFILE:
719 tok = au_to_arg32(4, "base addr", (u_int32_t)ar->ar_arg_addr);
720 kau_write(rec, tok);
721 KPATH1_VNODE1_OR_UPATH1_TOKENS;
722 break;
723
724 case AUE_MKDIR:
725 tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
726 kau_write(rec, tok);
727 KPATH1_VNODE1_OR_UPATH1_TOKENS;
728 break;
729
730 case AUE_MKNOD:
731 tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
732 kau_write(rec, tok);
733 tok = au_to_arg32(3, "dev", ar->ar_arg_dev);
734 kau_write(rec, tok);
735 KPATH1_VNODE1_OR_UPATH1_TOKENS;
736 break;
737
738 case AUE_MMAP:
739 case AUE_MUNMAP:
740 case AUE_MPROTECT:
741 case AUE_MLOCK:
742 case AUE_MUNLOCK:
743 case AUE_MINHERIT:
744 tok = au_to_arg32(1, "addr", (u_int32_t)ar->ar_arg_addr);
745 kau_write(rec, tok);
746 tok = au_to_arg32(2, "len", ar->ar_arg_len);
747 kau_write(rec, tok);
748 if (ar->ar_event == AUE_MMAP)
749 FD_KPATH1_VNODE1_TOKENS;
750 if (ar->ar_event == AUE_MPROTECT) {
751 tok = au_to_arg32(3, "protection", ar->ar_arg_value);
752 kau_write(rec, tok);
753 }
754 if (ar->ar_event == AUE_MINHERIT) {
755 tok = au_to_arg32(3, "inherit", ar->ar_arg_value);
756 kau_write(rec, tok);
757 }
758 break;
759
760 case AUE_MOUNT:
761 /* XXX Need to handle NFS mounts */
762 tok = au_to_arg32(3, "flags", ar->ar_arg_fflags);
763 kau_write(rec, tok);
764 if (ar->ar_valid_arg & ARG_TEXT) {
765 tok = au_to_text(ar->ar_arg_text);
766 kau_write(rec, tok);
767 }
768 /* fall through */
769 case AUE_UMOUNT:
770 KPATH1_VNODE1_OR_UPATH1_TOKENS;
771 break;
772
773 case AUE_MSGCTL:
774 ar->ar_event = msgctl_to_event(ar->ar_arg_svipc_cmd);
775 /* Fall through */
776 case AUE_MSGRCV:
777 case AUE_MSGSND:
778 tok = au_to_arg32(1, "msg ID", ar->ar_arg_svipc_id);
779 kau_write(rec, tok);
780 if (ar->ar_errno != EINVAL) {
781 tok = au_to_ipc(AT_IPC_MSG, ar->ar_arg_svipc_id);
782 kau_write(rec, tok);
783 }
784 break;
785
786 case AUE_MSGGET:
787 if (ar->ar_errno == 0) {
788 tok = au_to_ipc(AT_IPC_MSG, ar->ar_arg_svipc_id);
789 kau_write(rec, tok);
790 }
791 break;
792
793 case AUE_RESETSHFILE:
794 tok = au_to_arg32(1, "base addr", (u_int32_t)ar->ar_arg_addr);
795 kau_write(rec, tok);
796 break;
797
798 case AUE_OPEN_R:
799 case AUE_OPEN_RC:
800 case AUE_OPEN_RTC:
801 case AUE_OPEN_RT:
802 case AUE_OPEN_RW:
803 case AUE_OPEN_RWC:
804 case AUE_OPEN_RWTC:
805 case AUE_OPEN_RWT:
806 case AUE_OPEN_W:
807 case AUE_OPEN_WC:
808 case AUE_OPEN_WTC:
809 case AUE_OPEN_WT:
810 UPATH1_TOKENS; /* Save the user space path */
811 KPATH1_VNODE1_TOKENS; /* Audit the kernel path as well */
812 break;
813
814 case AUE_PTRACE:
815 tok = au_to_arg32(1, "request", ar->ar_arg_cmd);
816 kau_write(rec, tok);
817 tok = au_to_arg32(3, "addr", (u_int32_t)ar->ar_arg_addr);
818 kau_write(rec, tok);
819 tok = au_to_arg32(4, "data", ar->ar_arg_value);
820 kau_write(rec, tok);
821 PROCESS_PID_TOKENS(2);
822 break;
823
824 case AUE_QUOTACTL:
825 tok = au_to_arg32(2, "command", ar->ar_arg_cmd);
826 kau_write(rec, tok);
827 tok = au_to_arg32(3, "uid", ar->ar_arg_uid);
828 kau_write(rec, tok);
829 KPATH1_VNODE1_OR_UPATH1_TOKENS;
830 break;
831
832 case AUE_REBOOT:
833 tok = au_to_arg32(1, "howto", ar->ar_arg_cmd);
834 kau_write(rec, tok);
835 break;
836
837 case AUE_SEMCTL:
838 ar->ar_event = semctl_to_event(ar->ar_arg_svipc_cmd);
839 /* Fall through */
840 case AUE_SEMOP:
841 tok = au_to_arg32(1, "sem ID", ar->ar_arg_svipc_id);
842 kau_write(rec, tok);
843 if (ar->ar_errno != EINVAL) {
844 tok = au_to_ipc(AT_IPC_SEM, ar->ar_arg_svipc_id);
845 kau_write(rec, tok);
846 }
847 break;
848 case AUE_SEMGET:
849 if (ar->ar_errno == 0) {
850 tok = au_to_ipc(AT_IPC_SEM, ar->ar_arg_svipc_id);
851 kau_write(rec, tok);
852 }
853 break;
854 case AUE_SETEGID:
855 tok = au_to_arg32(1, "gid", ar->ar_arg_egid);
856 kau_write(rec, tok);
857 break;
858 case AUE_SETEUID:
859 tok = au_to_arg32(1, "uid", ar->ar_arg_euid);
860 kau_write(rec, tok);
861 break;
862 case AUE_SETGID:
863 tok = au_to_arg32(1, "gid", ar->ar_arg_gid);
864 kau_write(rec, tok);
865 break;
866 case AUE_SETUID:
867 tok = au_to_arg32(1, "uid", ar->ar_arg_uid);
868 kau_write(rec, tok);
869 break;
870 case AUE_SETGROUPS:
871 if (ar->ar_valid_arg & ARG_GROUPSET) {
872 for(ctr = 0; ctr < ar->ar_arg_groups.gidset_size; ctr++)
873 {
874 tok = au_to_arg32(1, "setgroups", ar->ar_arg_groups.gidset[ctr]);
875 kau_write(rec, tok);
876 }
877 }
878 break;
879
880 case AUE_SETLOGIN:
881 if (ar->ar_valid_arg & ARG_TEXT) {
882 tok = au_to_text(ar->ar_arg_text);
883 kau_write(rec, tok);
884 }
885 break;
886
887 case AUE_SETPRIORITY:
888 tok = au_to_arg32(1, "which", ar->ar_arg_cmd);
889 kau_write(rec, tok);
890 tok = au_to_arg32(2, "who", ar->ar_arg_uid);
891 kau_write(rec, tok);
892 tok = au_to_arg32(2, "priority", ar->ar_arg_value);
893 kau_write(rec, tok);
894 break;
895
896 case AUE_SETPRIVEXEC:
897 tok = au_to_arg32(1, "flag", ar->ar_arg_value);
898 kau_write(rec, tok);
899 break;
900
901 /* AUE_SHMAT, AUE_SHMCTL, AUE_SHMDT and AUE_SHMGET are SysV IPC */
902 case AUE_SHMAT:
903 tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id);
904 kau_write(rec, tok);
905 tok = au_to_arg32(2, "shmaddr", (int)ar->ar_arg_svipc_addr);
906 kau_write(rec, tok);
907 if (ar->ar_valid_arg & ARG_SVIPC_PERM) {
908 tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
909 kau_write(rec, tok);
910 tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
911 kau_write(rec, tok);
912 }
913 break;
914
915 case AUE_SHMCTL:
916 tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id);
917 kau_write(rec, tok);
918 switch (ar->ar_arg_svipc_cmd) {
919 case IPC_STAT:
920 ar->ar_event = AUE_SHMCTL_STAT;
921 if (ar->ar_valid_arg & ARG_SVIPC_PERM) {
922 tok = au_to_ipc(AT_IPC_SHM,
923 ar->ar_arg_svipc_id);
924 kau_write(rec, tok);
925 }
926 break;
927 case IPC_RMID:
928 ar->ar_event = AUE_SHMCTL_RMID;
929 if (ar->ar_valid_arg & ARG_SVIPC_PERM) {
930 tok = au_to_ipc(AT_IPC_SHM,
931 ar->ar_arg_svipc_id);
932 kau_write(rec, tok);
933 }
934 break;
935 case IPC_SET:
936 ar->ar_event = AUE_SHMCTL_SET;
937 if (ar->ar_valid_arg & ARG_SVIPC_PERM) {
938 tok = au_to_ipc(AT_IPC_SHM,
939 ar->ar_arg_svipc_id);
940 kau_write(rec, tok);
941 tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
942 kau_write(rec, tok);
943 }
944 break;
945 default:
946 break; /* We will audit a bad command */
947 }
948 break;
949
950 case AUE_SHMDT:
951 tok = au_to_arg32(1, "shmaddr", (int)ar->ar_arg_svipc_addr);
952 kau_write(rec, tok);
953 break;
954
955 case AUE_SHMGET:
956 /* This is unusual; the return value is in an argument token */
957 tok = au_to_arg32(0, "shmid", ar->ar_arg_svipc_id);
958 kau_write(rec, tok);
959 if (ar->ar_valid_arg & ARG_SVIPC_PERM) {
960 tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
961 kau_write(rec, tok);
962 tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
963 kau_write(rec, tok);
964 }
965 break;
966
967 /* AUE_SHMOPEN, AUE_SHMUNLINK, AUE_SEMOPEN, AUE_SEMCLOSE
968 * and AUE_SEMUNLINK are Posix IPC */
969 case AUE_SHMOPEN:
970 tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
971 kau_write(rec, tok);
972 tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
973 kau_write(rec, tok);
974 case AUE_SHMUNLINK:
975 if (ar->ar_valid_arg & ARG_TEXT) {
976 tok = au_to_text(ar->ar_arg_text);
977 kau_write(rec, tok);
978 }
979 if (ar->ar_valid_arg & ARG_POSIX_IPC_PERM) {
980 /* Create an ipc_perm token */
981 struct ipc_perm perm;
982 perm.uid = ar->ar_arg_pipc_perm.pipc_uid;
983 perm.gid = ar->ar_arg_pipc_perm.pipc_gid;
984 perm.cuid = ar->ar_arg_pipc_perm.pipc_uid;
985 perm.cgid = ar->ar_arg_pipc_perm.pipc_gid;
986 perm.mode = ar->ar_arg_pipc_perm.pipc_mode;
987 perm.seq = 0;
988 perm.key = 0;
989 tok = au_to_ipc_perm(&perm);
990 kau_write(rec, tok);
991 }
992 break;
993
994 case AUE_SEMOPEN:
995 tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
996 kau_write(rec, tok);
997 tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
998 kau_write(rec, tok);
999 tok = au_to_arg32(4, "value", ar->ar_arg_value);
1000 kau_write(rec, tok);
1001 /* fall through */
1002 case AUE_SEMUNLINK:
1003 if (ar->ar_valid_arg & ARG_TEXT) {
1004 tok = au_to_text(ar->ar_arg_text);
1005 kau_write(rec, tok);
1006 }
1007 if (ar->ar_valid_arg & ARG_POSIX_IPC_PERM) {
1008 /* Create an ipc_perm token */
1009 struct ipc_perm perm;
1010 perm.uid = ar->ar_arg_pipc_perm.pipc_uid;
1011 perm.gid = ar->ar_arg_pipc_perm.pipc_gid;
1012 perm.cuid = ar->ar_arg_pipc_perm.pipc_uid;
1013 perm.cgid = ar->ar_arg_pipc_perm.pipc_gid;
1014 perm.mode = ar->ar_arg_pipc_perm.pipc_mode;
1015 perm.seq = 0;
1016 perm.key = 0;
1017 tok = au_to_ipc_perm(&perm);
1018 kau_write(rec, tok);
1019 }
1020 break;
1021
1022 case AUE_SEMCLOSE:
1023 tok = au_to_arg32(1, "sem", ar->ar_arg_fd);
1024 kau_write(rec, tok);
1025 break;
1026
1027 case AUE_SYMLINK:
1028 if (ar->ar_valid_arg & ARG_TEXT) {
1029 tok = au_to_text(ar->ar_arg_text);
1030 kau_write(rec, tok);
1031 }
1032 KPATH1_VNODE1_OR_UPATH1_TOKENS;
1033 break;
1034
1035 case AUE_SYSCTL:
1036 if (ar->ar_valid_arg & (ARG_CTLNAME | ARG_LEN)) {
1037 for (ctr = 0; ctr < ar->ar_arg_len; ctr++) {
1038 tok = au_to_arg32(1, "name", ar->ar_arg_ctlname[ctr]);
1039 kau_write(rec, tok);
1040 }
1041 }
1042 if (ar->ar_valid_arg & ARG_VALUE) {
1043 tok = au_to_arg32(5, "newval", ar->ar_arg_value);
1044 kau_write(rec, tok);
1045 }
1046 if (ar->ar_valid_arg & ARG_TEXT) {
1047 tok = au_to_text(ar->ar_arg_text);
1048 kau_write(rec, tok);
1049 }
1050 break;
1051
1052 case AUE_UMASK:
1053 tok = au_to_arg32(1, "new mask", ar->ar_arg_mask);
1054 kau_write(rec, tok);
1055 tok = au_to_arg32(0, "prev mask", ar->ar_retval);
1056 kau_write(rec, tok);
1057 break;
1058
1059 /************************
1060 * Mach system calls *
1061 ************************/
1062 case AUE_INITPROCESS:
1063 break;
1064
1065 case AUE_PIDFORTASK:
1066 tok = au_to_arg32(1, "port", (u_int32_t)ar->ar_arg_mach_port1);
1067 kau_write(rec, tok);
1068 if (ar->ar_valid_arg & ARG_PID) {
1069 tok = au_to_arg32(2, "pid", (u_int32_t)ar->ar_arg_pid);
1070 kau_write(rec, tok);
1071 }
1072 break;
1073
1074 case AUE_TASKFORPID:
1075 tok = au_to_arg32(1, "target port",
1076 (u_int32_t)ar->ar_arg_mach_port1);
1077 kau_write(rec, tok);
1078 if (ar->ar_valid_arg & ARG_MACHPORT2) {
1079 tok = au_to_arg32(3, "task port",
1080 (u_int32_t)ar->ar_arg_mach_port2);
1081 kau_write(rec, tok);
1082 }
1083 PROCESS_PID_TOKENS(2);
1084 break;
1085
1086 case AUE_SWAPON:
1087 tok = au_to_arg32(4, "priority",
1088 (u_int32_t)ar->ar_arg_value);
1089 kau_write(rec, tok);
1090 KPATH1_VNODE1_OR_UPATH1_TOKENS;
1091 break;
1092
1093 case AUE_SWAPOFF:
1094 KPATH1_VNODE1_OR_UPATH1_TOKENS;
1095 break;
1096
1097 case AUE_MAPFD:
1098 tok = au_to_arg32(3, "va", (u_int32_t)ar->ar_arg_addr);
1099 kau_write(rec, tok);
1100 FD_KPATH1_VNODE1_TOKENS;
1101 break;
1102
1103 default: /* We shouldn't fall through to here. */
1104 printf("BSM conversion requested for unknown event %d\n",
1105 ar->ar_event);
1106 kau_free(rec);
1107 return BSM_NOAUDIT;
1108 }
1109
1110 kau_write(rec, subj_tok);
1111 tok = au_to_return32((char)ar->ar_errno, ar->ar_retval);
1112 kau_write(rec, tok); /* Every record gets a return token */
1113
1114 kau_close(rec, &ar->ar_endtime, ar->ar_event);
1115
1116 *pau = rec;
1117 return BSM_SUCCESS;
1118 }
1119
1120 /*
1121 * Verify that a record is a valid BSM record. This verification is
1122 * simple now, but may be expanded on sometime in the future.
1123 * Return 1 if the record is good, 0 otherwise.
1124 *
1125 */
1126 int
1127 bsm_rec_verify(void *rec)
1128 {
1129 char c = *(char *)rec;
1130 /*
1131 * Check the token ID of the first token; it has to be a header
1132 * token.
1133 */
1134 /* XXXAUDIT There needs to be a token structure to map a token.
1135 * XXXAUDIT 'Shouldn't be simply looking at the first char.
1136 */
1137 if ( (c != AU_HEADER_32_TOKEN) &&
1138 (c != AU_HEADER_EX_32_TOKEN) &&
1139 (c != AU_HEADER_64_TOKEN) &&
1140 (c != AU_HEADER_EX_64_TOKEN) ) {
1141 return (0);
1142 }
1143 return (1);
1144 }