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 McAfee Research in 2004 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/param.h>
35 #include <sys/fcntl.h>
36 #include <sys/kernel.h>
38 #include <sys/namei.h>
39 #include <sys/proc_internal.h>
40 #include <sys/kauth.h>
41 #include <sys/queue.h>
42 #include <sys/systm.h>
44 #include <sys/ucred.h>
46 #include <sys/unistd.h>
47 #include <sys/file_internal.h>
48 #include <sys/vnode_internal.h>
50 #include <sys/syscall.h>
51 #include <sys/malloc.h>
53 #include <sys/sysent.h>
54 #include <sys/sysproto.h>
55 #include <sys/vfs_context.h>
56 #include <sys/domain.h>
57 #include <sys/protosw.h>
58 #include <sys/socketvar.h>
60 #include <bsm/audit.h>
61 #include <bsm/audit_kevents.h>
62 #include <bsm/audit_klib.h>
63 #include <bsm/audit_kernel.h>
65 #include <mach/host_priv.h>
66 #include <mach/host_special_ports.h>
67 #include <mach/audit_triggers_server.h>
69 #include <kern/host.h>
70 #include <kern/kalloc.h>
71 #include <kern/zalloc.h>
72 #include <kern/lock.h>
73 #include <kern/wait_queue.h>
74 #include <kern/sched_prim.h>
77 #include <bsm/audit_record.h>
78 #include <security/mac.h>
79 #include <security/mac_framework.h>
80 #include <security/mac_policy.h>
81 #define MAC_ARG_PREFIX "arg: "
82 #define MAC_ARG_PREFIX_LEN 5
85 #include <net/route.h>
87 #include <netinet/in.h>
88 #include <netinet/in_pcb.h>
93 * The AUDIT_EXCESSIVELY_VERBOSE define enables a number of
94 * gratuitously noisy printf's to the console. Due to the
95 * volume, it should be left off unless you want your system
96 * to churn a lot whenever the audit record flow gets high.
98 /* #define AUDIT_EXCESSIVELY_VERBOSE */
99 #ifdef AUDIT_EXCESSIVELY_VERBOSE
100 #define AUDIT_PRINTF_ONLY
101 #define AUDIT_PRINTF(x) printf x
103 #define AUDIT_PRINTF_ONLY __unused
104 #define AUDIT_PRINTF(X)
111 #define assert(cond) \
112 ((void) ((cond) ? 0 : panic("Assert failed: %s", # cond)))
114 #include <kern/assert.h>
115 #endif /* DIAGNOSTIC */
118 * Define the audit control flags.
124 * Mutex to protect global variables shared between various threads and
127 static lck_grp_t
*audit_grp
;
128 static lck_attr_t
*audit_attr
;
129 static lck_grp_attr_t
*audit_grp_attr
;
130 static lck_mtx_t
*audit_mtx
;
133 * Queue of audit records ready for delivery to disk. We insert new
134 * records at the tail, and remove records from the head. Also,
135 * a count of the number of records used for checking queue depth.
136 * In addition, a counter of records that we have allocated but are
137 * not yet in the queue, which is needed to estimate the total
138 * size of the combined set of records outstanding in the system.
140 static TAILQ_HEAD(, kaudit_record
) audit_q
;
141 static size_t audit_q_len
;
142 static size_t audit_pre_q_len
;
144 static wait_queue_t audit_wait_queue
;
145 static zone_t audit_zone
;
147 static zone_t audit_mac_label_zone
;
151 * Condition variable to signal to the worker that it has work to do:
152 * either new records are in the queue, or a log replacement is taking
155 static int audit_worker_event
;
156 #define AUDIT_WORKER_EVENT ((event_t)&audit_worker_event)
159 * The audit worker thread (which is lazy started when we first
160 * rotate the audit log.
162 static thread_t audit_worker_thread
= THREAD_NULL
;
165 * When an audit log is rotated, the actual rotation must be performed
166 * by the audit worker thread, as it may have outstanding writes on the
167 * current audit log. audit_replacement_vp holds the vnode replacing
168 * the current vnode. We can't let more than one replacement occur
169 * at a time, so if more than one thread requests a replacement, only
170 * one can have the replacement "in progress" at any given moment. If
171 * a thread tries to replace the audit vnode and discovers a replacement
172 * is already in progress (i.e., audit_replacement_flag != 0), then it
173 * will sleep on audit_replacement_cv waiting its turn to perform a
174 * replacement. When a replacement is completed, this cv is signalled
175 * by the worker thread so a waiting thread can start another replacement.
176 * We also store a credential to perform audit log write operations with.
178 static int audit_replacement_event
;
179 #define AUDIT_REPLACEMENT_EVENT ((event_t)&audit_replacement_event)
181 static int audit_replacement_flag
;
182 static struct vnode
*audit_replacement_vp
;
183 static kauth_cred_t audit_replacement_cred
;
186 * Wait queue for auditing threads that cannot commit the audit
187 * record at the present time. Also, the queue control parameter
190 static int audit_commit_event
;
191 #define AUDIT_COMMIT_EVENT ((event_t)&audit_commit_event)
193 static struct au_qctrl audit_qctrl
;
196 * Flags to use on audit files when opening and closing.
198 static const int audit_open_flags
= FWRITE
| O_APPEND
;
199 static const int audit_close_flags
= FWRITE
| O_APPEND
;
202 * Global audit statistiscs.
204 static struct audit_fstat audit_fstat
;
207 Preselection mask for non-attributable events.
209 static struct au_mask audit_nae_mask
;
212 * Flags related to Kernel->user-space communication.
214 static int audit_file_rotate_wait
;
217 * Flags controlling behavior in low storage situations.
218 * Should we panic if a write fails? Should we fail stop
219 * if we're out of disk space? Are we currently "failing
220 * stop" due to out of disk space?
222 static int audit_panic_on_write_fail
;
223 static int audit_fail_stop
;
224 static int audit_in_failure
;
227 * When in a fail-stop mode, threads will drop into this wait queue
228 * rather than perform auditable events. They won't ever get woken
231 static int audit_failure_event
;
232 #define AUDIT_FAILURE_EVENT ((event_t)&audit_failure_event)
235 * XXX: Couldn't find the include file for this, so copied kern_exec.c's
238 extern task_t kernel_task
;
240 extern zone_t mac_audit_data_zone
;
242 audit_free(struct kaudit_record
*ar
)
244 if (ar
->k_ar
.ar_arg_upath1
!= NULL
) {
245 kfree(ar
->k_ar
.ar_arg_upath1
, MAXPATHLEN
);
247 if (ar
->k_ar
.ar_arg_upath2
!= NULL
) {
248 kfree(ar
->k_ar
.ar_arg_upath2
, MAXPATHLEN
);
251 if (ar
->k_ar
.ar_arg_kpath1
!= NULL
) {
252 kfree(ar
->k_ar
.ar_arg_kpath1
, MAXPATHLEN
);
255 if (ar
->k_ar
.ar_arg_kpath2
!= NULL
) {
256 kfree(ar
->k_ar
.ar_arg_kpath2
, MAXPATHLEN
);
259 if (ar
->k_ar
.ar_arg_text
!= NULL
) {
260 kfree(ar
->k_ar
.ar_arg_text
, MAXPATHLEN
);
263 if (ar
->k_udata
!= NULL
) {
264 kfree(ar
->k_udata
, ar
->k_ulen
);
268 if (ar
->k_ar
.ar_vnode1_mac_labels
!= NULL
) {
269 zfree(audit_mac_label_zone
, ar
->k_ar
.ar_vnode1_mac_labels
);
271 if (ar
->k_ar
.ar_vnode2_mac_labels
!= NULL
) {
272 zfree(audit_mac_label_zone
, ar
->k_ar
.ar_vnode2_mac_labels
);
274 if (ar
->k_ar
.ar_cred_mac_labels
!= NULL
) {
275 zfree(audit_mac_label_zone
, ar
->k_ar
.ar_cred_mac_labels
);
277 if (ar
->k_ar
.ar_arg_mac_string
!= NULL
) {
278 kfree(ar
->k_ar
.ar_arg_mac_string
,
279 MAC_MAX_LABEL_BUF_LEN
+ MAC_ARG_PREFIX_LEN
);
282 /* Free the audit data from the MAC policies. */
284 struct mac_audit_record
*head
, *next
;
286 head
= LIST_FIRST(ar
->k_ar
.ar_mac_records
);
287 while (head
!= NULL
) {
288 next
= LIST_NEXT(head
, records
);
289 zfree(mac_audit_data_zone
, head
->data
);
290 kfree(head
, sizeof(*head
));
294 kfree(ar
->k_ar
.ar_mac_records
,
295 sizeof(*ar
->k_ar
.ar_mac_records
));
299 zfree(audit_zone
, ar
);
303 * Converts an audit record into the BSM format before writing out to the
304 * audit logfile. Will perform it's own vnode iocounting.
307 * -1 if it could not get an ioreference on the vnode.
308 * EINVAL if the kaudit_record ar is not a valid audit record.
311 audit_write(struct vnode
*vp
, struct kaudit_record
*ar
, vfs_context_t ctx
)
313 struct vfsstatfs
*mnt_stat
= &vp
->v_mount
->mnt_vfsstat
;
315 struct au_record
*bsm
;
318 mach_port_t audit_port
;
320 if (vnode_getwithref(vp
))
324 * First, gather statistics on the audit log file and file system
325 * so that we know how we're doing on space. In both cases,
326 * if we're unable to perform the operation, we drop the record
327 * and return. However, this is arguably an assertion failure.
329 ret
= vfs_update_vfsstat(vp
->v_mount
, ctx
, VFS_KERNEL_EVENT
);
333 /* update the global stats struct */
334 if ((ret
= vnode_size(vp
, &file_size
, ctx
)) != 0)
336 audit_fstat
.af_currsz
= file_size
;
339 * Send a message to the audit daemon when disk space is getting
341 * XXX Need to decide what to do if the trigger to the audit daemon
344 if(host_get_audit_control_port(host_priv_self(), &audit_port
)
346 printf("Cannot get audit control port\n");
348 if (audit_port
!= MACH_PORT_NULL
) {
352 * If we fall below percent free blocks, then trigger the
353 * audit daemon to do something about it.
355 if (audit_qctrl
.aq_minfree
!= 0) {
356 temp
= mnt_stat
->f_blocks
/ (100 / audit_qctrl
.aq_minfree
);
357 if (mnt_stat
->f_bfree
< temp
) {
358 ret
= audit_triggers(audit_port
,
359 AUDIT_TRIGGER_LOW_SPACE
);
360 if (ret
!= KERN_SUCCESS
) {
362 "Failed audit_triggers(AUDIT_TRIGGER_LOW_SPACE): %d\n", ret
);
364 * XXX: What to do here? Disable auditing?
370 /* Check if the current log file is full; if so, call for
371 * a log rotate. This is not an exact comparison; we may
372 * write some records over the limit. If that's not
373 * acceptable, then add a fudge factor here.
375 if ((audit_fstat
.af_filesz
!= 0) &&
376 (audit_file_rotate_wait
== 0) &&
377 (file_size
>= (off_t
)audit_fstat
.af_filesz
)) {
378 audit_file_rotate_wait
= 1;
379 ret
= audit_triggers(audit_port
,
380 AUDIT_TRIGGER_FILE_FULL
);
381 if (ret
!= KERN_SUCCESS
) {
383 "Failed audit_triggers(AUDIT_TRIGGER_FILE_FULL): %d\n", ret
);
384 /* XXX what to do here? */
390 * If the estimated amount of audit data in the audit event queue
391 * (plus records allocated but not yet queued) has reached the
392 * amount of free space on the disk, then we need to go into an
393 * audit fail stop state, in which we do not permit the
394 * allocation/committing of any new audit records. We continue to
395 * process packets but don't allow any activities that might
396 * generate new records. In the future, we might want to detect
397 * when space is available again and allow operation to continue,
398 * but this behavior is sufficient to meet fail stop requirements
401 if (audit_fail_stop
&&
403 ((audit_q_len
+ audit_pre_q_len
+ 1) * MAX_AUDIT_RECORD_SIZE
) /
404 mnt_stat
->f_bsize
>= (unsigned long)(mnt_stat
->f_bfree
)) {
406 "audit_worker: free space below size of audit queue, failing stop\n");
407 audit_in_failure
= 1;
411 * If there is a user audit record attached to the kernel record,
412 * then write the user record.
414 /* XXX Need to decide a few things here: IF the user audit
415 * record is written, but the write of the kernel record fails,
416 * what to do? Should the kernel record come before or after the
417 * user record? For now, we write the user record first, and
420 if (ar
->k_ar_commit
& AR_COMMIT_USER
) {
421 ret
= vn_rdwr(UIO_WRITE
, vp
, (void *)ar
->k_udata
, ar
->k_ulen
,
422 (off_t
)0, UIO_SYSSPACE32
, IO_APPEND
|IO_UNIT
, vfs_context_ucred(ctx
), NULL
, vfs_context_proc(ctx
));
428 * Convert the internal kernel record to BSM format and write it
429 * out if everything's OK.
431 if (!(ar
->k_ar_commit
& AR_COMMIT_KERNEL
)) {
436 ret
= kaudit_to_bsm(ar
, &bsm
);
437 if (ret
== BSM_NOAUDIT
) {
443 * XXX: We drop the record on BSM conversion failure, but really
444 * this is an assertion failure.
446 if (ret
== BSM_FAILURE
) {
447 AUDIT_PRINTF(("BSM conversion failure\n"));
452 /* XXX: We should break the write functionality
453 * away from the BSM record generation and have the BSM generation
454 * done before this function is called. This function will then
455 * take the BSM record as a parameter.
457 ret
= (vn_rdwr(UIO_WRITE
, vp
, (void *)bsm
->data
, bsm
->len
,
458 (off_t
)0, UIO_SYSSPACE32
, IO_APPEND
|IO_UNIT
, vfs_context_ucred(ctx
), NULL
, vfs_context_proc(ctx
)));
463 * When we're done processing the current record, we have to
464 * check to see if we're in a failure mode, and if so, whether
465 * this was the last record left to be drained. If we're done
466 * draining, then we fsync the vnode and panic.
468 if (audit_in_failure
&&
469 audit_q_len
== 0 && audit_pre_q_len
== 0) {
470 (void)VNOP_FSYNC(vp
, MNT_WAIT
, ctx
);
471 panic("Audit store overflow; record queue drained.");
481 int do_replacement_signal
, error
;
482 TAILQ_HEAD(, kaudit_record
) ar_worklist
;
483 struct kaudit_record
*ar
;
484 struct vnode
*audit_vp
, *old_vp
;
485 kauth_cred_t audit_cred
;
488 AUDIT_PRINTF(("audit_worker starting\n"));
490 TAILQ_INIT(&ar_worklist
);
492 audit_p
= current_proc();
496 lck_mtx_lock(audit_mtx
);
498 struct vfs_context context
;
501 * First priority: replace the audit log target if requested.
503 * XXX It could well be we should drain existing records
504 * first to ensure that the timestamps and ordering
507 do_replacement_signal
= 0;
508 while (audit_replacement_flag
!= 0) {
509 kauth_cred_t old_cred
= audit_cred
;
512 audit_cred
= audit_replacement_cred
;
513 audit_vp
= audit_replacement_vp
;
514 audit_replacement_cred
= NOCRED
;
515 audit_replacement_vp
= NULL
;
516 audit_replacement_flag
= 0;
518 audit_enabled
= (audit_vp
!= NULL
);
521 * XXX: What to do about write failures here?
523 if (old_vp
!= NULL
) {
524 AUDIT_PRINTF(("Closing old audit file vnode %p\n", old_vp
));
525 if (vnode_get(old_vp
) == 0) {
526 vn_close(old_vp
, audit_close_flags
, vfs_context_kernel());
528 AUDIT_PRINTF(("Audit file closed\n"));
531 printf("audit_worker(): Couldn't close audit file.\n");
532 kauth_cred_unref(&old_cred
);
535 if (audit_vp
!= NULL
) {
536 AUDIT_PRINTF(("Opening new audit file\n"));
538 do_replacement_signal
= 1;
541 * Signal that replacement have occurred to wake up and
542 * start any other replacements started in parallel. We can
543 * continue about our business in the mean time. We
544 * broadcast so that both new replacements can be inserted,
545 * but also so that the source(s) of replacement can return
548 if (do_replacement_signal
)
549 wait_queue_wakeup_all(audit_wait_queue
,
550 AUDIT_REPLACEMENT_EVENT
, THREAD_AWAKENED
);
553 * Next, check to see if we have any records to drain into
554 * the vnode. If not, go back to waiting for an event.
556 if (TAILQ_EMPTY(&audit_q
)) {
559 AUDIT_PRINTF(("audit_worker waiting\n"));
560 ret
= wait_queue_assert_wait(audit_wait_queue
,
564 lck_mtx_unlock(audit_mtx
);
566 assert(ret
== THREAD_WAITING
);
567 ret
= thread_block(THREAD_CONTINUE_NULL
);
568 assert(ret
== THREAD_AWAKENED
);
569 AUDIT_PRINTF(("audit_worker woken up\n"));
570 AUDIT_PRINTF(("audit_worker: new vp = %p; value of flag %d\n",
571 audit_replacement_vp
, audit_replacement_flag
));
573 lck_mtx_lock(audit_mtx
);
578 * If we have records, but there's no active vnode to
579 * write to, drain the record queue. Generally, we
580 * prevent the unnecessary allocation of records
581 * elsewhere, but we need to allow for races between
582 * conditional allocation and queueing. Go back to
583 * waiting when we're done.
585 * XXX: We go out of our way to avoid calling audit_free()
586 * with the audit_mtx held, to avoid a lock order reversal
587 * as free() may grab the funnel. This will be fixed at
590 if (audit_vp
== NULL
) {
591 while ((ar
= TAILQ_FIRST(&audit_q
))) {
592 TAILQ_REMOVE(&audit_q
, ar
, k_q
);
594 if (audit_q_len
<= audit_qctrl
.aq_lowater
)
595 wait_queue_wakeup_one(
600 TAILQ_INSERT_TAIL(&ar_worklist
, ar
, k_q
);
602 lck_mtx_unlock(audit_mtx
);
603 while ((ar
= TAILQ_FIRST(&ar_worklist
))) {
604 TAILQ_REMOVE(&ar_worklist
, ar
, k_q
);
607 lck_mtx_lock(audit_mtx
);
612 * We have both records to write, and an active vnode
613 * to write to. Dequeue a record, and start the write.
614 * Eventually, it might make sense to dequeue several
615 * records and perform our own clustering, if the lower
616 * layers aren't doing it automatically enough.
618 * XXX: We go out of our way to avoid calling audit_free()
619 * with the audit_mtx held, to avoid a lock order reversal
620 * as free() may grab the funnel. This will be fixed at
623 while ((ar
= TAILQ_FIRST(&audit_q
))) {
624 TAILQ_REMOVE(&audit_q
, ar
, k_q
);
626 if (audit_q_len
<= audit_qctrl
.aq_lowater
) {
627 wait_queue_wakeup_one(audit_wait_queue
,
628 AUDIT_COMMIT_EVENT
, THREAD_AWAKENED
);
631 TAILQ_INSERT_TAIL(&ar_worklist
, ar
, k_q
);
633 lck_mtx_unlock(audit_mtx
);
634 context
.vc_thread
= current_thread();
635 context
.vc_ucred
= audit_cred
;
636 while ((ar
= TAILQ_FIRST(&ar_worklist
))) {
637 TAILQ_REMOVE(&ar_worklist
, ar
, k_q
);
638 if (audit_vp
!= NULL
) {
640 * XXX: What should happen if there's a write
643 error
= audit_write(audit_vp
, ar
, &context
);
644 if (error
&& audit_panic_on_write_fail
) {
645 panic("audit_worker: write error %d\n",
648 printf("audit_worker: write error %d\n",
654 lck_mtx_lock(audit_mtx
);
661 printf("Security auditing service present\n");
662 TAILQ_INIT(&audit_q
);
666 audit_replacement_cred
= NULL
;
667 audit_replacement_flag
= 0;
668 audit_file_rotate_wait
= 0;
669 audit_replacement_vp
= NULL
;
670 audit_fstat
.af_filesz
= 0; /* '0' means unset, unbounded */
671 audit_fstat
.af_currsz
= 0;
672 audit_qctrl
.aq_hiwater
= AQ_HIWATER
;
673 audit_qctrl
.aq_lowater
= AQ_LOWATER
;
674 audit_qctrl
.aq_bufsz
= AQ_BUFSZ
;
675 audit_qctrl
.aq_minfree
= AU_FS_MINFREE
;
677 audit_grp_attr
= lck_grp_attr_alloc_init();
678 audit_grp
= lck_grp_alloc_init("audit", audit_grp_attr
);
679 audit_attr
= lck_attr_alloc_init();
680 audit_mtx
= lck_mtx_alloc_init(audit_grp
, audit_attr
);
682 audit_wait_queue
= wait_queue_alloc(SYNC_POLICY_FIFO
);
683 audit_zone
= zinit(sizeof(struct kaudit_record
),
684 AQ_HIWATER
*sizeof(struct kaudit_record
),
688 /* Assume 3 MAC labels for each audit record: two for vnodes,
691 audit_mac_label_zone
= zinit(MAC_AUDIT_LABEL_LEN
,
692 AQ_HIWATER
* 3*MAC_AUDIT_LABEL_LEN
,
694 "audit_mac_label_zone");
697 /* Initialize the BSM audit subsystem. */
702 audit_rotate_vnode(kauth_cred_t cred
, struct vnode
*vp
)
707 * If other parallel log replacements have been requested, we wait
708 * until they've finished before continuing.
710 lck_mtx_lock(audit_mtx
);
711 while (audit_replacement_flag
!= 0) {
713 AUDIT_PRINTF(("audit_rotate_vnode: sleeping to wait for "
715 ret
= wait_queue_assert_wait(audit_wait_queue
,
716 AUDIT_REPLACEMENT_EVENT
,
719 lck_mtx_unlock(audit_mtx
);
721 assert(ret
== THREAD_WAITING
);
722 ret
= thread_block(THREAD_CONTINUE_NULL
);
723 assert(ret
== THREAD_AWAKENED
);
724 AUDIT_PRINTF(("audit_rotate_vnode: woken up (flag %d)\n",
725 audit_replacement_flag
));
727 lck_mtx_lock(audit_mtx
);
729 audit_replacement_cred
= cred
;
730 audit_replacement_flag
= 1;
731 audit_replacement_vp
= vp
;
734 * Start or wake up the audit worker to perform the exchange.
735 * It will have to wait until we release the mutex.
737 if (audit_worker_thread
== THREAD_NULL
)
738 audit_worker_thread
= kernel_thread(kernel_task
,
741 wait_queue_wakeup_one(audit_wait_queue
,
746 * Wait for the audit_worker to broadcast that a replacement has
747 * taken place; we know that once this has happened, our vnode
748 * has been replaced in, so we can return successfully.
750 AUDIT_PRINTF(("audit_rotate_vnode: waiting for news of "
752 ret
= wait_queue_assert_wait(audit_wait_queue
,
753 AUDIT_REPLACEMENT_EVENT
,
756 lck_mtx_unlock(audit_mtx
);
758 assert(ret
== THREAD_WAITING
);
759 ret
= thread_block(THREAD_CONTINUE_NULL
);
760 assert(ret
== THREAD_AWAKENED
);
761 AUDIT_PRINTF(("audit_rotate_vnode: change acknowledged by "
762 "audit_worker (flag " "now %d)\n", audit_replacement_flag
));
764 audit_file_rotate_wait
= 0; /* We can now request another rotation */
768 * Drain the audit queue and close the log at shutdown.
774 audit_rotate_vnode(NULL
, NULL
);
777 static __inline__
struct uthread
*
780 return (get_bsdthread_info(current_thread()));
783 static __inline__
struct kaudit_record
*
786 return (curuthread()->uu_ar
);
789 /**********************************
790 * Begin system calls. *
791 **********************************/
793 * System call to allow a user space application to submit a BSM audit
794 * record to the kernel for inclusion in the audit log. This function
795 * does little verification on the audit record that is submitted.
797 * XXXAUDIT: Audit preselection for user records does not currently
798 * work, since we pre-select only based on the AUE_audit event type,
799 * not the event type submitted as part of the user audit data.
803 audit(proc_t p
, struct audit_args
*uap
, __unused register_t
*retval
)
807 struct kaudit_record
*ar
;
808 struct uthread
*uthr
;
810 error
= suser(kauth_cred_get(), &p
->p_acflag
);
814 lck_mtx_lock(audit_mtx
);
815 if ((uap
->length
<= 0) || (uap
->length
> (int)audit_qctrl
.aq_bufsz
)) {
816 lck_mtx_unlock(audit_mtx
);
819 lck_mtx_unlock(audit_mtx
);
823 /* If there's no current audit record (audit() itself not audited)
824 * commit the user audit record.
828 if (uthr
== NULL
) /* can this happen? */
831 /* This is not very efficient; we're required to allocate
832 * a complete kernel audit record just so the user record
835 uthr
->uu_ar
= audit_new(AUE_NULL
, p
, uthr
);
836 if (uthr
->uu_ar
== NULL
) /* auditing not on, or memory error */
841 if (uap
->length
> MAX_AUDIT_RECORD_SIZE
)
844 rec
= (void *)kalloc((vm_size_t
)uap
->length
);
846 error
= copyin(uap
->record
, rec
, uap
->length
);
851 error
= mac_system_check_audit(kauth_cred_get(), rec
, uap
->length
);
856 /* Verify the record */
857 if (bsm_rec_verify(rec
) == 0) {
862 /* Attach the user audit record to the kernel audit record. Because
863 * this system call is an auditable event, we will write the user
864 * record along with the record for this audit event.
867 ar
->k_ar_commit
|= AR_COMMIT_USER
;
868 ar
->k_ulen
= uap
->length
;
872 /* audit_syscall_exit() will free the audit record on the thread
873 * even if we allocated it above.
875 kfree(rec
, uap
->length
);
880 * System call to manipulate auditing.
884 auditon(proc_t p
, struct auditon_args
*uap
, __unused register_t
*retval
)
888 union auditon_udata udata
;
889 proc_t tp
= PROC_NULL
;
890 kauth_cred_t my_cred
;
892 AUDIT_ARG(cmd
, uap
->cmd
);
893 ret
= suser(kauth_cred_get(), &p
->p_acflag
);
898 ret
= mac_system_check_auditon(kauth_cred_get(), uap
->cmd
);
904 if ((len
<= 0) || (len
> (int)sizeof(union auditon_udata
)))
907 memset((void *)&udata
, 0, sizeof(udata
));
910 /* Some of the GET commands use the arguments too */
924 case A_GETPINFO_ADDR
:
925 ret
= copyin(uap
->data
, (void *)&udata
, uap
->length
);
928 AUDIT_ARG(auditon
, &udata
);
932 /* XXX Need to implement these commands by accessing the global
933 * values associated with the commands.
935 lck_mtx_lock(audit_mtx
);
938 if (!audit_fail_stop
)
939 udata
.au_policy
|= AUDIT_CNT
;
940 if (audit_panic_on_write_fail
)
941 udata
.au_policy
|= AUDIT_AHLT
;
944 if (udata
.au_policy
& ~(AUDIT_CNT
|AUDIT_AHLT
)) {
949 * XXX - Need to wake up waiters if the policy relaxes?
951 audit_fail_stop
= ((udata
.au_policy
& AUDIT_CNT
) == 0);
952 audit_panic_on_write_fail
= (udata
.au_policy
& AUDIT_AHLT
);
955 udata
.au_mask
= audit_nae_mask
;
958 audit_nae_mask
= udata
.au_mask
;
961 udata
.au_qctrl
= audit_qctrl
;
964 if ((udata
.au_qctrl
.aq_hiwater
> AQ_MAXHIGH
) ||
965 (udata
.au_qctrl
.aq_lowater
>= udata
.au_qctrl
.aq_hiwater
) ||
966 (udata
.au_qctrl
.aq_bufsz
> AQ_MAXBUFSZ
) ||
967 (udata
.au_qctrl
.aq_minfree
< 0) ||
968 (udata
.au_qctrl
.aq_minfree
> 100)) {
973 audit_qctrl
= udata
.au_qctrl
;
974 /* XXX The queue delay value isn't used with the kernel. */
975 audit_qctrl
.aq_delay
= -1;
996 if (audit_enabled
&& !audit_suspended
)
997 udata
.au_cond
= AUC_AUDITING
;
999 udata
.au_cond
= AUC_NOAUDIT
;
1002 if (udata
.au_cond
== AUC_NOAUDIT
)
1003 audit_suspended
= 1;
1004 if (udata
.au_cond
== AUC_AUDITING
)
1005 audit_suspended
= 0;
1006 if (udata
.au_cond
== AUC_DISABLED
) {
1007 audit_suspended
= 1;
1012 udata
.au_evclass
.ec_class
=
1013 au_event_class(udata
.au_evclass
.ec_number
);
1016 au_evclassmap_insert(udata
.au_evclass
.ec_number
,
1017 udata
.au_evclass
.ec_class
);
1020 if (udata
.au_aupinfo
.ap_pid
< 1) {
1024 if ((tp
= proc_find(udata
.au_aupinfo
.ap_pid
)) == NULL
) {
1029 lck_mtx_unlock(audit_mtx
);
1030 my_cred
= kauth_cred_proc_ref(tp
);
1032 udata
.au_aupinfo
.ap_auid
= my_cred
->cr_au
.ai_auid
;
1033 udata
.au_aupinfo
.ap_mask
.am_success
=
1034 my_cred
->cr_au
.ai_mask
.am_success
;
1035 udata
.au_aupinfo
.ap_mask
.am_failure
=
1036 my_cred
->cr_au
.ai_mask
.am_failure
;
1037 udata
.au_aupinfo
.ap_termid
.machine
=
1038 my_cred
->cr_au
.ai_termid
.machine
;
1039 udata
.au_aupinfo
.ap_termid
.port
=
1040 my_cred
->cr_au
.ai_termid
.port
;
1041 udata
.au_aupinfo
.ap_asid
= my_cred
->cr_au
.ai_asid
;
1043 kauth_cred_unref(&my_cred
);
1047 lck_mtx_lock(audit_mtx
);
1050 if (udata
.au_aupinfo
.ap_pid
< 1) {
1054 if ((tp
= proc_find(udata
.au_aupinfo
.ap_pid
)) == NULL
) {
1060 * we are modifying the audit info in a credential so we need a new
1061 * credential (or take another reference on an existing credential that
1062 * matches our new one). We must do this because the audit info in the
1063 * credential is used as part of our hash key. Get current credential
1064 * in the target process and take a reference while we muck with it.
1066 lck_mtx_unlock(audit_mtx
);
1068 kauth_cred_t my_new_cred
;
1069 struct auditinfo temp_auditinfo
;
1071 my_cred
= kauth_cred_proc_ref(tp
);
1073 * Set the credential with new info. If there is no
1074 * change, we get back the same credential we passed
1075 * in; if there is a change, we drop the reference on
1076 * the credential we passed in. The subsequent
1077 * compare is safe, because it is a pointer compare
1078 * rather than a contents compare.
1080 temp_auditinfo
= my_cred
->cr_au
;
1081 temp_auditinfo
.ai_mask
.am_success
=
1082 udata
.au_aupinfo
.ap_mask
.am_success
;
1083 temp_auditinfo
.ai_mask
.am_failure
=
1084 udata
.au_aupinfo
.ap_mask
.am_failure
;
1085 my_new_cred
= kauth_cred_setauditinfo(my_cred
, &temp_auditinfo
);
1087 if (my_cred
!= my_new_cred
) {
1089 /* need to protect for a race where another thread also changed
1090 * the credential after we took our reference. If p_ucred has
1091 * changed then we should restart this again with the new cred.
1093 if (tp
->p_ucred
!= my_cred
) {
1095 kauth_cred_unref(&my_new_cred
);
1099 tp
->p_ucred
= my_new_cred
;
1102 /* drop old proc reference or our extra reference */
1103 kauth_cred_unref(&my_cred
);
1107 lck_mtx_lock(audit_mtx
);
1110 if ((udata
.au_fstat
.af_filesz
!= 0) &&
1111 (udata
.au_fstat
.af_filesz
< MIN_AUDIT_FILE_SIZE
)) {
1115 audit_fstat
.af_filesz
= udata
.au_fstat
.af_filesz
;
1118 udata
.au_fstat
.af_filesz
= audit_fstat
.af_filesz
;
1119 udata
.au_fstat
.af_currsz
= audit_fstat
.af_currsz
;
1121 case A_GETPINFO_ADDR
:
1131 /* Copy data back to userspace for the GET comands */
1144 case A_GETPINFO_ADDR
:
1146 ret
= copyout((void *)&udata
, uap
->data
, uap
->length
);
1151 lck_mtx_unlock(audit_mtx
);
1156 * System calls to manage the user audit information.
1160 getauid(__unused proc_t p
, struct getauid_args
*uap
, __unused register_t
*retval
)
1165 error
= mac_proc_check_getauid(p
);
1170 error
= copyout((void *)&kauth_cred_get()->cr_au
.ai_auid
,
1171 uap
->auid
, sizeof(au_id_t
));
1180 setauid(proc_t p
, struct setauid_args
*uap
, __unused register_t
*retval
)
1185 error
= suser(kauth_cred_get(), &p
->p_acflag
);
1189 error
= copyin(uap
->auid
,
1190 (void *)&temp_au_id
,
1195 error
= mac_proc_check_setauid(p
, temp_au_id
);
1201 * we are modifying the audit info in a credential so we need a new
1202 * credential (or take another reference on an existing credential that
1203 * matches our new one). We must do this because the audit info in the
1204 * credential is used as part of our hash key. Get current credential
1205 * in the target process and take a reference while we muck with it.
1208 kauth_cred_t my_cred
, my_new_cred
;
1209 struct auditinfo temp_auditinfo
;
1211 my_cred
= kauth_cred_proc_ref(p
);
1213 * Set the credential with new info. If there is no change,
1214 * we get back the same credential we passed in; if there is
1215 * a change, we drop the reference on the credential we
1216 * passed in. The subsequent compare is safe, because it is
1217 * a pointer compare rather than a contents compare.
1219 temp_auditinfo
= my_cred
->cr_au
;
1220 temp_auditinfo
.ai_auid
= temp_au_id
;
1221 my_new_cred
= kauth_cred_setauditinfo(my_cred
, &temp_auditinfo
);
1223 if (my_cred
!= my_new_cred
) {
1225 /* need to protect for a race where another thread also changed
1226 * the credential after we took our reference. If p_ucred has
1227 * changed then we should restart this again with the new cred.
1229 if (p
->p_ucred
!= my_cred
) {
1231 kauth_cred_unref(&my_new_cred
);
1235 p
->p_ucred
= my_new_cred
;
1238 /* drop old proc reference or our extra reference */
1239 kauth_cred_unref(&my_cred
);
1243 /* propagate the change from the process to Mach task */
1244 set_security_token(p
);
1246 audit_arg_auid(kauth_cred_get()->cr_au
.ai_auid
);
1251 * System calls to get and set process audit information.
1252 * If the caller is privileged, they get the whole set of
1253 * audit information. Otherwise, the real audit mask is
1254 * filtered out - but the rest of the information is
1259 getaudit(proc_t p
, struct getaudit_args
*uap
, __unused register_t
*retval
)
1261 struct auditinfo ai
;
1265 error
= mac_proc_check_getaudit(p
);
1270 ai
= kauth_cred_get()->cr_au
;
1272 /* only superuser gets to see the real mask */
1273 error
= suser(kauth_cred_get(), &p
->p_acflag
);
1275 ai
.ai_mask
.am_success
= ~0;
1276 ai
.ai_mask
.am_failure
= ~0;
1279 error
= copyout(&ai
, uap
->auditinfo
, sizeof(ai
));
1288 setaudit(proc_t p
, struct setaudit_args
*uap
, __unused register_t
*retval
)
1291 struct auditinfo temp_auditinfo
;
1292 kauth_cred_t safecred
;
1294 error
= suser(kauth_cred_get(), &p
->p_acflag
);
1297 error
= copyin(uap
->auditinfo
,
1298 (void *)&temp_auditinfo
,
1299 sizeof(temp_auditinfo
));
1303 error
= mac_proc_check_setaudit(p
, &temp_auditinfo
);
1311 * we are modifying the audit info in a credential so we need a new
1312 * credential (or take another reference on an existing credential that
1313 * matches our new one). We must do this because the audit info in the
1314 * credential is used as part of our hash key. Get current credential
1315 * in the target process and take a reference while we muck with it.
1318 kauth_cred_t my_cred
, my_new_cred
;
1320 my_cred
= kauth_cred_proc_ref(p
);
1322 * Set the credential with new info. If there is no change,
1323 * we get back the same credential we passed in; if there is
1324 * a change, we drop the reference on the credential we
1325 * passed in. The subsequent compare is safe, because it is
1326 * a pointer compare rather than a contents compare.
1328 my_new_cred
= kauth_cred_setauditinfo(my_cred
, &temp_auditinfo
);
1330 if (my_cred
!= my_new_cred
) {
1332 /* need to protect for a race where another thread also changed
1333 * the credential after we took our reference. If p_ucred has
1334 * changed then we should restart this again with the new cred.
1336 if (p
->p_ucred
!= my_cred
) {
1338 kauth_cred_unref(&my_new_cred
);
1342 p
->p_ucred
= my_new_cred
;
1345 /* drop old proc reference or our extra reference */
1346 kauth_cred_unref(&my_cred
);
1350 /* propagate the change from the process to Mach task */
1351 set_security_token(p
);
1353 safecred
= kauth_cred_proc_ref(p
);
1354 audit_arg_auditinfo(&safecred
->cr_au
);
1355 kauth_cred_unref(&safecred
);
1362 getaudit_addr(__unused proc_t p
, __unused
struct getaudit_addr_args
*uap
, __unused register_t
*retval
)
1369 setaudit_addr(proc_t p
, __unused
struct setaudit_addr_args
*uap
, __unused register_t
*retval
)
1373 error
= suser(kauth_cred_get(), &p
->p_acflag
);
1380 * Syscall to manage audit files.
1385 auditctl(proc_t p
, struct auditctl_args
*uap
, __unused register_t
*retval
)
1387 struct nameidata nd
;
1392 error
= suser(kauth_cred_get(), &p
->p_acflag
);
1400 * If a path is specified, open the replacement vnode, perform
1401 * validity checks, and grab another reference to the current
1404 if (uap
->path
!= USER_ADDR_NULL
) {
1405 NDINIT(&nd
, LOOKUP
, FOLLOW
| LOCKLEAF
| AUDITVNPATH1
,
1406 (IS_64BIT_PROCESS(p
) ? UIO_USERSPACE64
: UIO_USERSPACE32
),
1407 uap
->path
, vfs_context_current());
1408 error
= vn_open(&nd
, audit_open_flags
, 0);
1413 if (vp
->v_type
!= VREG
) {
1414 vn_close(vp
, audit_close_flags
, vfs_context_current());
1421 * Accessibility of the vnode was determined in
1422 * vn_open; the mac_system_check_auditctl should only
1423 * determine whether that vnode is appropriate for
1424 * storing audit data, or that the caller was
1425 * permitted to control the auditing system at all.
1426 * For example, a confidentiality policy may want to
1427 * ensure that audit files are always high
1431 error
= mac_system_check_auditctl(kauth_cred_get(), vp
);
1433 vn_close(vp
, audit_close_flags
, vfs_context_current());
1438 cred
= kauth_cred_get_with_ref();
1439 lck_mtx_lock(audit_mtx
);
1440 audit_suspended
= 0;
1441 lck_mtx_unlock(audit_mtx
);
1445 error
= mac_system_check_auditctl(kauth_cred_get(), NULL
);
1452 * a vp and cred of NULL is valid at this point
1453 * and indicates we're to turn off auditing...
1455 audit_rotate_vnode(cred
, vp
);
1462 /**********************************
1463 * End of system calls. *
1464 **********************************/
1469 struct kaudit_record
*
1470 audit_new(int event
, proc_t p
, __unused
struct uthread
*uthread
)
1472 struct kaudit_record
*ar
;
1474 kauth_cred_t safecred
;
1477 * Eventually, there may be certain classes of events that
1478 * we will audit regardless of the audit state at the time
1479 * the record is created. These events will generally
1480 * correspond to changes in the audit state. The dummy
1481 * code below is from our first prototype, but may also
1482 * be used in the final version (with modified event numbers).
1485 if (event
!= AUDIT_EVENT_FILESTOP
&& event
!= AUDIT_EVENT_FILESTART
) {
1487 lck_mtx_lock(audit_mtx
);
1488 no_record
= (audit_suspended
|| !audit_enabled
);
1489 lck_mtx_unlock(audit_mtx
);
1497 * Initialize the audit record header.
1498 * XXX: We may want to fail-stop if allocation fails.
1499 * XXX: The number of outstanding uncommitted audit records is
1500 * limited by the number of concurrent threads servicing system
1501 * calls in the kernel.
1504 ar
= (struct kaudit_record
*)zalloc(audit_zone
);
1508 bzero(ar
, sizeof(*ar
));
1509 ar
->k_ar
.ar_magic
= AUDIT_RECORD_MAGIC
;
1510 ar
->k_ar
.ar_event
= event
;
1511 nanotime(&ar
->k_ar
.ar_starttime
);
1513 safecred
= kauth_cred_proc_ref(p
);
1514 /* Export the subject credential. */
1515 cru2x(safecred
, &ar
->k_ar
.ar_subj_cred
);
1517 ar
->k_ar
.ar_subj_ruid
= safecred
->cr_ruid
;
1518 ar
->k_ar
.ar_subj_rgid
= safecred
->cr_rgid
;
1519 ar
->k_ar
.ar_subj_egid
= safecred
->cr_groups
[0];
1520 ar
->k_ar
.ar_subj_auid
= safecred
->cr_au
.ai_auid
;
1521 ar
->k_ar
.ar_subj_asid
= safecred
->cr_au
.ai_asid
;
1522 ar
->k_ar
.ar_subj_amask
= safecred
->cr_au
.ai_mask
;
1523 ar
->k_ar
.ar_subj_term
= safecred
->cr_au
.ai_termid
;
1524 kauth_cred_unref(&safecred
);
1526 ar
->k_ar
.ar_subj_pid
= p
->p_pid
;
1527 bcopy(p
->p_comm
, ar
->k_ar
.ar_subj_comm
, MAXCOMLEN
);
1533 /* Retrieve the MAC labels for the process. */
1534 ar
->k_ar
.ar_cred_mac_labels
=
1535 (char *)zalloc(audit_mac_label_zone
);
1536 if (ar
->k_ar
.ar_cred_mac_labels
== NULL
) {
1537 zfree(audit_zone
, ar
);
1540 mac
.m_buflen
= MAC_AUDIT_LABEL_LEN
;
1541 mac
.m_string
= ar
->k_ar
.ar_cred_mac_labels
;
1542 mac_cred_label_externalize_audit(p
, &mac
);
1545 * grab space for the reconds.
1547 ar
->k_ar
.ar_mac_records
= (struct mac_audit_record_list_t
*)
1548 kalloc(sizeof(*ar
->k_ar
.ar_mac_records
));
1549 if (ar
->k_ar
.ar_mac_records
== NULL
) {
1550 zfree(audit_mac_label_zone
,
1551 ar
->k_ar
.ar_cred_mac_labels
);
1552 zfree(audit_zone
, ar
);
1556 LIST_INIT(ar
->k_ar
.ar_mac_records
);
1558 ar
->k_ar
.ar_forced_by_mac
= 0;
1563 lck_mtx_lock(audit_mtx
);
1565 lck_mtx_unlock(audit_mtx
);
1572 * XXXAUDIT: So far, this is unused, and should probably be GC'd.
1575 audit_abort(struct kaudit_record
*ar
)
1577 lck_mtx_lock(audit_mtx
);
1579 lck_mtx_unlock(audit_mtx
);
1587 audit_commit(struct kaudit_record
*ar
, int error
, int retval
)
1591 struct au_mask
*aumask
;
1597 * Decide whether to commit the audit record by checking the
1598 * error value from the system call and using the appropriate
1601 if (ar
->k_ar
.ar_subj_auid
== AU_DEFAUDITID
)
1602 aumask
= &audit_nae_mask
;
1604 aumask
= &ar
->k_ar
.ar_subj_amask
;
1607 sorf
= AU_PRS_FAILURE
;
1609 sorf
= AU_PRS_SUCCESS
;
1611 switch(ar
->k_ar
.ar_event
) {
1614 /* The open syscall always writes a OPEN_RWTC event; limit the
1615 * to the proper type of event based on the flags and the error
1618 ar
->k_ar
.ar_event
= flags_and_error_to_openevent(ar
->k_ar
.ar_arg_fflags
, error
);
1622 ar
->k_ar
.ar_event
= ctlname_to_sysctlevent(ar
->k_ar
.ar_arg_ctlname
, ar
->k_ar
.ar_valid_arg
);
1626 /* Convert the auditon() command to an event */
1627 ar
->k_ar
.ar_event
= auditon_command_event(ar
->k_ar
.ar_arg_cmd
);
1631 if (au_preselect(ar
->k_ar
.ar_event
, aumask
, sorf
) != 0)
1632 ar
->k_ar_commit
|= AR_COMMIT_KERNEL
;
1634 if ((ar
->k_ar_commit
& (AR_COMMIT_USER
| AR_COMMIT_KERNEL
)) == 0) {
1635 lck_mtx_lock(audit_mtx
);
1637 lck_mtx_unlock(audit_mtx
);
1642 ar
->k_ar
.ar_errno
= error
;
1643 ar
->k_ar
.ar_retval
= retval
;
1646 * We might want to do some system-wide post-filtering
1647 * here at some point.
1651 * Timestamp system call end.
1653 nanotime(&ar
->k_ar
.ar_endtime
);
1655 lck_mtx_lock(audit_mtx
);
1657 * Note: it could be that some records initiated while audit was
1658 * enabled should still be committed?
1660 if (audit_suspended
|| !audit_enabled
) {
1662 lck_mtx_unlock(audit_mtx
);
1668 * Constrain the number of committed audit records based on
1669 * the configurable parameter.
1671 while (audit_q_len
>= audit_qctrl
.aq_hiwater
) {
1673 ret
= wait_queue_assert_wait(audit_wait_queue
,
1677 lck_mtx_unlock(audit_mtx
);
1679 assert(ret
== THREAD_WAITING
);
1681 ret
= thread_block(THREAD_CONTINUE_NULL
);
1682 assert(ret
== THREAD_AWAKENED
);
1683 lck_mtx_lock(audit_mtx
);
1686 TAILQ_INSERT_TAIL(&audit_q
, ar
, k_q
);
1689 wait_queue_wakeup_one(audit_wait_queue
, AUDIT_WORKER_EVENT
, THREAD_AWAKENED
);
1690 lck_mtx_unlock(audit_mtx
);
1694 * If we're out of space and need to suspend unprivileged
1695 * processes, do that here rather than trying to allocate
1696 * another audit record.
1699 audit_new_wait(int audit_event
, proc_t proc
, struct uthread
*uthread
)
1703 if (audit_in_failure
&&
1704 suser(kauth_cred_get(), &proc
->p_acflag
) != 0) {
1705 ret
= wait_queue_assert_wait(audit_wait_queue
,
1706 AUDIT_FAILURE_EVENT
, THREAD_UNINT
, 0);
1707 assert(ret
== THREAD_WAITING
);
1708 (void)thread_block(THREAD_CONTINUE_NULL
);
1709 panic("audit_failing_stop: thread continued");
1711 uthread
->uu_ar
= audit_new(audit_event
, proc
, uthread
);
1715 * Calls to set up and tear down audit structures associated with
1719 audit_syscall_enter(unsigned short code
, proc_t proc
,
1720 struct uthread
*uthread
)
1723 struct au_mask
*aumask
;
1724 kauth_cred_t my_cred
;
1726 audit_event
= sys_au_event
[code
];
1727 if (audit_event
== AUE_NULL
)
1730 assert(uthread
->uu_ar
== NULL
);
1732 /* Check which audit mask to use; either the kernel non-attributable
1733 * event mask or the process audit mask.
1735 my_cred
= kauth_cred_proc_ref(proc
);
1737 if (my_cred
->cr_au
.ai_auid
== AU_DEFAUDITID
)
1738 aumask
= &audit_nae_mask
;
1740 aumask
= &my_cred
->cr_au
.ai_mask
;
1743 * Allocate an audit record, if preselection allows it, and store
1744 * in the BSD thread for later use.
1751 error
= mac_audit_check_preselect(my_cred
, code
,
1752 (void *) uthread
->uu_arg
);
1754 if (error
== MAC_AUDIT_YES
) {
1755 uthread
->uu_ar
= audit_new(audit_event
, proc
, uthread
);
1756 uthread
->uu_ar
->k_ar
.ar_forced_by_mac
= 1;
1757 au_to_text("Forced by a MAC policy");
1759 else if (error
== MAC_AUDIT_NO
) {
1760 uthread
->uu_ar
= NULL
;
1762 else if (error
== MAC_AUDIT_DEFAULT
&&
1763 au_preselect(audit_event
, &my_cred
->cr_au
.ai_mask
,
1764 AU_PRS_FAILURE
| AU_PRS_SUCCESS
))
1765 audit_new_wait(audit_event
, proc
, uthread
);
1768 if (au_preselect(audit_event
, &my_cred
->cr_au
.ai_mask
,
1769 AU_PRS_FAILURE
| AU_PRS_SUCCESS
)) {
1770 audit_new_wait(audit_event
, proc
, uthread
);
1772 uthread
->uu_ar
= NULL
;
1775 kauth_cred_unref(&my_cred
);
1779 * Note: The audit_syscall_exit() parameter list was modified to support
1780 * mac_audit_check_postselect(), which requires the Darwin syscall number.
1784 audit_syscall_exit(unsigned short code
, int error
, AUDIT_PRINTF_ONLY proc_t proc
, struct uthread
*uthread
)
1787 audit_syscall_exit(int error
, AUDIT_PRINTF_ONLY proc_t proc
, struct uthread
*uthread
)
1793 * Commit the audit record as desired; once we pass the record
1794 * into audit_commit(), the memory is owned by the audit
1796 * The return value from the system call is stored on the user
1797 * thread. If there was an error, the return value is set to -1,
1798 * imitating the behavior of the cerror routine.
1803 retval
= uthread
->uu_rval
[0];
1809 if (uthread
->uu_ar
== NULL
) /* syscall wasn't audited */
1813 * Note, no other postselect mechanism exists. If
1814 * mac_audit_check_postselect returns MAC_AUDIT_NO, the
1815 * record will be suppressed. Other values at this
1816 * point result in the audit record being committed.
1817 * This suppression behavior will probably go away in
1818 * the port to 10.3.4.
1820 mac_error
= mac_audit_check_postselect(kauth_cred_get(), code
,
1821 (void *) uthread
->uu_arg
, error
, retval
,
1822 uthread
->uu_ar
->k_ar
.ar_forced_by_mac
);
1824 if (mac_error
== MAC_AUDIT_YES
)
1825 uthread
->uu_ar
->k_ar_commit
|= AR_COMMIT_KERNEL
;
1826 else if (mac_error
== MAC_AUDIT_NO
) {
1827 audit_free(uthread
->uu_ar
);
1834 audit_commit(uthread
->uu_ar
, error
, retval
);
1835 if (uthread
->uu_ar
!= NULL
) {
1836 AUDIT_PRINTF(("audit record committed by pid %d\n", proc
->p_pid
));
1842 uthread
->uu_ar
= NULL
;
1847 * Calls to set up and tear down audit structures used during Mach
1851 audit_mach_syscall_enter(unsigned short audit_event
)
1853 struct uthread
*uthread
;
1855 struct au_mask
*aumask
;
1856 kauth_cred_t my_cred
;
1858 if (audit_event
== AUE_NULL
)
1861 uthread
= curuthread();
1862 if (uthread
== NULL
)
1865 proc
= current_proc();
1869 assert(uthread
->uu_ar
== NULL
);
1871 my_cred
= kauth_cred_proc_ref(proc
);
1873 /* Check which audit mask to use; either the kernel non-attributable
1874 * event mask or the process audit mask.
1876 if (my_cred
->cr_au
.ai_auid
== AU_DEFAUDITID
)
1877 aumask
= &audit_nae_mask
;
1879 aumask
= &my_cred
->cr_au
.ai_mask
;
1881 kauth_cred_unref(&my_cred
);
1884 * Allocate an audit record, if desired, and store in the BSD
1885 * thread for later use.
1887 if (au_preselect(audit_event
, aumask
,
1888 AU_PRS_FAILURE
| AU_PRS_SUCCESS
)) {
1889 uthread
->uu_ar
= audit_new(audit_event
, proc
, uthread
);
1891 uthread
->uu_ar
= NULL
;
1896 audit_mach_syscall_exit(int retval
, struct uthread
*uthread
)
1898 /* The error code from Mach system calls is the same as the
1901 /* XXX Is the above statement always true? */
1902 audit_commit(uthread
->uu_ar
, retval
, retval
);
1903 uthread
->uu_ar
= NULL
;
1908 * Calls to manipulate elements of the audit record structure from system
1909 * call code. Macro wrappers will prevent this functions from being
1910 * entered if auditing is disabled, avoiding the function call cost. We
1911 * check the thread audit record pointer anyway, as the audit condition
1912 * could change, and pre-selection may not have allocated an audit
1913 * record for this event.
1916 audit_arg_addr(user_addr_t addr
)
1918 struct kaudit_record
*ar
;
1924 ar
->k_ar
.ar_arg_addr
= CAST_DOWN(void *, addr
); /* XXX */
1925 ar
->k_ar
.ar_valid_arg
|= ARG_ADDR
;
1929 audit_arg_len(user_size_t len
)
1931 struct kaudit_record
*ar
;
1937 ar
->k_ar
.ar_arg_len
= CAST_DOWN(int, len
); /* XXX */
1938 ar
->k_ar
.ar_valid_arg
|= ARG_LEN
;
1942 audit_arg_fd(int fd
)
1944 struct kaudit_record
*ar
;
1950 ar
->k_ar
.ar_arg_fd
= fd
;
1951 ar
->k_ar
.ar_valid_arg
|= ARG_FD
;
1955 audit_arg_fflags(int fflags
)
1957 struct kaudit_record
*ar
;
1963 ar
->k_ar
.ar_arg_fflags
= fflags
;
1964 ar
->k_ar
.ar_valid_arg
|= ARG_FFLAGS
;
1968 audit_arg_gid(gid_t gid
, gid_t egid
, gid_t rgid
, gid_t sgid
)
1970 struct kaudit_record
*ar
;
1976 ar
->k_ar
.ar_arg_gid
= gid
;
1977 ar
->k_ar
.ar_arg_egid
= egid
;
1978 ar
->k_ar
.ar_arg_rgid
= rgid
;
1979 ar
->k_ar
.ar_arg_sgid
= sgid
;
1980 ar
->k_ar
.ar_valid_arg
|= (ARG_GID
| ARG_EGID
| ARG_RGID
| ARG_SGID
);
1984 audit_arg_uid(uid_t uid
, uid_t euid
, uid_t ruid
, uid_t suid
)
1986 struct kaudit_record
*ar
;
1992 ar
->k_ar
.ar_arg_uid
= uid
;
1993 ar
->k_ar
.ar_arg_euid
= euid
;
1994 ar
->k_ar
.ar_arg_ruid
= ruid
;
1995 ar
->k_ar
.ar_arg_suid
= suid
;
1996 ar
->k_ar
.ar_valid_arg
|= (ARG_UID
| ARG_EUID
| ARG_RUID
| ARG_SUID
);
2000 audit_arg_groupset(const gid_t
*gidset
, u_int gidset_size
)
2003 struct kaudit_record
*ar
;
2009 for (i
= 0; i
< gidset_size
; i
++)
2010 ar
->k_ar
.ar_arg_groups
.gidset
[i
] = gidset
[i
];
2011 ar
->k_ar
.ar_arg_groups
.gidset_size
= gidset_size
;
2012 ar
->k_ar
.ar_valid_arg
|= ARG_GROUPSET
;
2016 audit_arg_login(const char *login
)
2018 struct kaudit_record
*ar
;
2024 strlcpy(ar
->k_ar
.ar_arg_login
, login
, MAXLOGNAME
);
2026 ar
->k_ar
.ar_valid_arg
|= ARG_LOGIN
;
2030 audit_arg_ctlname(const int *name
, int namelen
)
2032 struct kaudit_record
*ar
;
2038 bcopy(name
, &ar
->k_ar
.ar_arg_ctlname
, namelen
* sizeof(int));
2039 ar
->k_ar
.ar_arg_len
= namelen
;
2040 ar
->k_ar
.ar_valid_arg
|= (ARG_CTLNAME
| ARG_LEN
);
2044 audit_arg_mask(int mask
)
2046 struct kaudit_record
*ar
;
2052 ar
->k_ar
.ar_arg_mask
= mask
;
2053 ar
->k_ar
.ar_valid_arg
|= ARG_MASK
;
2057 audit_arg_mode(mode_t mode
)
2059 struct kaudit_record
*ar
;
2065 ar
->k_ar
.ar_arg_mode
= mode
;
2066 ar
->k_ar
.ar_valid_arg
|= ARG_MODE
;
2070 audit_arg_dev(int dev
)
2072 struct kaudit_record
*ar
;
2078 ar
->k_ar
.ar_arg_dev
= dev
;
2079 ar
->k_ar
.ar_valid_arg
|= ARG_DEV
;
2083 audit_arg_value(long value
)
2085 struct kaudit_record
*ar
;
2091 ar
->k_ar
.ar_arg_value
= value
;
2092 ar
->k_ar
.ar_valid_arg
|= ARG_VALUE
;
2096 audit_arg_owner(uid_t uid
, gid_t gid
)
2098 struct kaudit_record
*ar
;
2104 ar
->k_ar
.ar_arg_uid
= uid
;
2105 ar
->k_ar
.ar_arg_gid
= gid
;
2106 ar
->k_ar
.ar_valid_arg
|= (ARG_UID
| ARG_GID
);
2110 audit_arg_pid(pid_t pid
)
2112 struct kaudit_record
*ar
;
2118 ar
->k_ar
.ar_arg_pid
= pid
;
2119 ar
->k_ar
.ar_valid_arg
|= ARG_PID
;
2123 audit_arg_process(proc_t p
)
2125 struct kaudit_record
*ar
;
2126 kauth_cred_t my_cred
;
2129 if ((ar
== NULL
) || (p
== NULL
))
2132 my_cred
= kauth_cred_proc_ref(p
);
2133 ar
->k_ar
.ar_arg_auid
= my_cred
->cr_au
.ai_auid
;
2134 ar
->k_ar
.ar_arg_euid
= my_cred
->cr_uid
;
2135 ar
->k_ar
.ar_arg_egid
= my_cred
->cr_groups
[0];
2136 ar
->k_ar
.ar_arg_ruid
= my_cred
->cr_ruid
;
2137 ar
->k_ar
.ar_arg_rgid
= my_cred
->cr_rgid
;
2138 ar
->k_ar
.ar_arg_asid
= my_cred
->cr_au
.ai_asid
;
2139 ar
->k_ar
.ar_arg_termid
= my_cred
->cr_au
.ai_termid
;
2140 kauth_cred_unref(&my_cred
);
2142 ar
->k_ar
.ar_valid_arg
|= ARG_AUID
| ARG_EUID
| ARG_EGID
| ARG_RUID
|
2143 ARG_RGID
| ARG_ASID
| ARG_TERMID
| ARG_PROCESS
;
2147 audit_arg_signum(u_int signum
)
2149 struct kaudit_record
*ar
;
2155 ar
->k_ar
.ar_arg_signum
= signum
;
2156 ar
->k_ar
.ar_valid_arg
|= ARG_SIGNUM
;
2160 audit_arg_socket(int sodomain
, int sotype
, int soprotocol
)
2163 struct kaudit_record
*ar
;
2169 ar
->k_ar
.ar_arg_sockinfo
.so_domain
= sodomain
;
2170 ar
->k_ar
.ar_arg_sockinfo
.so_type
= sotype
;
2171 ar
->k_ar
.ar_arg_sockinfo
.so_protocol
= soprotocol
;
2172 ar
->k_ar
.ar_valid_arg
|= ARG_SOCKINFO
;
2176 * Note that the current working directory vp must be supplied at the audit
2177 * call site to permit per thread current working directories, and that it
2178 * must take a upath starting with '/' into account for chroot if the path
2179 * is absolute. This results in the real (non-chroot) path being recorded
2180 * in the audit record.
2183 audit_arg_sockaddr(struct vnode
*cwd_vp
, struct sockaddr
*so
)
2185 struct kaudit_record
*ar
;
2188 if (ar
== NULL
|| cwd_vp
== NULL
|| so
== NULL
)
2191 bcopy(so
, &ar
->k_ar
.ar_arg_sockaddr
, sizeof(ar
->k_ar
.ar_arg_sockaddr
));
2192 switch (so
->sa_family
) {
2194 ar
->k_ar
.ar_valid_arg
|= ARG_SADDRINET
;
2197 ar
->k_ar
.ar_valid_arg
|= ARG_SADDRINET6
;
2200 audit_arg_upath(cwd_vp
, ((struct sockaddr_un
*)so
)->sun_path
,
2202 ar
->k_ar
.ar_valid_arg
|= ARG_SADDRUNIX
;
2208 audit_arg_auid(uid_t auid
)
2210 struct kaudit_record
*ar
;
2216 ar
->k_ar
.ar_arg_auid
= auid
;
2217 ar
->k_ar
.ar_valid_arg
|= ARG_AUID
;
2221 audit_arg_auditinfo(const struct auditinfo
*au_info
)
2223 struct kaudit_record
*ar
;
2229 ar
->k_ar
.ar_arg_auid
= au_info
->ai_auid
;
2230 ar
->k_ar
.ar_arg_asid
= au_info
->ai_asid
;
2231 ar
->k_ar
.ar_arg_amask
.am_success
= au_info
->ai_mask
.am_success
;
2232 ar
->k_ar
.ar_arg_amask
.am_failure
= au_info
->ai_mask
.am_failure
;
2233 ar
->k_ar
.ar_arg_termid
.port
= au_info
->ai_termid
.port
;
2234 ar
->k_ar
.ar_arg_termid
.machine
= au_info
->ai_termid
.machine
;
2235 ar
->k_ar
.ar_valid_arg
|= ARG_AUID
| ARG_ASID
| ARG_AMASK
| ARG_TERMID
;
2239 audit_arg_text(const char *text
)
2241 struct kaudit_record
*ar
;
2247 /* Invalidate the text string */
2248 ar
->k_ar
.ar_valid_arg
&= (ARG_ALL
^ ARG_TEXT
);
2252 if (ar
->k_ar
.ar_arg_text
== NULL
) {
2253 ar
->k_ar
.ar_arg_text
= (char *)kalloc(MAXPATHLEN
);
2254 if (ar
->k_ar
.ar_arg_text
== NULL
)
2258 strlcpy(ar
->k_ar
.ar_arg_text
, text
, MAXPATHLEN
);
2259 ar
->k_ar
.ar_valid_arg
|= ARG_TEXT
;
2263 audit_arg_cmd(int cmd
)
2265 struct kaudit_record
*ar
;
2271 ar
->k_ar
.ar_arg_cmd
= cmd
;
2272 ar
->k_ar
.ar_valid_arg
|= ARG_CMD
;
2276 audit_arg_svipc_cmd(int cmd
)
2278 struct kaudit_record
*ar
;
2284 ar
->k_ar
.ar_arg_svipc_cmd
= cmd
;
2285 ar
->k_ar
.ar_valid_arg
|= ARG_SVIPC_CMD
;
2289 audit_arg_svipc_perm(const struct ipc_perm
*perm
)
2291 struct kaudit_record
*ar
;
2297 bcopy(perm
, &ar
->k_ar
.ar_arg_svipc_perm
,
2298 sizeof(ar
->k_ar
.ar_arg_svipc_perm
));
2299 ar
->k_ar
.ar_valid_arg
|= ARG_SVIPC_PERM
;
2303 audit_arg_svipc_id(int id
)
2305 struct kaudit_record
*ar
;
2311 ar
->k_ar
.ar_arg_svipc_id
= id
;
2312 ar
->k_ar
.ar_valid_arg
|= ARG_SVIPC_ID
;
2316 audit_arg_svipc_addr(user_addr_t addr
)
2318 struct kaudit_record
*ar
;
2324 ar
->k_ar
.ar_arg_svipc_addr
= addr
;
2325 ar
->k_ar
.ar_valid_arg
|= ARG_SVIPC_ADDR
;
2329 audit_arg_posix_ipc_perm(uid_t uid
, gid_t gid
, mode_t mode
)
2331 struct kaudit_record
*ar
;
2337 ar
->k_ar
.ar_arg_pipc_perm
.pipc_uid
= uid
;
2338 ar
->k_ar
.ar_arg_pipc_perm
.pipc_gid
= gid
;
2339 ar
->k_ar
.ar_arg_pipc_perm
.pipc_mode
= mode
;
2340 ar
->k_ar
.ar_valid_arg
|= ARG_POSIX_IPC_PERM
;
2344 audit_arg_auditon(const union auditon_udata
*udata
)
2346 struct kaudit_record
*ar
;
2352 bcopy((const void *)udata
, &ar
->k_ar
.ar_arg_auditon
,
2353 sizeof(ar
->k_ar
.ar_arg_auditon
));
2354 ar
->k_ar
.ar_valid_arg
|= ARG_AUDITON
;
2358 * Audit information about a file, either the file's vnode info, or its
2359 * socket address info.
2362 audit_arg_file(__unused proc_t p
, const struct fileproc
*fp
)
2364 struct kaudit_record
*ar
;
2368 if (fp
->f_fglob
->fg_type
== DTYPE_VNODE
) {
2369 audit_arg_vnpath_withref((struct vnode
*)fp
->f_fglob
->fg_data
, ARG_VNODE1
);
2373 if (fp
->f_fglob
->fg_type
== DTYPE_SOCKET
) {
2377 so
= (struct socket
*)fp
->f_fglob
->fg_data
;
2378 if (INP_CHECK_SOCKAF(so
, PF_INET
)) {
2379 if (so
->so_pcb
== NULL
)
2381 ar
->k_ar
.ar_arg_sockinfo
.so_type
=
2383 ar
->k_ar
.ar_arg_sockinfo
.so_domain
=
2385 ar
->k_ar
.ar_arg_sockinfo
.so_protocol
=
2386 so
->so_proto
->pr_protocol
;
2387 pcb
= (struct inpcb
*)so
->so_pcb
;
2388 ar
->k_ar
.ar_arg_sockinfo
.so_raddr
=
2389 pcb
->inp_faddr
.s_addr
;
2390 ar
->k_ar
.ar_arg_sockinfo
.so_laddr
=
2391 pcb
->inp_laddr
.s_addr
;
2392 ar
->k_ar
.ar_arg_sockinfo
.so_rport
=
2394 ar
->k_ar
.ar_arg_sockinfo
.so_lport
=
2396 ar
->k_ar
.ar_valid_arg
|= ARG_SOCKINFO
;
2404 * Store a path as given by the user process for auditing into the audit
2405 * record stored on the user thread. This function will allocate the memory to
2406 * store the path info if not already available. This memory will be
2407 * freed when the audit record is freed. Note that the current working
2408 * directory vp must be supplied at the audit call site to permit per thread
2409 * current working directories, and that it must take a upath starting with
2410 * '/' into account for chroot if the path is absolute. This results in the
2411 * real (non-chroot) path being recorded in the audit record.
2414 audit_arg_upath(struct vnode
*cwd_vp
, char *upath
, u_int64_t flags
)
2416 struct kaudit_record
*ar
;
2419 if (cwd_vp
== NULL
|| upath
== NULL
)
2420 return; /* nothing to do! */
2422 if ((flags
& (ARG_UPATH1
| ARG_UPATH2
)) == 0)
2426 if (ar
== NULL
) /* This will be the case for unaudited system calls */
2429 if (flags
& ARG_UPATH1
) {
2430 ar
->k_ar
.ar_valid_arg
&= (ARG_ALL
^ ARG_UPATH1
);
2431 pathp
= &ar
->k_ar
.ar_arg_upath1
;
2434 ar
->k_ar
.ar_valid_arg
&= (ARG_ALL
^ ARG_UPATH2
);
2435 pathp
= &ar
->k_ar
.ar_arg_upath2
;
2438 if (*pathp
== NULL
) {
2439 *pathp
= (char *)kalloc(MAXPATHLEN
);
2444 if (canon_path(cwd_vp
, upath
, *pathp
) == 0) {
2445 if (flags
& ARG_UPATH1
)
2446 ar
->k_ar
.ar_valid_arg
|= ARG_UPATH1
;
2448 ar
->k_ar
.ar_valid_arg
|= ARG_UPATH2
;
2450 kfree(*pathp
, MAXPATHLEN
);
2456 * Function to save the path and vnode attr information into the audit
2459 * It is assumed that the caller will hold any vnode locks necessary to
2460 * perform a VNOP_GETATTR() on the passed vnode.
2462 * XXX: The attr code is very similar to vfs_vnops.c:vn_stat(), but
2463 * always provides access to the generation number as we need that
2464 * to construct the BSM file ID.
2465 * XXX: We should accept the process argument from the caller, since
2466 * it's very likely they already have a reference.
2467 * XXX: Error handling in this function is poor.
2470 audit_arg_vnpath(struct vnode
*vp
, u_int64_t flags
)
2472 struct kaudit_record
*ar
;
2473 struct vnode_attr va
;
2477 struct vnode_au_info
*vnp
;
2480 char **vnode_mac_labelp
;
2488 if (ar
== NULL
) /* This will be the case for unaudited system calls */
2491 if ((flags
& (ARG_VNODE1
| ARG_VNODE2
)) == 0)
2496 if (flags
& ARG_VNODE1
) {
2497 ar
->k_ar
.ar_valid_arg
&= (ARG_ALL
^ ARG_KPATH1
);
2498 ar
->k_ar
.ar_valid_arg
&= (ARG_ALL
^ ARG_VNODE1
);
2499 pathp
= &ar
->k_ar
.ar_arg_kpath1
;
2500 vnp
= &ar
->k_ar
.ar_arg_vnode1
;
2502 vnode_mac_labelp
= &ar
->k_ar
.ar_vnode1_mac_labels
;
2506 ar
->k_ar
.ar_valid_arg
&= (ARG_ALL
^ ARG_KPATH2
);
2507 ar
->k_ar
.ar_valid_arg
&= (ARG_ALL
^ ARG_VNODE2
);
2508 pathp
= &ar
->k_ar
.ar_arg_kpath2
;
2509 vnp
= &ar
->k_ar
.ar_arg_vnode2
;
2511 vnode_mac_labelp
= &ar
->k_ar
.ar_vnode2_mac_labels
;
2515 if (*pathp
== NULL
) {
2516 *pathp
= (char *)kalloc(MAXPATHLEN
);
2522 * If vn_getpath() succeeds, place it in a string buffer
2523 * attached to the audit record, and set a flag indicating
2527 if (vn_getpath(vp
, *pathp
, &len
) == 0) {
2528 if (flags
& ARG_VNODE1
)
2529 ar
->k_ar
.ar_valid_arg
|= ARG_KPATH1
;
2531 ar
->k_ar
.ar_valid_arg
|= ARG_KPATH2
;
2533 kfree(*pathp
, MAXPATHLEN
);
2538 VATTR_WANTED(&va
, va_mode
);
2539 VATTR_WANTED(&va
, va_uid
);
2540 VATTR_WANTED(&va
, va_gid
);
2541 VATTR_WANTED(&va
, va_rdev
);
2542 VATTR_WANTED(&va
, va_fsid
);
2543 VATTR_WANTED(&va
, va_fileid
);
2544 VATTR_WANTED(&va
, va_gen
);
2545 error
= vnode_getattr(vp
, &va
, vfs_context_current());
2547 /* XXX: How to handle this case? */
2552 if (*vnode_mac_labelp
== NULL
) {
2553 *vnode_mac_labelp
= (char *)zalloc(audit_mac_label_zone
);
2554 if (*vnode_mac_labelp
!= NULL
) {
2555 mac
.m_buflen
= MAC_AUDIT_LABEL_LEN
;
2556 mac
.m_string
= *vnode_mac_labelp
;
2557 mac_vnode_label_externalize_audit(vp
, &mac
);
2565 /* XXX do we want to fall back here when these aren't supported? */
2566 vnp
->vn_mode
= va
.va_mode
;
2567 vnp
->vn_uid
= va
.va_uid
;
2568 vnp
->vn_gid
= va
.va_gid
;
2569 vnp
->vn_dev
= va
.va_rdev
;
2570 vnp
->vn_fsid
= va
.va_fsid
;
2571 vnp
->vn_fileid
= (u_long
)va
.va_fileid
;
2572 vnp
->vn_gen
= va
.va_gen
;
2573 if (flags
& ARG_VNODE1
)
2574 ar
->k_ar
.ar_valid_arg
|= ARG_VNODE1
;
2576 ar
->k_ar
.ar_valid_arg
|= ARG_VNODE2
;
2581 audit_arg_vnpath_withref(struct vnode
*vp
, u_int64_t flags
)
2583 if (vp
== NULL
|| vnode_getwithref(vp
))
2585 audit_arg_vnpath(vp
, flags
);
2586 (void)vnode_put(vp
);
2590 audit_arg_mach_port1(mach_port_name_t port
)
2592 struct kaudit_record
*ar
;
2598 ar
->k_ar
.ar_arg_mach_port1
= port
;
2599 ar
->k_ar
.ar_valid_arg
|= ARG_MACHPORT1
;
2603 audit_arg_mach_port2(mach_port_name_t port
)
2605 struct kaudit_record
*ar
;
2611 ar
->k_ar
.ar_arg_mach_port2
= port
;
2612 ar
->k_ar
.ar_valid_arg
|= ARG_MACHPORT2
;
2616 * The close() system call uses it's own audit call to capture the
2617 * path/vnode information because those pieces are not easily obtained
2618 * within the system call itself.
2621 audit_sysclose(proc_t p
, int fd
)
2623 struct fileproc
*fp
;
2628 if (fp_getfvp(p
, fd
, &fp
, &vp
) != 0)
2631 audit_arg_vnpath_withref((struct vnode
*)fp
->f_fglob
->fg_data
, ARG_VNODE1
);
2637 * This function is called by the MAC Framework to add audit data
2638 * from a policy to the current audit record.
2641 audit_mac_data(int type
, int len
, u_char
*data
) {
2642 struct kaudit_record
*cur
;
2643 struct mac_audit_record
*record
;
2646 if (audit_enabled
== 0) {
2658 * XXX: Note that we silently drop the audit data if this
2659 * allocation fails - this is consistent with the rest of the
2660 * audit implementation.
2662 record
= (struct mac_audit_record
*)kalloc(sizeof(*record
));
2666 record
->type
= type
;
2667 record
->length
= len
;
2668 record
->data
= data
;
2669 LIST_INSERT_HEAD(cur
->k_ar
.ar_mac_records
, record
, records
);
2679 audit_arg_mac_string(const char *string
)
2681 struct kaudit_record
*ar
;
2687 if (ar
->k_ar
.ar_arg_mac_string
== NULL
) {
2688 ar
->k_ar
.ar_arg_mac_string
=
2689 (char *)kalloc(MAC_MAX_LABEL_BUF_LEN
+ MAC_ARG_PREFIX_LEN
);
2690 /* This should be a rare event. If kalloc() returns NULL, the
2691 * system is low on kernel virtual memory. To be consistent with the
2692 * rest of audit, just return (may need to panic if required to for audit6).
2694 if (ar
->k_ar
.ar_arg_mac_string
== NULL
)
2697 strncpy(ar
->k_ar
.ar_arg_mac_string
, MAC_ARG_PREFIX
, MAC_ARG_PREFIX_LEN
);
2698 strncpy(ar
->k_ar
.ar_arg_mac_string
+ MAC_ARG_PREFIX_LEN
, string
, MAC_MAX_LABEL_BUF_LEN
);
2699 ar
->k_ar
.ar_valid_arg
|= ARG_MAC_STRING
;
2705 * kau_will_audit can be used by a security policy to determine
2706 * if an audit record will be stored, reducing wasted memory allocation
2707 * and string handling.
2711 kau_will_audit(void)
2714 return (audit_enabled
&& currecord() != NULL
);
2726 audit_shutdown(void)
2732 audit(proc_t p
, struct audit_args
*uap
, register_t
*retval
)
2738 auditon(proc_t p
, struct auditon_args
*uap
, register_t
*retval
)
2744 getauid(proc_t p
, struct getauid_args
*uap
, register_t
*retval
)
2750 setauid(proc_t p
, struct setauid_args
*uap
, register_t
*retval
)
2756 getaudit(proc_t p
, struct getaudit_args
*uap
, register_t
*retval
)
2762 setaudit(proc_t p
, struct setaudit_args
*uap
, register_t
*retval
)
2768 getaudit_addr(proc_t p
, struct getaudit_addr_args
*uap
, register_t
*retval
)
2774 setaudit_addr(proc_t p
, struct setaudit_addr_args
*uap
, register_t
*retval
)
2780 auditctl(proc_t p
, struct auditctl_args
*uap
, register_t
*retval
)
2787 audit_mac_data(int type
, int len
, u_char
*data
)