2 * Copyright (c) 2003-2007 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
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,
34 #include <sys/types.h>
35 #include <sys/vnode_internal.h>
38 #include <sys/socketvar.h>
39 #include <sys/socket.h>
40 #include <sys/queue.h>
41 #include <sys/fcntl.h>
45 #include <bsm/audit.h>
46 #include <bsm/audit_record.h>
47 #include <bsm/audit_kernel.h>
48 #include <bsm/audit_kevents.h>
49 #include <bsm/audit_klib.h>
51 #include <netinet/in_systm.h>
52 #include <netinet/in.h>
53 #include <netinet/ip.h>
55 #include <kern/lock.h>
56 #include <kern/kalloc.h>
59 #include <security/mac_framework.h>
62 /* The number of BSM records allocated. */
63 static int bsm_rec_count
= 0;
66 * Records that can be recycled are maintained in the list given below
67 * The maximum number of elements that can be present in this list is
68 * bounded by MAX_AUDIT_RECORDS. Memory allocated for these records are never
71 LIST_HEAD(, au_record
) bsm_free_q
;
74 * Lock for serializing access to the list of audit records.
76 static lck_grp_t
*bsm_audit_grp
;
77 static lck_attr_t
*bsm_audit_attr
;
78 static lck_grp_attr_t
*bsm_audit_grp_attr
;
79 static lck_mtx_t
*bsm_audit_mutex
;
81 static void audit_sys_auditon(struct audit_record
*ar
, struct au_record
*rec
);
84 * Initialize the BSM auditing subsystem.
89 printf("BSM auditing present\n");
90 LIST_INIT(&bsm_free_q
);
91 bsm_audit_grp_attr
= lck_grp_attr_alloc_init();
92 bsm_audit_grp
= lck_grp_alloc_init("BSM Audit", bsm_audit_grp_attr
);
93 bsm_audit_attr
= lck_attr_alloc_init();
94 bsm_audit_mutex
= lck_mtx_alloc_init(bsm_audit_grp
, bsm_audit_attr
);
99 * This call reserves memory for the audit record.
100 * Memory must be guaranteed before any auditable event can be
102 * The au_record structure maintains a reference to the
103 * memory allocated above and also the list of tokens associated
109 struct au_record
*rec
= NULL
;
112 * Find an unused record, remove it from the free list, mark as used
114 lck_mtx_lock(bsm_audit_mutex
);
115 if (!LIST_EMPTY(&bsm_free_q
)) {
116 rec
= LIST_FIRST(&bsm_free_q
);
117 LIST_REMOVE(rec
, au_rec_q
);
119 lck_mtx_unlock(bsm_audit_mutex
);
122 lck_mtx_lock(bsm_audit_mutex
);
123 if (bsm_rec_count
>= MAX_AUDIT_RECORDS
) {
124 /* XXX We need to increase size of MAX_AUDIT_RECORDS */
125 lck_mtx_unlock(bsm_audit_mutex
);
128 lck_mtx_unlock(bsm_audit_mutex
);
131 * Create a new BSM kernel record.
133 rec
= (struct au_record
*)kalloc(sizeof(*rec
));
137 rec
->data
= (u_char
*)kalloc(MAX_AUDIT_RECORD_SIZE
* sizeof(u_char
));
138 if((rec
->data
) == NULL
) {
139 kfree(rec
, sizeof(*rec
));
142 lck_mtx_lock(bsm_audit_mutex
);
144 lck_mtx_unlock(bsm_audit_mutex
);
146 memset(rec
->data
, 0, MAX_AUDIT_RECORD_SIZE
);
148 TAILQ_INIT(&rec
->token_q
);
156 * Store the token with the record descriptor
159 int kau_write(struct au_record
*rec
, struct au_token
*tok
)
162 return -1; /* Invalid Token */
165 /* Add the token to the tail */
167 * XXX Not locking here -- we should not be writing to
168 * XXX the same audit record from different threads
170 TAILQ_INSERT_TAIL(&rec
->token_q
, tok
, tokens
);
172 rec
->len
+= tok
->len
; /* grow record length by token size bytes */
178 * Close out the audit record by adding the header token, identifying
179 * any missing tokens. Write out the tokens to the record memory.
182 kau_close(struct au_record
*rec
, struct timespec
*ctime
, short event
)
186 token_t
*cur
, *hdr
, *trail
;
189 tot_rec_size
= rec
->len
+ HEADER_SIZE
+ TRAILER_SIZE
;
190 if(tot_rec_size
<= MAX_AUDIT_RECORD_SIZE
) {
191 /* Create the header token */
192 hdr
= kau_to_header32(ctime
, tot_rec_size
, event
, 0);
195 /* Add to head of list */
196 TAILQ_INSERT_HEAD(&rec
->token_q
, hdr
, tokens
);
198 trail
= au_to_trailer(tot_rec_size
);
200 TAILQ_INSERT_TAIL(&rec
->token_q
, trail
, tokens
);
203 /* Serialize token data to the record */
205 rec
->len
= tot_rec_size
;
207 TAILQ_FOREACH(cur
, &rec
->token_q
, tokens
) {
208 memcpy(dptr
, cur
->t_data
, cur
->len
);
217 * Free a BSM audit record by releasing all the tokens and clearing the
218 * audit record information.
220 void kau_free(struct au_record
*rec
)
222 struct au_token
*tok
;
224 /* Free the token list */
225 while ((tok
= TAILQ_FIRST(&rec
->token_q
))) {
226 TAILQ_REMOVE(&rec
->token_q
, tok
, tokens
);
227 kfree(tok
, sizeof(*tok
) + tok
->len
);
233 lck_mtx_lock(bsm_audit_mutex
);
235 /* Add the record to the freelist */
236 LIST_INSERT_HEAD(&bsm_free_q
, rec
, au_rec_q
);
238 lck_mtx_unlock(bsm_audit_mutex
);
243 * XXX May want turn some (or all) of these macros into functions in order
244 * to reduce the generated code size.
247 #define MAC_VNODE1_LABEL_TOKEN \
249 if (ar->ar_vnode1_mac_labels != NULL) { \
250 tok = au_to_text(ar->ar_vnode1_mac_labels); \
251 kau_write(rec, tok); \
255 #define MAC_VNODE2_LABEL_TOKEN \
257 if (ar->ar_vnode2_mac_labels != NULL) { \
258 tok = au_to_text(ar->ar_vnode2_mac_labels); \
259 kau_write(rec, tok); \
263 #define MAC_VNODE1_LABEL_TOKEN
264 #define MAC_VNODE2_LABEL_TOKEN
266 #define UPATH1_TOKENS \
268 if (ar->ar_valid_arg & ARG_UPATH1) { \
269 tok = au_to_path(ar->ar_arg_upath1); \
270 kau_write(rec, tok); \
274 #define UPATH2_TOKENS \
276 if (ar->ar_valid_arg & ARG_UPATH2) { \
277 tok = au_to_path(ar->ar_arg_upath2); \
278 kau_write(rec, tok); \
282 #define UPATH1_KPATH1_VNODE1_TOKENS \
284 if (ar->ar_valid_arg & ARG_UPATH1) { \
285 tok = au_to_path(ar->ar_arg_upath1); \
286 kau_write(rec, tok); \
288 if (ar->ar_valid_arg & ARG_KPATH1) { \
289 tok = au_to_path(ar->ar_arg_kpath1); \
290 kau_write(rec, tok); \
292 if (ar->ar_valid_arg & ARG_VNODE1) { \
293 tok = kau_to_attr32(&ar->ar_arg_vnode1);\
294 kau_write(rec, tok); \
295 MAC_VNODE1_LABEL_TOKEN; \
299 #define KPATH1_VNODE1_TOKENS \
301 if (ar->ar_valid_arg & ARG_KPATH1) { \
302 tok = au_to_path(ar->ar_arg_kpath1); \
303 kau_write(rec, tok); \
305 if (ar->ar_valid_arg & ARG_VNODE1) { \
306 tok = kau_to_attr32(&ar->ar_arg_vnode1);\
307 kau_write(rec, tok); \
308 MAC_VNODE1_LABEL_TOKEN; \
312 #define KPATH2_VNODE2_TOKENS \
314 if (ar->ar_valid_arg & ARG_KPATH2) { \
315 tok = au_to_path(ar->ar_arg_kpath2); \
316 kau_write(rec, tok); \
318 if (ar->ar_valid_arg & ARG_VNODE2) { \
319 tok = kau_to_attr32(&ar->ar_arg_vnode2);\
320 kau_write(rec, tok); \
321 MAC_VNODE2_LABEL_TOKEN; \
325 #define FD_KPATH1_VNODE1_TOKENS \
327 if (ar->ar_valid_arg & ARG_KPATH1) { \
328 tok = au_to_path(ar->ar_arg_kpath1); \
329 kau_write(rec, tok); \
330 if (ar->ar_valid_arg & ARG_VNODE1) { \
331 tok = kau_to_attr32(&ar->ar_arg_vnode1);\
332 kau_write(rec, tok); \
333 MAC_VNODE1_LABEL_TOKEN; \
336 tok = au_to_arg32(1, "no path: fd", ar->ar_arg_fd); \
337 kau_write(rec, tok); \
341 #define PROCESS_PID_TOKENS(argn) \
343 if ((ar->ar_arg_pid > 0) /* Kill a single process */ \
344 && (ar->ar_valid_arg & ARG_PROCESS)) { \
345 tok = au_to_process(ar->ar_arg_auid, ar->ar_arg_euid, \
346 ar->ar_arg_egid, ar->ar_arg_ruid, \
347 ar->ar_arg_rgid, ar->ar_arg_pid, \
348 ar->ar_arg_asid, &ar->ar_arg_termid); \
349 kau_write(rec, tok); \
351 tok = au_to_arg32(argn, "process", ar->ar_arg_pid);\
352 kau_write(rec, tok); \
356 #define PROCESS_MAC_TOKENS \
358 if (ar->ar_valid_arg & ARG_MAC_STRING) { \
359 tok = au_to_text(ar->ar_arg_mac_string); \
360 kau_write(rec, tok); \
365 * Implement auditing for the auditon() system call. The audit tokens
366 * that are generated depend on the command that was sent into the
367 * auditon() system call.
371 audit_sys_auditon(struct audit_record
*ar
, struct au_record
*rec
)
373 struct au_token
*tok
;
375 switch (ar
->ar_arg_cmd
) {
377 if (sizeof(ar
->ar_arg_auditon
.au_flags
) > 4)
378 tok
= au_to_arg64(1, "policy",
379 ar
->ar_arg_auditon
.au_flags
);
381 tok
= au_to_arg32(1, "policy",
382 ar
->ar_arg_auditon
.au_flags
);
386 tok
= au_to_arg32(2, "setkmask:as_success",
387 ar
->ar_arg_auditon
.au_mask
.am_success
);
389 tok
= au_to_arg32(2, "setkmask:as_failure",
390 ar
->ar_arg_auditon
.au_mask
.am_failure
);
394 tok
= au_to_arg32(3, "setqctrl:aq_hiwater",
395 ar
->ar_arg_auditon
.au_qctrl
.aq_hiwater
);
397 tok
= au_to_arg32(3, "setqctrl:aq_lowater",
398 ar
->ar_arg_auditon
.au_qctrl
.aq_lowater
);
400 tok
= au_to_arg32(3, "setqctrl:aq_bufsz",
401 ar
->ar_arg_auditon
.au_qctrl
.aq_bufsz
);
403 tok
= au_to_arg32(3, "setqctrl:aq_delay",
404 ar
->ar_arg_auditon
.au_qctrl
.aq_delay
);
406 tok
= au_to_arg32(3, "setqctrl:aq_minfree",
407 ar
->ar_arg_auditon
.au_qctrl
.aq_minfree
);
411 tok
= au_to_arg32(3, "setumask:as_success",
412 ar
->ar_arg_auditon
.au_auinfo
.ai_mask
.am_success
);
414 tok
= au_to_arg32(3, "setumask:as_failure",
415 ar
->ar_arg_auditon
.au_auinfo
.ai_mask
.am_failure
);
419 tok
= au_to_arg32(3, "setsmask:as_success",
420 ar
->ar_arg_auditon
.au_auinfo
.ai_mask
.am_success
);
422 tok
= au_to_arg32(3, "setsmask:as_failure",
423 ar
->ar_arg_auditon
.au_auinfo
.ai_mask
.am_failure
);
427 if (sizeof(ar
->ar_arg_auditon
.au_cond
) > 4)
428 tok
= au_to_arg64(3, "setcond",
429 ar
->ar_arg_auditon
.au_cond
);
431 tok
= au_to_arg32(3, "setcond",
432 ar
->ar_arg_auditon
.au_cond
);
436 tok
= au_to_arg32(2, "setclass:ec_event",
437 ar
->ar_arg_auditon
.au_evclass
.ec_number
);
439 tok
= au_to_arg32(3, "setclass:ec_class",
440 ar
->ar_arg_auditon
.au_evclass
.ec_class
);
444 tok
= au_to_arg32(2, "setpmask:as_success",
445 ar
->ar_arg_auditon
.au_aupinfo
.ap_mask
.am_success
);
447 tok
= au_to_arg32(2, "setpmask:as_failure",
448 ar
->ar_arg_auditon
.au_aupinfo
.ap_mask
.am_failure
);
452 tok
= au_to_arg32(2, "setfsize:filesize",
453 ar
->ar_arg_auditon
.au_fstat
.af_filesz
);
462 * Convert an internal kernel audit record to a BSM record and return
463 * a success/failure indicator. The BSM record is passed as an out
464 * parameter to this function.
466 * BSM_SUCCESS: The BSM record is valid
467 * BSM_FAILURE: Failure; the BSM record is NULL.
468 * BSM_NOAUDIT: The event is not auditable for BSM; the BSM record is NULL.
471 kaudit_to_bsm(struct kaudit_record
*kar
, struct au_record
**pau
)
473 struct au_token
*tok
= NULL
, *subj_tok
;
474 struct au_record
*rec
;
476 struct audit_record
*ar
;
480 return (BSM_FAILURE
);
486 return (BSM_FAILURE
);
488 /* Create the subject token */
489 tid
.port
= ar
->ar_subj_term
.port
;
490 tid
.machine
= ar
->ar_subj_term
.machine
;
491 subj_tok
= au_to_subject32(ar
->ar_subj_auid
, /* audit ID */
492 ar
->ar_subj_cred
.cr_uid
, /* eff uid */
493 ar
->ar_subj_egid
, /* eff group id */
494 ar
->ar_subj_ruid
, /* real uid */
495 ar
->ar_subj_rgid
, /* real group id */
496 ar
->ar_subj_pid
, /* process id */
497 ar
->ar_subj_asid
, /* session ID */
500 /* The logic inside each case fills in the tokens required for the
501 * event, except for the header, trailer, and return tokens. The
502 * header and trailer tokens are added by the kau_close() function.
503 * The return token is added outside of the switch statement.
505 switch(ar
->ar_event
) {
508 * Socket-related events.
517 tok
= au_to_arg32(1, "fd", ar
->ar_arg_fd
);
519 if (ar
->ar_valid_arg
& ARG_SADDRINET
) {
520 tok
= au_to_sock_inet(
521 (struct sockaddr_in
*)&ar
->ar_arg_sockaddr
);
524 if (ar
->ar_valid_arg
& ARG_SADDRUNIX
) {
525 tok
= au_to_sock_unix(
526 (struct sockaddr_un
*)&ar
->ar_arg_sockaddr
);
530 /* XXX Need to handle ARG_SADDRINET6 */
535 tok
= au_to_arg32(1,"domain", ar
->ar_arg_sockinfo
.so_domain
);
537 tok
= au_to_arg32(2,"type", ar
->ar_arg_sockinfo
.so_type
);
539 tok
= au_to_arg32(3,"protocol",ar
->ar_arg_sockinfo
.so_protocol
);
545 tok
= au_to_arg32(1, "fd", ar
->ar_arg_fd
);
550 if (ar
->ar_valid_arg
& (ARG_KPATH1
| ARG_UPATH1
)) {
551 UPATH1_KPATH1_VNODE1_TOKENS
;
553 tok
= au_to_arg32(1, "accounting off", 0);
559 tok
= au_to_arg32(2, "setauid", ar
->ar_arg_auid
);
564 if (ar
->ar_valid_arg
& ARG_AUID
) {
565 tok
= au_to_arg32(1, "setaudit:auid", ar
->ar_arg_auid
);
567 tok
= au_to_arg32(1, "setaudit:port",
568 ar
->ar_arg_termid
.port
);
570 tok
= au_to_arg32(1, "setaudit:machine",
571 ar
->ar_arg_termid
.machine
);
573 tok
= au_to_arg32(1, "setaudit:as_success",
574 ar
->ar_arg_amask
.am_success
);
576 tok
= au_to_arg32(1, "setaudit:as_failure",
577 ar
->ar_arg_amask
.am_failure
);
579 tok
= au_to_arg32(1, "setaudit:asid", ar
->ar_arg_asid
);
584 case AUE_SETAUDIT_ADDR
:
585 break; /* XXX need to add arguments */
588 /* For AUDITON commands without own event, audit the cmd */
589 tok
= au_to_arg32(1, "cmd", ar
->ar_arg_cmd
);
593 case AUE_AUDITON_GETCAR
:
594 case AUE_AUDITON_GETCLASS
:
595 case AUE_AUDITON_GETCOND
:
596 case AUE_AUDITON_GETCWD
:
597 case AUE_AUDITON_GETKMASK
:
598 case AUE_AUDITON_GETSTAT
:
599 case AUE_AUDITON_GPOLICY
:
600 case AUE_AUDITON_GQCTRL
:
601 case AUE_AUDITON_SETCLASS
:
602 case AUE_AUDITON_SETCOND
:
603 case AUE_AUDITON_SETKMASK
:
604 case AUE_AUDITON_SETSMASK
:
605 case AUE_AUDITON_SETSTAT
:
606 case AUE_AUDITON_SETUMASK
:
607 case AUE_AUDITON_SPOLICY
:
608 case AUE_AUDITON_SQCTRL
:
609 if (ar
->ar_valid_arg
& ARG_AUDITON
) {
610 audit_sys_auditon(ar
, rec
);
615 UPATH1_KPATH1_VNODE1_TOKENS
;
622 case AUE_GETAUDIT_ADDR
:
625 case AUE_MAC_GETFSSTAT
:
630 case AUE_SETTIMEOFDAY
:
631 /* Header, subject, and return tokens added at end */
638 case AUE_GETATTRLIST
:
647 case AUE_SETATTRLIST
:
654 UPATH1_KPATH1_VNODE1_TOKENS
;
658 tok
= au_to_arg32(2, "flags", ar
->ar_arg_fflags
);
660 UPATH1_KPATH1_VNODE1_TOKENS
;
664 tok
= au_to_arg32(2, "new file mode", ar
->ar_arg_mode
);
666 UPATH1_KPATH1_VNODE1_TOKENS
;
671 tok
= au_to_arg32(2, "new file uid", ar
->ar_arg_uid
);
673 tok
= au_to_arg32(3, "new file gid", ar
->ar_arg_gid
);
675 UPATH1_KPATH1_VNODE1_TOKENS
;
678 case AUE_EXCHANGEDATA
:
679 UPATH1_KPATH1_VNODE1_TOKENS
;
680 KPATH2_VNODE2_TOKENS
;
684 tok
= au_to_arg32(2, "fd", ar
->ar_arg_fd
);
686 UPATH1_KPATH1_VNODE1_TOKENS
;
690 tok
= au_to_arg32(2, "new file mode", ar
->ar_arg_mode
);
692 FD_KPATH1_VNODE1_TOKENS
;
696 tok
= au_to_arg32(1, "request", ar
->ar_arg_cmd
);
698 if (ar
->ar_valid_arg
& (ARG_KPATH1
| ARG_UPATH1
)) {
699 UPATH1_KPATH1_VNODE1_TOKENS
;
705 case AUE_FSTAT
: /* XXX Need to handle sockets and shm */
709 case AUE_GETDIRENTRIES
:
710 case AUE_GETDIRENTRIESATTR
:
711 case AUE_EXTATTR_GET_FD
:
712 case AUE_EXTATTR_LIST_FD
:
713 case AUE_EXTATTR_SET_FD
:
714 case AUE_EXTATTR_DELETE_FD
:
715 FD_KPATH1_VNODE1_TOKENS
;
719 tok
= au_to_arg32(2, "new file uid", ar
->ar_arg_uid
);
721 tok
= au_to_arg32(3, "new file gid", ar
->ar_arg_gid
);
723 FD_KPATH1_VNODE1_TOKENS
;
727 tok
= au_to_arg32(2, "cmd", ar
->ar_arg_cmd
);
729 if (ar
->ar_valid_arg
& ARG_VNODE1
) {
730 FD_KPATH1_VNODE1_TOKENS
;
735 tok
= au_to_arg32(2, "flags", ar
->ar_arg_fflags
);
737 FD_KPATH1_VNODE1_TOKENS
;
741 tok
= au_to_arg32(2, "operation", ar
->ar_arg_cmd
);
743 FD_KPATH1_VNODE1_TOKENS
;
748 tok
= au_to_arg32(0, "child PID", ar
->ar_arg_pid
);
753 tok
= au_to_arg32(1, "pid", (u_int32_t
)ar
->ar_arg_pid
);
758 tok
= au_to_arg32(1, "pid", (u_int32_t
)ar
->ar_arg_pid
);
760 tok
= au_to_arg32(2, "lcid", (u_int32_t
)ar
->ar_arg_value
);
765 tok
= au_to_arg32(2, "cmd", ar
->ar_arg_cmd
);
767 tok
= au_to_arg32(1, "arg", (u_int32_t
)ar
->ar_arg_addr
);
769 if (ar
->ar_valid_arg
& ARG_VNODE1
) {
770 FD_KPATH1_VNODE1_TOKENS
;
772 if (ar
->ar_valid_arg
& ARG_SOCKINFO
) {
773 tok
= kau_to_socket(&ar
->ar_arg_sockinfo
);
776 tok
= au_to_arg32(1, "fd", ar
->ar_arg_fd
);
783 tok
= au_to_arg32(2, "signal", ar
->ar_arg_signum
);
785 PROCESS_PID_TOKENS(1);
790 UPATH1_KPATH1_VNODE1_TOKENS
;
795 tok
= au_to_arg32(2, "mode", ar
->ar_arg_mode
);
797 UPATH1_KPATH1_VNODE1_TOKENS
;
801 tok
= au_to_arg32(2, "mode", ar
->ar_arg_mode
);
803 tok
= au_to_arg32(3, "dev", ar
->ar_arg_dev
);
805 UPATH1_KPATH1_VNODE1_TOKENS
;
814 tok
= au_to_arg32(1, "addr", (u_int32_t
)ar
->ar_arg_addr
); /* LP64todo */
816 tok
= au_to_arg32(2, "len", ar
->ar_arg_len
); /* LP64todo */
818 if (ar
->ar_event
== AUE_MMAP
)
819 FD_KPATH1_VNODE1_TOKENS
;
820 if (ar
->ar_event
== AUE_MPROTECT
) {
821 tok
= au_to_arg32(3, "protection", ar
->ar_arg_value
);
824 if (ar
->ar_event
== AUE_MINHERIT
) {
825 tok
= au_to_arg32(3, "inherit", ar
->ar_arg_value
);
836 /* XXX Need to handle NFS mounts */
837 tok
= au_to_arg32(3, "flags", ar
->ar_arg_fflags
);
839 if (ar
->ar_valid_arg
& ARG_TEXT
) {
840 tok
= au_to_text(ar
->ar_arg_text
);
845 UPATH1_KPATH1_VNODE1_TOKENS
;
849 ar
->ar_event
= msgctl_to_event(ar
->ar_arg_svipc_cmd
);
853 tok
= au_to_arg32(1, "msg ID", ar
->ar_arg_svipc_id
);
855 if (ar
->ar_errno
!= EINVAL
) {
856 tok
= au_to_ipc(AT_IPC_MSG
, ar
->ar_arg_svipc_id
);
862 if (ar
->ar_errno
== 0) {
863 tok
= au_to_ipc(AT_IPC_MSG
, ar
->ar_arg_svipc_id
);
874 tok
= au_to_arg32(3, "mode", ar
->ar_arg_mode
);
885 tok
= au_to_arg32(2, "flags", ar
->ar_arg_fflags
);
887 UPATH1_KPATH1_VNODE1_TOKENS
;
891 tok
= au_to_arg32(1, "request", ar
->ar_arg_cmd
);
893 tok
= au_to_arg32(3, "addr", (u_int32_t
)ar
->ar_arg_addr
); /* LP64todo */
895 tok
= au_to_arg32(4, "data", ar
->ar_arg_value
);
897 PROCESS_PID_TOKENS(2);
901 tok
= au_to_arg32(2, "command", ar
->ar_arg_cmd
);
903 tok
= au_to_arg32(3, "uid", ar
->ar_arg_uid
);
905 UPATH1_KPATH1_VNODE1_TOKENS
;
909 tok
= au_to_arg32(1, "howto", ar
->ar_arg_cmd
);
914 ar
->ar_event
= semctl_to_event(ar
->ar_arg_svipc_cmd
);
917 tok
= au_to_arg32(1, "sem ID", ar
->ar_arg_svipc_id
);
919 if (ar
->ar_errno
!= EINVAL
) {
920 tok
= au_to_ipc(AT_IPC_SEM
, ar
->ar_arg_svipc_id
);
925 if (ar
->ar_errno
== 0) {
926 tok
= au_to_ipc(AT_IPC_SEM
, ar
->ar_arg_svipc_id
);
931 tok
= au_to_arg32(1, "gid", ar
->ar_arg_egid
);
935 tok
= au_to_arg32(1, "uid", ar
->ar_arg_euid
);
939 tok
= au_to_arg32(1, "gid", ar
->ar_arg_gid
);
943 tok
= au_to_arg32(1, "uid", ar
->ar_arg_uid
);
947 if (ar
->ar_valid_arg
& ARG_GROUPSET
) {
950 for(ctr
= 0; ctr
< ar
->ar_arg_groups
.gidset_size
; ctr
++)
952 tok
= au_to_arg32(1, "setgroups", ar
->ar_arg_groups
.gidset
[ctr
]);
959 if (ar
->ar_valid_arg
& ARG_TEXT
) {
960 tok
= au_to_text(ar
->ar_arg_text
);
965 case AUE_SETPRIORITY
:
966 tok
= au_to_arg32(1, "which", ar
->ar_arg_cmd
);
968 tok
= au_to_arg32(2, "who", ar
->ar_arg_uid
);
970 tok
= au_to_arg32(2, "priority", ar
->ar_arg_value
);
974 case AUE_SETPRIVEXEC
:
975 tok
= au_to_arg32(1, "flag", ar
->ar_arg_value
);
979 /* AUE_SHMAT, AUE_SHMCTL, AUE_SHMDT and AUE_SHMGET are SysV IPC */
981 tok
= au_to_arg32(1, "shmid", ar
->ar_arg_svipc_id
);
983 tok
= au_to_arg64(2, "shmaddr", ar
->ar_arg_svipc_addr
);
985 if (ar
->ar_valid_arg
& ARG_SVIPC_PERM
) {
986 tok
= au_to_ipc(AT_IPC_SHM
, ar
->ar_arg_svipc_id
);
988 tok
= au_to_ipc_perm(&ar
->ar_arg_svipc_perm
);
994 tok
= au_to_arg32(1, "shmid", ar
->ar_arg_svipc_id
);
996 switch (ar
->ar_arg_svipc_cmd
) {
998 ar
->ar_event
= AUE_SHMCTL_STAT
;
999 if (ar
->ar_valid_arg
& ARG_SVIPC_PERM
) {
1000 tok
= au_to_ipc(AT_IPC_SHM
,
1001 ar
->ar_arg_svipc_id
);
1002 kau_write(rec
, tok
);
1006 ar
->ar_event
= AUE_SHMCTL_RMID
;
1007 if (ar
->ar_valid_arg
& ARG_SVIPC_PERM
) {
1008 tok
= au_to_ipc(AT_IPC_SHM
,
1009 ar
->ar_arg_svipc_id
);
1010 kau_write(rec
, tok
);
1014 ar
->ar_event
= AUE_SHMCTL_SET
;
1015 if (ar
->ar_valid_arg
& ARG_SVIPC_PERM
) {
1016 tok
= au_to_ipc(AT_IPC_SHM
,
1017 ar
->ar_arg_svipc_id
);
1018 kau_write(rec
, tok
);
1019 tok
= au_to_ipc_perm(&ar
->ar_arg_svipc_perm
);
1020 kau_write(rec
, tok
);
1024 break; /* We will audit a bad command */
1029 tok
= au_to_arg64(1, "shmaddr", ar
->ar_arg_svipc_addr
);
1030 kau_write(rec
, tok
);
1034 /* This is unusual; the return value is in an argument token */
1035 tok
= au_to_arg32(0, "shmid", ar
->ar_arg_svipc_id
);
1036 kau_write(rec
, tok
);
1037 if (ar
->ar_valid_arg
& ARG_SVIPC_PERM
) {
1038 tok
= au_to_ipc(AT_IPC_SHM
, ar
->ar_arg_svipc_id
);
1039 kau_write(rec
, tok
);
1040 tok
= au_to_ipc_perm(&ar
->ar_arg_svipc_perm
);
1041 kau_write(rec
, tok
);
1045 /* AUE_SHMOPEN, AUE_SHMUNLINK, AUE_SEMOPEN, AUE_SEMCLOSE
1046 * and AUE_SEMUNLINK are Posix IPC */
1048 tok
= au_to_arg32(2, "flags", ar
->ar_arg_fflags
);
1049 kau_write(rec
, tok
);
1050 tok
= au_to_arg32(3, "mode", ar
->ar_arg_mode
);
1051 kau_write(rec
, tok
);
1053 if (ar
->ar_valid_arg
& ARG_TEXT
) {
1054 tok
= au_to_text(ar
->ar_arg_text
);
1055 kau_write(rec
, tok
);
1057 if (ar
->ar_valid_arg
& ARG_POSIX_IPC_PERM
) {
1058 /* Create an ipc_perm token */
1059 struct ipc_perm perm
;
1060 perm
.uid
= ar
->ar_arg_pipc_perm
.pipc_uid
;
1061 perm
.gid
= ar
->ar_arg_pipc_perm
.pipc_gid
;
1062 perm
.cuid
= ar
->ar_arg_pipc_perm
.pipc_uid
;
1063 perm
.cgid
= ar
->ar_arg_pipc_perm
.pipc_gid
;
1064 perm
.mode
= ar
->ar_arg_pipc_perm
.pipc_mode
;
1067 tok
= au_to_ipc_perm(&perm
);
1068 kau_write(rec
, tok
);
1073 tok
= au_to_arg32(2, "flags", ar
->ar_arg_fflags
);
1074 kau_write(rec
, tok
);
1075 tok
= au_to_arg32(3, "mode", ar
->ar_arg_mode
);
1076 kau_write(rec
, tok
);
1077 tok
= au_to_arg32(4, "value", ar
->ar_arg_value
);
1078 kau_write(rec
, tok
);
1081 if (ar
->ar_valid_arg
& ARG_TEXT
) {
1082 tok
= au_to_text(ar
->ar_arg_text
);
1083 kau_write(rec
, tok
);
1085 if (ar
->ar_valid_arg
& ARG_POSIX_IPC_PERM
) {
1086 /* Create an ipc_perm token */
1087 struct ipc_perm perm
;
1088 perm
.uid
= ar
->ar_arg_pipc_perm
.pipc_uid
;
1089 perm
.gid
= ar
->ar_arg_pipc_perm
.pipc_gid
;
1090 perm
.cuid
= ar
->ar_arg_pipc_perm
.pipc_uid
;
1091 perm
.cgid
= ar
->ar_arg_pipc_perm
.pipc_gid
;
1092 perm
.mode
= ar
->ar_arg_pipc_perm
.pipc_mode
;
1095 tok
= au_to_ipc_perm(&perm
);
1096 kau_write(rec
, tok
);
1101 tok
= au_to_arg32(1, "sem", ar
->ar_arg_fd
);
1102 kau_write(rec
, tok
);
1106 if (ar
->ar_valid_arg
& ARG_TEXT
) {
1107 tok
= au_to_text(ar
->ar_arg_text
);
1108 kau_write(rec
, tok
);
1110 UPATH1_KPATH1_VNODE1_TOKENS
;
1114 case AUE_SYSCTL_NONADMIN
:
1115 if (ar
->ar_valid_arg
& (ARG_CTLNAME
| ARG_LEN
)) {
1118 for (ctr
= 0; ctr
< ar
->ar_arg_len
; ctr
++) {
1119 tok
= au_to_arg32(1, "name", ar
->ar_arg_ctlname
[ctr
]);
1120 kau_write(rec
, tok
);
1123 if (ar
->ar_valid_arg
& ARG_VALUE
) {
1124 tok
= au_to_arg32(5, "newval", ar
->ar_arg_value
);
1125 kau_write(rec
, tok
);
1127 if (ar
->ar_valid_arg
& ARG_TEXT
) {
1128 tok
= au_to_text(ar
->ar_arg_text
);
1129 kau_write(rec
, tok
);
1134 tok
= au_to_arg32(1, "new mask", ar
->ar_arg_mask
);
1135 kau_write(rec
, tok
);
1136 tok
= au_to_arg32(0, "prev mask", ar
->ar_retval
);
1137 kau_write(rec
, tok
);
1140 /************************
1141 * Mach system calls *
1142 ************************/
1143 case AUE_INITPROCESS
:
1146 case AUE_PIDFORTASK
:
1147 tok
= au_to_arg32(1, "port", (u_int32_t
)ar
->ar_arg_mach_port1
);
1148 kau_write(rec
, tok
);
1149 if (ar
->ar_valid_arg
& ARG_PID
) {
1150 tok
= au_to_arg32(2, "pid", (u_int32_t
)ar
->ar_arg_pid
);
1151 kau_write(rec
, tok
);
1155 case AUE_TASKFORPID
:
1156 tok
= au_to_arg32(1, "target port",
1157 (u_int32_t
)ar
->ar_arg_mach_port1
);
1158 kau_write(rec
, tok
);
1159 if (ar
->ar_valid_arg
& ARG_MACHPORT2
) {
1160 tok
= au_to_arg32(3, "task port",
1161 (u_int32_t
)ar
->ar_arg_mach_port2
);
1162 kau_write(rec
, tok
);
1164 PROCESS_PID_TOKENS(2);
1168 tok
= au_to_arg32(4, "priority",
1169 (u_int32_t
)ar
->ar_arg_value
);
1170 kau_write(rec
, tok
);
1171 UPATH1_KPATH1_VNODE1_TOKENS
;
1175 UPATH1_KPATH1_VNODE1_TOKENS
;
1179 tok
= au_to_arg32(3, "va", (u_int32_t
)ar
->ar_arg_addr
);
1180 kau_write(rec
, tok
);
1181 FD_KPATH1_VNODE1_TOKENS
;
1184 case AUE_EXTATTR_GET_FILE
:
1185 case AUE_EXTATTR_SET_FILE
:
1186 case AUE_EXTATTR_LIST_FILE
:
1187 case AUE_EXTATTR_DELETE_FILE
:
1188 case AUE_EXTATTR_GET_LINK
:
1189 case AUE_EXTATTR_SET_LINK
:
1190 case AUE_EXTATTR_LIST_LINK
:
1191 case AUE_EXTATTR_DELETE_LINK
:
1192 UPATH1_KPATH1_VNODE1_TOKENS
;
1196 case AUE_MAC_GET_FILE
:
1197 case AUE_MAC_SET_FILE
:
1198 case AUE_MAC_GET_LINK
:
1199 case AUE_MAC_SET_LINK
:
1200 case AUE_MAC_GET_MOUNT
:
1201 UPATH1_KPATH1_VNODE1_TOKENS
;
1205 case AUE_MAC_GET_FD
:
1206 case AUE_MAC_SET_FD
:
1207 FD_KPATH1_VNODE1_TOKENS
;
1211 case AUE_MAC_SYSCALL
:
1213 tok
= au_to_arg32(3, "call", ar
->ar_arg_value
);
1214 kau_write(rec
, tok
);
1217 case AUE_MAC_EXECVE
:
1218 UPATH1_KPATH1_VNODE1_TOKENS
;
1222 case AUE_MAC_GET_PID
:
1223 tok
= au_to_arg32(1, "pid", (u_int32_t
)ar
->ar_arg_pid
);
1224 kau_write(rec
, tok
);
1228 case AUE_MAC_GET_LCID
:
1229 tok
= au_to_arg32(1, "lcid", (u_int32_t
)ar
->ar_arg_value
);
1230 kau_write(rec
, tok
);
1234 case AUE_MAC_GET_PROC
:
1235 case AUE_MAC_SET_PROC
:
1236 case AUE_MAC_GET_LCTX
:
1237 case AUE_MAC_SET_LCTX
:
1242 default: /* We shouldn't fall through to here. */
1243 printf("BSM conversion requested for unknown event %d\n",
1251 /* Convert the audit data from the MAC policies */
1252 struct mac_audit_record
*mar
;
1254 LIST_FOREACH(mar
, ar
->ar_mac_records
, records
) {
1255 switch (mar
->type
) {
1256 case MAC_AUDIT_DATA_TYPE
:
1257 tok
= au_to_data(AUP_BINARY
, AUR_BYTE
,
1258 mar
->length
, mar
->data
);
1260 case MAC_AUDIT_TEXT_TYPE
:
1261 tok
= au_to_text((char*) mar
->data
);
1265 * XXX: we can either continue,
1266 * skipping this particular entry,
1267 * or we can pre-verify the list and
1268 * abort before writing any records
1270 printf("kaudit_to_bsm(): BSM conversion requested for unknown mac_audit data type %d\n",
1274 kau_write(rec
, tok
);
1279 kau_write(rec
, subj_tok
);
1282 if (ar
->ar_cred_mac_labels
!= NULL
) {
1283 tok
= au_to_text(ar
->ar_cred_mac_labels
);
1284 kau_write(rec
, tok
);
1288 tok
= au_to_return32((char)ar
->ar_errno
, ar
->ar_retval
);
1289 kau_write(rec
, tok
); /* Every record gets a return token */
1291 kau_close(rec
, &ar
->ar_endtime
, ar
->ar_event
);
1298 * Verify that a record is a valid BSM record. This verification is
1299 * simple now, but may be expanded on sometime in the future.
1300 * Return 1 if the record is good, 0 otherwise.
1304 bsm_rec_verify(void* rec
)
1306 char c
= *(char *)rec
;
1308 * Check the token ID of the first token; it has to be a header
1311 /* XXXAUDIT There needs to be a token structure to map a token.
1312 * XXXAUDIT 'Shouldn't be simply looking at the first char.
1314 if ( (c
!= AU_HEADER_32_TOKEN
) &&
1315 (c
!= AU_HEADER_EX_32_TOKEN
) &&
1316 (c
!= AU_HEADER_64_TOKEN
) &&
1317 (c
!= AU_HEADER_EX_64_TOKEN
) ) {