]> git.saurik.com Git - apple/xnu.git/blame - bsd/kern/kern_audit.c
xnu-1228.5.18.tar.gz
[apple/xnu.git] / bsd / kern / kern_audit.c
CommitLineData
55e303ae 1/*
2d21ac55 2 * Copyright (c) 2003-2007 Apple Inc. All rights reserved.
55e303ae 3 *
2d21ac55
A
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
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.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
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
8f6c56a5
A
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
2d21ac55
A
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.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28/*
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,
32 * Version 2.0.
55e303ae
A
33 */
34#include <sys/param.h>
35#include <sys/fcntl.h>
36#include <sys/kernel.h>
37#include <sys/lock.h>
38#include <sys/namei.h>
91447636
A
39#include <sys/proc_internal.h>
40#include <sys/kauth.h>
55e303ae
A
41#include <sys/queue.h>
42#include <sys/systm.h>
43#include <sys/time.h>
44#include <sys/ucred.h>
45#include <sys/uio.h>
46#include <sys/unistd.h>
91447636
A
47#include <sys/file_internal.h>
48#include <sys/vnode_internal.h>
55e303ae 49#include <sys/user.h>
55e303ae
A
50#include <sys/syscall.h>
51#include <sys/malloc.h>
52#include <sys/un.h>
91447636
A
53#include <sys/sysent.h>
54#include <sys/sysproto.h>
55#include <sys/vfs_context.h>
e5568f75 56#include <sys/domain.h>
91447636
A
57#include <sys/protosw.h>
58#include <sys/socketvar.h>
e5568f75
A
59
60#include <bsm/audit.h>
61#include <bsm/audit_kevents.h>
62#include <bsm/audit_klib.h>
63#include <bsm/audit_kernel.h>
64
91447636 65#include <mach/host_priv.h>
e5568f75 66#include <mach/host_special_ports.h>
91447636 67#include <mach/audit_triggers_server.h>
55e303ae 68
91447636
A
69#include <kern/host.h>
70#include <kern/kalloc.h>
71#include <kern/zalloc.h>
55e303ae
A
72#include <kern/lock.h>
73#include <kern/wait_queue.h>
91447636
A
74#include <kern/sched_prim.h>
75
2d21ac55
A
76#if CONFIG_MACF
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
83#endif
84
91447636 85#include <net/route.h>
e5568f75 86
91447636
A
87#include <netinet/in.h>
88#include <netinet/in_pcb.h>
55e303ae 89
2d21ac55 90#if AUDIT
55e303ae
A
91
92/*
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.
97 */
98/* #define AUDIT_EXCESSIVELY_VERBOSE */
99#ifdef AUDIT_EXCESSIVELY_VERBOSE
91447636 100#define AUDIT_PRINTF_ONLY
55e303ae
A
101#define AUDIT_PRINTF(x) printf x
102#else
91447636 103#define AUDIT_PRINTF_ONLY __unused
55e303ae
A
104#define AUDIT_PRINTF(X)
105#endif
106
107#if DIAGNOSTIC
108#if defined(assert)
109#undef assert()
110#endif
111#define assert(cond) \
2d21ac55 112 ((void) ((cond) ? 0 : panic("Assert failed: %s", # cond)))
55e303ae
A
113#else
114#include <kern/assert.h>
115#endif /* DIAGNOSTIC */
116
117/*
118 * Define the audit control flags.
119 */
120int audit_enabled;
121int audit_suspended;
122
123/*
124 * Mutex to protect global variables shared between various threads and
125 * processes.
126 */
2d21ac55
A
127static lck_grp_t *audit_grp;
128static lck_attr_t *audit_attr;
129static lck_grp_attr_t *audit_grp_attr;
130static lck_mtx_t *audit_mtx;
55e303ae
A
131
132/*
133 * Queue of audit records ready for delivery to disk. We insert new
e5568f75
A
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.
55e303ae 139 */
91447636
A
140static TAILQ_HEAD(, kaudit_record) audit_q;
141static size_t audit_q_len;
142static size_t audit_pre_q_len;
e5568f75
A
143
144static wait_queue_t audit_wait_queue;
145static zone_t audit_zone;
2d21ac55
A
146#if CONFIG_MACF
147static zone_t audit_mac_label_zone;
148#endif
55e303ae
A
149
150/*
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
153 * place.
154 */
e5568f75
A
155static int audit_worker_event;
156#define AUDIT_WORKER_EVENT ((event_t)&audit_worker_event)
55e303ae 157
91447636
A
158/*
159 * The audit worker thread (which is lazy started when we first
160 * rotate the audit log.
161 */
162static thread_t audit_worker_thread = THREAD_NULL;
163
55e303ae
A
164/*
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.
177 */
e5568f75
A
178static int audit_replacement_event;
179#define AUDIT_REPLACEMENT_EVENT ((event_t)&audit_replacement_event)
55e303ae 180
91447636 181static int audit_replacement_flag;
55e303ae 182static struct vnode *audit_replacement_vp;
91447636 183static kauth_cred_t audit_replacement_cred;
55e303ae 184
e5568f75
A
185/*
186 * Wait queue for auditing threads that cannot commit the audit
187 * record at the present time. Also, the queue control parameter
188 * structure.
189 */
190static int audit_commit_event;
191#define AUDIT_COMMIT_EVENT ((event_t)&audit_commit_event)
192
193static struct au_qctrl audit_qctrl;
194
55e303ae
A
195/*
196 * Flags to use on audit files when opening and closing.
197 */
91447636
A
198static const int audit_open_flags = FWRITE | O_APPEND;
199static const int audit_close_flags = FWRITE | O_APPEND;
55e303ae 200
e5568f75
A
201/*
202 * Global audit statistiscs.
203 */
204static struct audit_fstat audit_fstat;
205
206/*
207 Preselection mask for non-attributable events.
208 */
209static struct au_mask audit_nae_mask;
210
211/*
212 * Flags related to Kernel->user-space communication.
213 */
214static int audit_file_rotate_wait;
215
216/*
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?
221 */
222static int audit_panic_on_write_fail;
223static int audit_fail_stop;
224static int audit_in_failure;
225
226/*
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
229 * up.
230 */
231static int audit_failure_event;
232#define AUDIT_FAILURE_EVENT ((event_t)&audit_failure_event)
233
55e303ae
A
234/*
235 * XXX: Couldn't find the include file for this, so copied kern_exec.c's
236 * behavior.
237 */
238extern task_t kernel_task;
239
2d21ac55 240extern zone_t mac_audit_data_zone;
55e303ae
A
241static void
242audit_free(struct kaudit_record *ar)
243{
244 if (ar->k_ar.ar_arg_upath1 != NULL) {
91447636 245 kfree(ar->k_ar.ar_arg_upath1, MAXPATHLEN);
55e303ae
A
246 }
247 if (ar->k_ar.ar_arg_upath2 != NULL) {
91447636
A
248 kfree(ar->k_ar.ar_arg_upath2, MAXPATHLEN);
249
55e303ae
A
250 }
251 if (ar->k_ar.ar_arg_kpath1 != NULL) {
91447636
A
252 kfree(ar->k_ar.ar_arg_kpath1, MAXPATHLEN);
253
55e303ae
A
254 }
255 if (ar->k_ar.ar_arg_kpath2 != NULL) {
91447636
A
256 kfree(ar->k_ar.ar_arg_kpath2, MAXPATHLEN);
257
55e303ae
A
258 }
259 if (ar->k_ar.ar_arg_text != NULL) {
91447636
A
260 kfree(ar->k_ar.ar_arg_text, MAXPATHLEN);
261
55e303ae
A
262 }
263 if (ar->k_udata != NULL) {
91447636 264 kfree(ar->k_udata, ar->k_ulen);
2d21ac55 265 }
91447636 266
2d21ac55
A
267#if CONFIG_MACF
268 if (ar->k_ar.ar_vnode1_mac_labels != NULL) {
269 zfree(audit_mac_label_zone, ar->k_ar.ar_vnode1_mac_labels);
55e303ae 270 }
2d21ac55
A
271 if (ar->k_ar.ar_vnode2_mac_labels != NULL) {
272 zfree(audit_mac_label_zone, ar->k_ar.ar_vnode2_mac_labels);
273 }
274 if (ar->k_ar.ar_cred_mac_labels != NULL) {
275 zfree(audit_mac_label_zone, ar->k_ar.ar_cred_mac_labels);
276 }
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);
280 }
281
282 /* Free the audit data from the MAC policies. */
283 do {
284 struct mac_audit_record *head, *next;
285
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));
291 head = next;
292 }
293
294 kfree(ar->k_ar.ar_mac_records,
295 sizeof(*ar->k_ar.ar_mac_records));
296 } while (0);
297#endif
298
91447636 299 zfree(audit_zone, ar);
55e303ae
A
300}
301
2d21ac55
A
302/*
303 * Converts an audit record into the BSM format before writing out to the
304 * audit logfile. Will perform it's own vnode iocounting.
305 *
306 * Returns:
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.
309 */
55e303ae 310static int
2d21ac55 311audit_write(struct vnode *vp, struct kaudit_record *ar, vfs_context_t ctx)
55e303ae 312{
91447636 313 struct vfsstatfs *mnt_stat = &vp->v_mount->mnt_vfsstat;
2d21ac55 314 int ret = 0;
55e303ae 315 struct au_record *bsm;
91447636 316 off_t file_size;
e5568f75
A
317
318 mach_port_t audit_port;
319
2d21ac55
A
320 if (vnode_getwithref(vp))
321 return ENOENT;
322
91447636 323 /*
e5568f75
A
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.
328 */
2d21ac55 329 ret = vfs_update_vfsstat(vp->v_mount, ctx, VFS_KERNEL_EVENT);
e5568f75
A
330 if (ret)
331 goto out;
332
333 /* update the global stats struct */
2d21ac55 334 if ((ret = vnode_size(vp, &file_size, ctx)) != 0)
91447636
A
335 goto out;
336 audit_fstat.af_currsz = file_size;
337
e5568f75
A
338 /*
339 * Send a message to the audit daemon when disk space is getting
340 * low.
341 * XXX Need to decide what to do if the trigger to the audit daemon
342 * fails.
343 */
344 if(host_get_audit_control_port(host_priv_self(), &audit_port)
345 != KERN_SUCCESS)
346 printf("Cannot get audit control port\n");
347
348 if (audit_port != MACH_PORT_NULL) {
91447636 349 uint64_t temp;
e5568f75
A
350
351 /*
352 * If we fall below percent free blocks, then trigger the
353 * audit daemon to do something about it.
354 */
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) {
361 printf(
362 "Failed audit_triggers(AUDIT_TRIGGER_LOW_SPACE): %d\n", ret);
363 /*
364 * XXX: What to do here? Disable auditing?
365 * panic?
366 */
367 }
368 }
369 }
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.
374 */
375 if ((audit_fstat.af_filesz != 0) &&
376 (audit_file_rotate_wait == 0) &&
2d21ac55 377 (file_size >= (off_t)audit_fstat.af_filesz)) {
e5568f75
A
378 audit_file_rotate_wait = 1;
379 ret = audit_triggers(audit_port,
380 AUDIT_TRIGGER_FILE_FULL);
381 if (ret != KERN_SUCCESS) {
382 printf(
383 "Failed audit_triggers(AUDIT_TRIGGER_FILE_FULL): %d\n", ret);
384 /* XXX what to do here? */
385 }
386 }
387 }
388
389 /*
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
399 * in CAPP.
400 */
401 if (audit_fail_stop &&
402 (unsigned long)
403 ((audit_q_len + audit_pre_q_len + 1) * MAX_AUDIT_RECORD_SIZE) /
404 mnt_stat->f_bsize >= (unsigned long)(mnt_stat->f_bfree)) {
405 printf(
406 "audit_worker: free space below size of audit queue, failing stop\n");
407 audit_in_failure = 1;
408 }
55e303ae
A
409
410 /*
411 * If there is a user audit record attached to the kernel record,
412 * then write the user record.
413 */
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
418 * we ignore errors.
419 */
e5568f75 420 if (ar->k_ar_commit & AR_COMMIT_USER) {
2d21ac55
A
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));
423 if (ret)
e5568f75 424 goto out;
55e303ae
A
425 }
426
427 /*
428 * Convert the internal kernel record to BSM format and write it
429 * out if everything's OK.
430 */
e5568f75
A
431 if (!(ar->k_ar_commit & AR_COMMIT_KERNEL)) {
432 ret = 0;
433 goto out;
434 }
435
55e303ae 436 ret = kaudit_to_bsm(ar, &bsm);
e5568f75
A
437 if (ret == BSM_NOAUDIT) {
438 ret = 0;
439 goto out;
440 }
55e303ae 441
e5568f75
A
442 /*
443 * XXX: We drop the record on BSM conversion failure, but really
444 * this is an assertion failure.
445 */
55e303ae
A
446 if (ret == BSM_FAILURE) {
447 AUDIT_PRINTF(("BSM conversion failure\n"));
e5568f75
A
448 ret = EINVAL;
449 goto out;
55e303ae
A
450 }
451
2d21ac55 452 /* XXX: We should break the write functionality
55e303ae
A
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.
456 */
2d21ac55
A
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)));
55e303ae
A
459 kau_free(bsm);
460
e5568f75
A
461out:
462 /*
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.
467 */
468 if (audit_in_failure &&
469 audit_q_len == 0 && audit_pre_q_len == 0) {
2d21ac55 470 (void)VNOP_FSYNC(vp, MNT_WAIT, ctx);
e5568f75
A
471 panic("Audit store overflow; record queue drained.");
472 }
473
2d21ac55 474 vnode_put(vp);
55e303ae
A
475 return (ret);
476}
477
478static void
91447636 479audit_worker(void)
55e303ae 480{
2d21ac55 481 int do_replacement_signal, error;
55e303ae 482 TAILQ_HEAD(, kaudit_record) ar_worklist;
91447636 483 struct kaudit_record *ar;
55e303ae 484 struct vnode *audit_vp, *old_vp;
91447636 485 kauth_cred_t audit_cred;
2d21ac55 486 proc_t audit_p;
55e303ae
A
487
488 AUDIT_PRINTF(("audit_worker starting\n"));
489
490 TAILQ_INIT(&ar_worklist);
0c530ab8 491 audit_cred = NOCRED;
55e303ae
A
492 audit_p = current_proc();
493 audit_vp = NULL;
494
55e303ae 495
2d21ac55 496 lck_mtx_lock(audit_mtx);
55e303ae 497 while (1) {
2d21ac55
A
498 struct vfs_context context;
499
55e303ae
A
500 /*
501 * First priority: replace the audit log target if requested.
55e303ae
A
502 *
503 * XXX It could well be we should drain existing records
504 * first to ensure that the timestamps and ordering
505 * are right.
506 */
507 do_replacement_signal = 0;
508 while (audit_replacement_flag != 0) {
2d21ac55
A
509 kauth_cred_t old_cred = audit_cred;
510
55e303ae
A
511 old_vp = audit_vp;
512 audit_cred = audit_replacement_cred;
513 audit_vp = audit_replacement_vp;
0c530ab8 514 audit_replacement_cred = NOCRED;
55e303ae
A
515 audit_replacement_vp = NULL;
516 audit_replacement_flag = 0;
517
518 audit_enabled = (audit_vp != NULL);
519
55e303ae
A
520 /*
521 * XXX: What to do about write failures here?
522 */
523 if (old_vp != NULL) {
2d21ac55
A
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());
527 vnode_put(old_vp);
528 AUDIT_PRINTF(("Audit file closed\n"));
529 }
530 else
531 printf("audit_worker(): Couldn't close audit file.\n");
0c530ab8 532 kauth_cred_unref(&old_cred);
55e303ae 533 old_vp = NULL;
55e303ae
A
534 }
535 if (audit_vp != NULL) {
536 AUDIT_PRINTF(("Opening new audit file\n"));
537 }
55e303ae
A
538 do_replacement_signal = 1;
539 }
540 /*
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
546 * successfully.
547 */
548 if (do_replacement_signal)
e5568f75
A
549 wait_queue_wakeup_all(audit_wait_queue,
550 AUDIT_REPLACEMENT_EVENT, THREAD_AWAKENED);
55e303ae
A
551
552 /*
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.
555 */
556 if (TAILQ_EMPTY(&audit_q)) {
557 int ret;
558
559 AUDIT_PRINTF(("audit_worker waiting\n"));
e5568f75
A
560 ret = wait_queue_assert_wait(audit_wait_queue,
561 AUDIT_WORKER_EVENT,
91447636
A
562 THREAD_UNINT,
563 0);
2d21ac55 564 lck_mtx_unlock(audit_mtx);
55e303ae
A
565
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));
91447636 572
2d21ac55 573 lck_mtx_lock(audit_mtx);
55e303ae
A
574 continue;
575 }
576
577 /*
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.
584 *
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
588 * some point.
589 */
590 if (audit_vp == NULL) {
591 while ((ar = TAILQ_FIRST(&audit_q))) {
592 TAILQ_REMOVE(&audit_q, ar, k_q);
e5568f75
A
593 audit_q_len--;
594 if (audit_q_len <= audit_qctrl.aq_lowater)
595 wait_queue_wakeup_one(
596 audit_wait_queue,
597 AUDIT_COMMIT_EVENT,
598 THREAD_AWAKENED);
599
55e303ae
A
600 TAILQ_INSERT_TAIL(&ar_worklist, ar, k_q);
601 }
2d21ac55 602 lck_mtx_unlock(audit_mtx);
55e303ae
A
603 while ((ar = TAILQ_FIRST(&ar_worklist))) {
604 TAILQ_REMOVE(&ar_worklist, ar, k_q);
605 audit_free(ar);
606 }
2d21ac55 607 lck_mtx_lock(audit_mtx);
55e303ae
A
608 continue;
609 }
610
611 /*
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.
617 *
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
621 * some point.
622 */
623 while ((ar = TAILQ_FIRST(&audit_q))) {
624 TAILQ_REMOVE(&audit_q, ar, k_q);
e5568f75
A
625 audit_q_len--;
626 if (audit_q_len <= audit_qctrl.aq_lowater) {
627 wait_queue_wakeup_one(audit_wait_queue,
628 AUDIT_COMMIT_EVENT, THREAD_AWAKENED);
629 }
630
55e303ae
A
631 TAILQ_INSERT_TAIL(&ar_worklist, ar, k_q);
632 }
2d21ac55
A
633 lck_mtx_unlock(audit_mtx);
634 context.vc_thread = current_thread();
635 context.vc_ucred = audit_cred;
55e303ae
A
636 while ((ar = TAILQ_FIRST(&ar_worklist))) {
637 TAILQ_REMOVE(&ar_worklist, ar, k_q);
638 if (audit_vp != NULL) {
639 /*
640 * XXX: What should happen if there's a write
641 * error here?
642 */
2d21ac55 643 error = audit_write(audit_vp, ar, &context);
91447636 644 if (error && audit_panic_on_write_fail) {
e5568f75
A
645 panic("audit_worker: write error %d\n",
646 error);
91447636 647 } else if (error) {
55e303ae
A
648 printf("audit_worker: write error %d\n",
649 error);
2d21ac55 650 }
91447636 651 }
55e303ae
A
652 audit_free(ar);
653 }
2d21ac55 654 lck_mtx_lock(audit_mtx);
55e303ae
A
655 }
656}
657
658void
659audit_init(void)
660{
55e303ae
A
661 printf("Security auditing service present\n");
662 TAILQ_INIT(&audit_q);
e5568f75 663 audit_q_len = 0;
55e303ae
A
664 audit_enabled = 0;
665 audit_suspended = 0;
666 audit_replacement_cred = NULL;
667 audit_replacement_flag = 0;
e5568f75 668 audit_file_rotate_wait = 0;
55e303ae 669 audit_replacement_vp = NULL;
e5568f75
A
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;
676
2d21ac55
A
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);
681
55e303ae 682 audit_wait_queue = wait_queue_alloc(SYNC_POLICY_FIFO);
e5568f75
A
683 audit_zone = zinit(sizeof(struct kaudit_record),
684 AQ_HIWATER*sizeof(struct kaudit_record),
685 8192,
686 "audit_zone");
2d21ac55
A
687#if CONFIG_MACF
688 /* Assume 3 MAC labels for each audit record: two for vnodes,
689 * one for creds.
690 */
691 audit_mac_label_zone = zinit(MAC_AUDIT_LABEL_LEN,
692 AQ_HIWATER * 3*MAC_AUDIT_LABEL_LEN,
693 8192,
694 "audit_mac_label_zone");
695#endif
55e303ae
A
696
697 /* Initialize the BSM audit subsystem. */
698 kau_init();
55e303ae
A
699}
700
701static void
91447636 702audit_rotate_vnode(kauth_cred_t cred, struct vnode *vp)
55e303ae
A
703{
704 int ret;
705
706 /*
707 * If other parallel log replacements have been requested, we wait
708 * until they've finished before continuing.
709 */
2d21ac55 710 lck_mtx_lock(audit_mtx);
55e303ae
A
711 while (audit_replacement_flag != 0) {
712
713 AUDIT_PRINTF(("audit_rotate_vnode: sleeping to wait for "
714 "flag\n"));
e5568f75
A
715 ret = wait_queue_assert_wait(audit_wait_queue,
716 AUDIT_REPLACEMENT_EVENT,
91447636
A
717 THREAD_UNINT,
718 0);
2d21ac55 719 lck_mtx_unlock(audit_mtx);
55e303ae
A
720
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));
726
2d21ac55 727 lck_mtx_lock(audit_mtx);
55e303ae
A
728 }
729 audit_replacement_cred = cred;
730 audit_replacement_flag = 1;
731 audit_replacement_vp = vp;
732
733 /*
91447636
A
734 * Start or wake up the audit worker to perform the exchange.
735 * It will have to wait until we release the mutex.
55e303ae 736 */
91447636
A
737 if (audit_worker_thread == THREAD_NULL)
738 audit_worker_thread = kernel_thread(kernel_task,
739 audit_worker);
740 else
741 wait_queue_wakeup_one(audit_wait_queue,
742 AUDIT_WORKER_EVENT,
743 THREAD_AWAKENED);
55e303ae
A
744
745 /*
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.
749 */
750 AUDIT_PRINTF(("audit_rotate_vnode: waiting for news of "
751 "replacement\n"));
e5568f75
A
752 ret = wait_queue_assert_wait(audit_wait_queue,
753 AUDIT_REPLACEMENT_EVENT,
91447636
A
754 THREAD_UNINT,
755 0);
2d21ac55 756 lck_mtx_unlock(audit_mtx);
55e303ae
A
757
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));
e5568f75
A
763
764 audit_file_rotate_wait = 0; /* We can now request another rotation */
55e303ae
A
765}
766
767/*
768 * Drain the audit queue and close the log at shutdown.
769 */
770void
771audit_shutdown(void)
772{
2d21ac55
A
773 if (audit_mtx)
774 audit_rotate_vnode(NULL, NULL);
55e303ae
A
775}
776
777static __inline__ struct uthread *
778curuthread(void)
779{
91447636 780 return (get_bsdthread_info(current_thread()));
55e303ae
A
781}
782
783static __inline__ struct kaudit_record *
784currecord(void)
785{
55e303ae
A
786 return (curuthread()->uu_ar);
787}
788
789/**********************************
790 * Begin system calls. *
791 **********************************/
792/*
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.
796 *
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.
800 */
55e303ae
A
801/* ARGSUSED */
802int
2d21ac55 803audit(proc_t p, struct audit_args *uap, __unused register_t *retval)
55e303ae 804{
55e303ae
A
805 int error;
806 void * rec;
807 struct kaudit_record *ar;
e5568f75 808 struct uthread *uthr;
55e303ae 809
91447636 810 error = suser(kauth_cred_get(), &p->p_acflag);
55e303ae
A
811 if (error)
812 return (error);
813
2d21ac55
A
814 lck_mtx_lock(audit_mtx);
815 if ((uap->length <= 0) || (uap->length > (int)audit_qctrl.aq_bufsz)) {
816 lck_mtx_unlock(audit_mtx);
e5568f75 817 return (EINVAL);
2d21ac55
A
818 }
819 lck_mtx_unlock(audit_mtx);
e5568f75
A
820
821 ar = currecord();
822
823 /* If there's no current audit record (audit() itself not audited)
824 * commit the user audit record.
825 */
826 if (ar == NULL) {
827 uthr = curuthread();
828 if (uthr == NULL) /* can this happen? */
91447636 829 return (ENOTSUP);
e5568f75
A
830
831 /* This is not very efficient; we're required to allocate
832 * a complete kernel audit record just so the user record
833 * can tag along.
834 */
835 uthr->uu_ar = audit_new(AUE_NULL, p, uthr);
836 if (uthr->uu_ar == NULL) /* auditing not on, or memory error */
837 return (ENOTSUP);
838 ar = uthr->uu_ar;
839 }
840
55e303ae
A
841 if (uap->length > MAX_AUDIT_RECORD_SIZE)
842 return (EINVAL);
843
e5568f75 844 rec = (void *)kalloc((vm_size_t)uap->length);
55e303ae
A
845
846 error = copyin(uap->record, rec, uap->length);
847 if (error)
848 goto free_out;
849
2d21ac55
A
850#if CONFIG_MACF
851 error = mac_system_check_audit(kauth_cred_get(), rec, uap->length);
852 if (error)
853 goto free_out;
854#endif
855
55e303ae
A
856 /* Verify the record */
857 if (bsm_rec_verify(rec) == 0) {
858 error = EINVAL;
859 goto free_out;
860 }
861
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.
865 */
866 ar->k_udata = rec;
e5568f75 867 ar->k_ar_commit |= AR_COMMIT_USER;
55e303ae
A
868 ar->k_ulen = uap->length;
869 return (0);
870
871free_out:
e5568f75
A
872 /* audit_syscall_exit() will free the audit record on the thread
873 * even if we allocated it above.
874 */
91447636 875 kfree(rec, uap->length);
55e303ae
A
876 return (error);
877}
878
879/*
880 * System call to manipulate auditing.
881 */
55e303ae
A
882/* ARGSUSED */
883int
2d21ac55 884auditon(proc_t p, struct auditon_args *uap, __unused register_t *retval)
55e303ae 885{
e5568f75
A
886 int ret;
887 int len;
888 union auditon_udata udata;
2d21ac55
A
889 proc_t tp = PROC_NULL;
890 kauth_cred_t my_cred;
55e303ae 891
e5568f75 892 AUDIT_ARG(cmd, uap->cmd);
91447636 893 ret = suser(kauth_cred_get(), &p->p_acflag);
e5568f75
A
894 if (ret)
895 return (ret);
55e303ae 896
2d21ac55
A
897#if CONFIG_MACF
898 ret = mac_system_check_auditon(kauth_cred_get(), uap->cmd);
899 if (ret)
900 return (ret);
901#endif
902
e5568f75 903 len = uap->length;
91447636 904 if ((len <= 0) || (len > (int)sizeof(union auditon_udata)))
e5568f75 905 return (EINVAL);
55e303ae 906
e5568f75
A
907 memset((void *)&udata, 0, sizeof(udata));
908
909 switch (uap->cmd) {
910 /* Some of the GET commands use the arguments too */
911 case A_SETPOLICY:
912 case A_SETKMASK:
913 case A_SETQCTRL:
914 case A_SETSTAT:
915 case A_SETUMASK:
916 case A_SETSMASK:
917 case A_SETCOND:
918 case A_SETCLASS:
919 case A_SETPMASK:
920 case A_SETFSIZE:
921 case A_SETKAUDIT:
922 case A_GETCLASS:
923 case A_GETPINFO:
924 case A_GETPINFO_ADDR:
925 ret = copyin(uap->data, (void *)&udata, uap->length);
926 if (ret)
927 return (ret);
928 AUDIT_ARG(auditon, &udata);
929 break;
2d21ac55 930 }
e5568f75
A
931
932 /* XXX Need to implement these commands by accessing the global
933 * values associated with the commands.
934 */
2d21ac55 935 lck_mtx_lock(audit_mtx);
e5568f75
A
936 switch (uap->cmd) {
937 case A_GETPOLICY:
938 if (!audit_fail_stop)
939 udata.au_policy |= AUDIT_CNT;
940 if (audit_panic_on_write_fail)
941 udata.au_policy |= AUDIT_AHLT;
942 break;
943 case A_SETPOLICY:
2d21ac55
A
944 if (udata.au_policy & ~(AUDIT_CNT|AUDIT_AHLT)) {
945 ret = EINVAL;
946 break;
947 }
948 /*
e5568f75 949 * XXX - Need to wake up waiters if the policy relaxes?
2d21ac55 950 */
e5568f75
A
951 audit_fail_stop = ((udata.au_policy & AUDIT_CNT) == 0);
952 audit_panic_on_write_fail = (udata.au_policy & AUDIT_AHLT);
953 break;
954 case A_GETKMASK:
955 udata.au_mask = audit_nae_mask;
956 break;
957 case A_SETKMASK:
958 audit_nae_mask = udata.au_mask;
959 break;
960 case A_GETQCTRL:
961 udata.au_qctrl = audit_qctrl;
962 break;
963 case A_SETQCTRL:
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) ||
2d21ac55
A
968 (udata.au_qctrl.aq_minfree > 100)) {
969 ret = EINVAL;
970 break;
971 }
e5568f75
A
972
973 audit_qctrl = udata.au_qctrl;
974 /* XXX The queue delay value isn't used with the kernel. */
975 audit_qctrl.aq_delay = -1;
976 break;
977 case A_GETCWD:
2d21ac55 978 ret = ENOSYS;
e5568f75
A
979 break;
980 case A_GETCAR:
2d21ac55 981 ret = ENOSYS;
e5568f75
A
982 break;
983 case A_GETSTAT:
2d21ac55 984 ret = ENOSYS;
e5568f75
A
985 break;
986 case A_SETSTAT:
2d21ac55 987 ret = ENOSYS;
e5568f75
A
988 break;
989 case A_SETUMASK:
2d21ac55 990 ret = ENOSYS;
e5568f75
A
991 break;
992 case A_SETSMASK:
2d21ac55 993 ret = ENOSYS;
e5568f75
A
994 break;
995 case A_GETCOND:
996 if (audit_enabled && !audit_suspended)
997 udata.au_cond = AUC_AUDITING;
998 else
999 udata.au_cond = AUC_NOAUDIT;
1000 break;
1001 case A_SETCOND:
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;
1008 audit_shutdown();
1009 }
1010 break;
1011 case A_GETCLASS:
1012 udata.au_evclass.ec_class =
1013 au_event_class(udata.au_evclass.ec_number);
1014 break;
1015 case A_SETCLASS:
1016 au_evclassmap_insert(udata.au_evclass.ec_number,
1017 udata.au_evclass.ec_class);
1018 break;
1019 case A_GETPINFO:
2d21ac55
A
1020 if (udata.au_aupinfo.ap_pid < 1) {
1021 ret = EINVAL;
1022 break;
1023 }
1024 if ((tp = proc_find(udata.au_aupinfo.ap_pid)) == NULL) {
1025 ret = EINVAL;
1026 break;
1027 }
e5568f75 1028
2d21ac55
A
1029 lck_mtx_unlock(audit_mtx);
1030 my_cred = kauth_cred_proc_ref(tp);
1031
1032 udata.au_aupinfo.ap_auid = my_cred->cr_au.ai_auid;
e5568f75 1033 udata.au_aupinfo.ap_mask.am_success =
2d21ac55 1034 my_cred->cr_au.ai_mask.am_success;
e5568f75 1035 udata.au_aupinfo.ap_mask.am_failure =
2d21ac55 1036 my_cred->cr_au.ai_mask.am_failure;
e5568f75 1037 udata.au_aupinfo.ap_termid.machine =
2d21ac55 1038 my_cred->cr_au.ai_termid.machine;
e5568f75 1039 udata.au_aupinfo.ap_termid.port =
2d21ac55
A
1040 my_cred->cr_au.ai_termid.port;
1041 udata.au_aupinfo.ap_asid = my_cred->cr_au.ai_asid;
1042
1043 kauth_cred_unref(&my_cred);
1044
1045 proc_rele(tp);
1046 tp = PROC_NULL;
1047 lck_mtx_lock(audit_mtx);
e5568f75
A
1048 break;
1049 case A_SETPMASK:
2d21ac55
A
1050 if (udata.au_aupinfo.ap_pid < 1) {
1051 ret = EINVAL;
1052 break;
1053 }
1054 if ((tp = proc_find(udata.au_aupinfo.ap_pid)) == NULL) {
1055 ret = EINVAL;
1056 break;
1057 }
e5568f75 1058
91447636
A
1059 /*
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.
1065 */
2d21ac55 1066 lck_mtx_unlock(audit_mtx);
91447636 1067 for (;;) {
2d21ac55 1068 kauth_cred_t my_new_cred;
91447636
A
1069 struct auditinfo temp_auditinfo;
1070
1071 my_cred = kauth_cred_proc_ref(tp);
1072 /*
0c530ab8
A
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.
91447636
A
1079 */
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);
1086
1087 if (my_cred != my_new_cred) {
1088 proc_lock(tp);
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.
1092 */
1093 if (tp->p_ucred != my_cred) {
1094 proc_unlock(tp);
0c530ab8 1095 kauth_cred_unref(&my_new_cred);
91447636
A
1096 /* try again */
1097 continue;
1098 }
1099 tp->p_ucred = my_new_cred;
1100 proc_unlock(tp);
1101 }
0c530ab8
A
1102 /* drop old proc reference or our extra reference */
1103 kauth_cred_unref(&my_cred);
91447636
A
1104 break;
1105 }
2d21ac55
A
1106 proc_rele(tp);
1107 lck_mtx_lock(audit_mtx);
e5568f75
A
1108 break;
1109 case A_SETFSIZE:
1110 if ((udata.au_fstat.af_filesz != 0) &&
2d21ac55
A
1111 (udata.au_fstat.af_filesz < MIN_AUDIT_FILE_SIZE)) {
1112 ret = EINVAL;
1113 break;
1114 }
e5568f75
A
1115 audit_fstat.af_filesz = udata.au_fstat.af_filesz;
1116 break;
1117 case A_GETFSIZE:
1118 udata.au_fstat.af_filesz = audit_fstat.af_filesz;
1119 udata.au_fstat.af_currsz = audit_fstat.af_currsz;
1120 break;
1121 case A_GETPINFO_ADDR:
2d21ac55 1122 ret = ENOSYS;
e5568f75
A
1123 break;
1124 case A_GETKAUDIT:
2d21ac55 1125 ret = ENOSYS;
e5568f75
A
1126 break;
1127 case A_SETKAUDIT:
2d21ac55 1128 ret = ENOSYS;
e5568f75 1129 break;
2d21ac55 1130 }
e5568f75 1131 /* Copy data back to userspace for the GET comands */
2d21ac55
A
1132 if (ret == 0) {
1133 switch (uap->cmd) {
1134 case A_GETPOLICY:
1135 case A_GETKMASK:
1136 case A_GETQCTRL:
1137 case A_GETCWD:
1138 case A_GETCAR:
1139 case A_GETSTAT:
1140 case A_GETCOND:
1141 case A_GETCLASS:
1142 case A_GETPINFO:
1143 case A_GETFSIZE:
1144 case A_GETPINFO_ADDR:
1145 case A_GETKAUDIT:
1146 ret = copyout((void *)&udata, uap->data, uap->length);
1147 break;
1148 }
e5568f75
A
1149 }
1150
2d21ac55
A
1151 lck_mtx_unlock(audit_mtx);
1152 return (ret);
55e303ae
A
1153}
1154
1155/*
1156 * System calls to manage the user audit information.
55e303ae 1157 */
55e303ae
A
1158/* ARGSUSED */
1159int
2d21ac55 1160getauid(__unused proc_t p, struct getauid_args *uap, __unused register_t *retval)
55e303ae 1161{
55e303ae
A
1162 int error;
1163
2d21ac55
A
1164#if CONFIG_MACF
1165 error = mac_proc_check_getauid(p);
1166 if (error)
1167 return (error);
1168#endif
1169
91447636
A
1170 error = copyout((void *)&kauth_cred_get()->cr_au.ai_auid,
1171 uap->auid, sizeof(au_id_t));
55e303ae
A
1172 if (error)
1173 return (error);
1174
1175 return (0);
1176}
1177
55e303ae
A
1178/* ARGSUSED */
1179int
2d21ac55 1180setauid(proc_t p, struct setauid_args *uap, __unused register_t *retval)
55e303ae 1181{
55e303ae 1182 int error;
91447636 1183 au_id_t temp_au_id;
55e303ae 1184
91447636 1185 error = suser(kauth_cred_get(), &p->p_acflag);
55e303ae
A
1186 if (error)
1187 return (error);
1188
91447636
A
1189 error = copyin(uap->auid,
1190 (void *)&temp_au_id,
1191 sizeof(au_id_t));
55e303ae
A
1192 if (error)
1193 return (error);
2d21ac55
A
1194#if CONFIG_MACF
1195 error = mac_proc_check_setauid(p, temp_au_id);
1196 if (error)
1197 return (error);
1198#endif
55e303ae 1199
91447636
A
1200 /*
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.
1206 */
1207 for (;;) {
1208 kauth_cred_t my_cred, my_new_cred;
1209 struct auditinfo temp_auditinfo;
1210
1211 my_cred = kauth_cred_proc_ref(p);
1212 /*
0c530ab8
A
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.
91447636
A
1218 */
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);
1222
1223 if (my_cred != my_new_cred) {
1224 proc_lock(p);
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.
1228 */
1229 if (p->p_ucred != my_cred) {
1230 proc_unlock(p);
0c530ab8 1231 kauth_cred_unref(&my_new_cred);
91447636
A
1232 /* try again */
1233 continue;
1234 }
1235 p->p_ucred = my_new_cred;
1236 proc_unlock(p);
1237 }
0c530ab8
A
1238 /* drop old proc reference or our extra reference */
1239 kauth_cred_unref(&my_cred);
91447636
A
1240 break;
1241 }
1242
e5568f75
A
1243 /* propagate the change from the process to Mach task */
1244 set_security_token(p);
1245
91447636 1246 audit_arg_auid(kauth_cred_get()->cr_au.ai_auid);
55e303ae
A
1247 return (0);
1248}
1249
1250/*
1251 * System calls to get and set process audit information.
a3d08fcd
A
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
1255 * returned.
55e303ae 1256 */
55e303ae
A
1257/* ARGSUSED */
1258int
2d21ac55 1259getaudit(proc_t p, struct getaudit_args *uap, __unused register_t *retval)
55e303ae 1260{
91447636 1261 struct auditinfo ai;
55e303ae
A
1262 int error;
1263
2d21ac55
A
1264#if CONFIG_MACF
1265 error = mac_proc_check_getaudit(p);
1266 if (error)
1267 return (error);
1268#endif
1269
91447636
A
1270 ai = kauth_cred_get()->cr_au;
1271
a3d08fcd 1272 /* only superuser gets to see the real mask */
91447636 1273 error = suser(kauth_cred_get(), &p->p_acflag);
a3d08fcd
A
1274 if (error) {
1275 ai.ai_mask.am_success = ~0;
1276 ai.ai_mask.am_failure = ~0;
1277 }
1278
91447636 1279 error = copyout(&ai, uap->auditinfo, sizeof(ai));
55e303ae
A
1280 if (error)
1281 return (error);
1282
1283 return (0);
1284}
1285
55e303ae
A
1286/* ARGSUSED */
1287int
2d21ac55 1288setaudit(proc_t p, struct setaudit_args *uap, __unused register_t *retval)
55e303ae 1289{
55e303ae 1290 int error;
91447636 1291 struct auditinfo temp_auditinfo;
0c530ab8 1292 kauth_cred_t safecred;
55e303ae 1293
91447636 1294 error = suser(kauth_cred_get(), &p->p_acflag);
55e303ae
A
1295 if (error)
1296 return (error);
91447636
A
1297 error = copyin(uap->auditinfo,
1298 (void *)&temp_auditinfo,
1299 sizeof(temp_auditinfo));
55e303ae
A
1300 if (error)
1301 return (error);
2d21ac55
A
1302#if CONFIG_MACF
1303 error = mac_proc_check_setaudit(p, &temp_auditinfo);
1304 if (error)
1305 return (error);
1306
1307#endif
1308
55e303ae 1309
91447636
A
1310 /*
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.
1316 */
1317 for (;;) {
1318 kauth_cred_t my_cred, my_new_cred;
1319
1320 my_cred = kauth_cred_proc_ref(p);
1321 /*
0c530ab8
A
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.
91447636
A
1327 */
1328 my_new_cred = kauth_cred_setauditinfo(my_cred, &temp_auditinfo);
1329
1330 if (my_cred != my_new_cred) {
1331 proc_lock(p);
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.
1335 */
1336 if (p->p_ucred != my_cred) {
1337 proc_unlock(p);
0c530ab8 1338 kauth_cred_unref(&my_new_cred);
91447636
A
1339 /* try again */
1340 continue;
1341 }
1342 p->p_ucred = my_new_cred;
1343 proc_unlock(p);
1344 }
0c530ab8
A
1345 /* drop old proc reference or our extra reference */
1346 kauth_cred_unref(&my_cred);
91447636
A
1347 break;
1348 }
1349
e5568f75
A
1350 /* propagate the change from the process to Mach task */
1351 set_security_token(p);
1352
0c530ab8
A
1353 safecred = kauth_cred_proc_ref(p);
1354 audit_arg_auditinfo(&safecred->cr_au);
1355 kauth_cred_unref(&safecred);
e5568f75 1356
55e303ae
A
1357 return (0);
1358}
1359
55e303ae
A
1360/* ARGSUSED */
1361int
2d21ac55 1362getaudit_addr(__unused proc_t p, __unused struct getaudit_addr_args *uap, __unused register_t *retval)
55e303ae 1363{
55e303ae
A
1364 return (ENOSYS);
1365}
1366
55e303ae
A
1367/* ARGSUSED */
1368int
2d21ac55 1369setaudit_addr(proc_t p, __unused struct setaudit_addr_args *uap, __unused register_t *retval)
55e303ae 1370{
55e303ae
A
1371 int error;
1372
91447636 1373 error = suser(kauth_cred_get(), &p->p_acflag);
55e303ae
A
1374 if (error)
1375 return (error);
1376 return (ENOSYS);
1377}
1378
1379/*
1380 * Syscall to manage audit files.
1381 *
55e303ae 1382 */
55e303ae
A
1383/* ARGSUSED */
1384int
2d21ac55 1385auditctl(proc_t p, struct auditctl_args *uap, __unused register_t *retval)
55e303ae 1386{
55e303ae 1387 struct nameidata nd;
91447636 1388 kauth_cred_t cred;
55e303ae 1389 struct vnode *vp;
2d21ac55 1390 int error;
55e303ae 1391
91447636 1392 error = suser(kauth_cred_get(), &p->p_acflag);
55e303ae
A
1393 if (error)
1394 return (error);
1395
1396 vp = NULL;
1397 cred = NULL;
1398
1399 /*
1400 * If a path is specified, open the replacement vnode, perform
1401 * validity checks, and grab another reference to the current
1402 * credential.
1403 */
2d21ac55 1404 if (uap->path != USER_ADDR_NULL) {
e5568f75 1405 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNPATH1,
91447636 1406 (IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32),
2d21ac55
A
1407 uap->path, vfs_context_current());
1408 error = vn_open(&nd, audit_open_flags, 0);
55e303ae
A
1409 if (error)
1410 goto out;
55e303ae 1411 vp = nd.ni_vp;
2d21ac55 1412
55e303ae 1413 if (vp->v_type != VREG) {
2d21ac55 1414 vn_close(vp, audit_close_flags, vfs_context_current());
91447636 1415 vnode_put(vp);
55e303ae
A
1416 error = EINVAL;
1417 goto out;
1418 }
2d21ac55
A
1419#if CONFIG_MACF
1420 /*
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
1428 * sensitivity.
1429 */
1430
1431 error = mac_system_check_auditctl(kauth_cred_get(), vp);
1432 if (error) {
1433 vn_close(vp, audit_close_flags, vfs_context_current());
1434 vnode_put(vp);
1435 goto out;
1436 }
1437#endif
91447636 1438 cred = kauth_cred_get_with_ref();
2d21ac55 1439 lck_mtx_lock(audit_mtx);
e5568f75 1440 audit_suspended = 0;
2d21ac55 1441 lck_mtx_unlock(audit_mtx);
55e303ae 1442 }
2d21ac55
A
1443#if CONFIG_MACF
1444 else {
1445 error = mac_system_check_auditctl(kauth_cred_get(), NULL);
1446 if (error)
1447 return (error);
1448 }
1449#endif
1450
91447636
A
1451 /*
1452 * a vp and cred of NULL is valid at this point
1453 * and indicates we're to turn off auditing...
1454 */
55e303ae 1455 audit_rotate_vnode(cred, vp);
91447636
A
1456 if (vp)
1457 vnode_put(vp);
55e303ae
A
1458out:
1459 return (error);
1460}
1461
1462/**********************************
1463 * End of system calls. *
1464 **********************************/
1465
1466/*
1467 * MPSAFE
1468 */
1469struct kaudit_record *
2d21ac55 1470audit_new(int event, proc_t p, __unused struct uthread *uthread)
55e303ae
A
1471{
1472 struct kaudit_record *ar;
1473 int no_record;
0c530ab8 1474 kauth_cred_t safecred;
55e303ae
A
1475
1476 /*
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).
1483 */
1484#if 0
1485 if (event != AUDIT_EVENT_FILESTOP && event != AUDIT_EVENT_FILESTART) {
1486#endif
2d21ac55 1487 lck_mtx_lock(audit_mtx);
55e303ae 1488 no_record = (audit_suspended || !audit_enabled);
2d21ac55 1489 lck_mtx_unlock(audit_mtx);
55e303ae
A
1490 if (no_record)
1491 return (NULL);
1492#if 0
1493 }
1494#endif
1495
55e303ae
A
1496 /*
1497 * Initialize the audit record header.
55e303ae 1498 * XXX: We may want to fail-stop if allocation fails.
e5568f75
A
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.
55e303ae 1502 */
e5568f75
A
1503
1504 ar = (struct kaudit_record *)zalloc(audit_zone);
55e303ae
A
1505 if (ar == NULL)
1506 return NULL;
1507
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);
1512
0c530ab8 1513 safecred = kauth_cred_proc_ref(p);
55e303ae 1514 /* Export the subject credential. */
0c530ab8
A
1515 cru2x(safecred, &ar->k_ar.ar_subj_cred);
1516
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);
1525
55e303ae
A
1526 ar->k_ar.ar_subj_pid = p->p_pid;
1527 bcopy(p->p_comm, ar->k_ar.ar_subj_comm, MAXCOMLEN);
55e303ae 1528
2d21ac55
A
1529#if CONFIG_MACF
1530 do {
1531 struct mac mac;
1532
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);
1538 return (NULL);
1539 }
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);
1543
1544 /*
1545 * grab space for the reconds.
1546 */
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);
1553 return (NULL);
1554 }
1555
1556 LIST_INIT(ar->k_ar.ar_mac_records);
1557
1558 ar->k_ar.ar_forced_by_mac = 0;
1559
1560 } while (0);
1561#endif
1562
1563 lck_mtx_lock(audit_mtx);
1564 audit_pre_q_len++;
1565 lck_mtx_unlock(audit_mtx);
1566
55e303ae
A
1567 return (ar);
1568}
1569
1570/*
1571 * MPSAFE
1572 * XXXAUDIT: So far, this is unused, and should probably be GC'd.
1573 */
1574void
1575audit_abort(struct kaudit_record *ar)
1576{
2d21ac55 1577 lck_mtx_lock(audit_mtx);
e5568f75 1578 audit_pre_q_len--;
2d21ac55 1579 lck_mtx_unlock(audit_mtx);
55e303ae
A
1580 audit_free(ar);
1581}
1582
1583/*
1584 * MPSAFE
1585 */
1586void
1587audit_commit(struct kaudit_record *ar, int error, int retval)
1588{
e5568f75
A
1589 int ret;
1590 int sorf;
1591 struct au_mask *aumask;
55e303ae
A
1592
1593 if (ar == NULL)
1594 return;
1595
e5568f75
A
1596 /*
1597 * Decide whether to commit the audit record by checking the
1598 * error value from the system call and using the appropriate
1599 * audit mask.
1600 */
1601 if (ar->k_ar.ar_subj_auid == AU_DEFAUDITID)
1602 aumask = &audit_nae_mask;
1603 else
1604 aumask = &ar->k_ar.ar_subj_amask;
1605
1606 if (error)
1607 sorf = AU_PRS_FAILURE;
1608 else
1609 sorf = AU_PRS_SUCCESS;
1610
1611 switch(ar->k_ar.ar_event) {
1612
1613 case AUE_OPEN_RWTC:
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
1616 * value.
1617 */
1618 ar->k_ar.ar_event = flags_and_error_to_openevent(ar->k_ar.ar_arg_fflags, error);
1619 break;
1620
1621 case AUE_SYSCTL:
1622 ar->k_ar.ar_event = ctlname_to_sysctlevent(ar->k_ar.ar_arg_ctlname, ar->k_ar.ar_valid_arg);
1623 break;
1624
1625 case AUE_AUDITON:
1626 /* Convert the auditon() command to an event */
1627 ar->k_ar.ar_event = auditon_command_event(ar->k_ar.ar_arg_cmd);
1628 break;
1629 }
1630
1631 if (au_preselect(ar->k_ar.ar_event, aumask, sorf) != 0)
1632 ar->k_ar_commit |= AR_COMMIT_KERNEL;
1633
91447636 1634 if ((ar->k_ar_commit & (AR_COMMIT_USER | AR_COMMIT_KERNEL)) == 0) {
2d21ac55 1635 lck_mtx_lock(audit_mtx);
e5568f75 1636 audit_pre_q_len--;
2d21ac55 1637 lck_mtx_unlock(audit_mtx);
e5568f75
A
1638 audit_free(ar);
1639 return;
1640 }
1641
55e303ae
A
1642 ar->k_ar.ar_errno = error;
1643 ar->k_ar.ar_retval = retval;
1644
1645 /*
1646 * We might want to do some system-wide post-filtering
1647 * here at some point.
1648 */
1649
1650 /*
1651 * Timestamp system call end.
1652 */
1653 nanotime(&ar->k_ar.ar_endtime);
1654
2d21ac55 1655 lck_mtx_lock(audit_mtx);
55e303ae
A
1656 /*
1657 * Note: it could be that some records initiated while audit was
1658 * enabled should still be committed?
1659 */
1660 if (audit_suspended || !audit_enabled) {
e5568f75 1661 audit_pre_q_len--;
2d21ac55 1662 lck_mtx_unlock(audit_mtx);
55e303ae
A
1663 audit_free(ar);
1664 return;
1665 }
91447636 1666
e5568f75
A
1667 /*
1668 * Constrain the number of committed audit records based on
1669 * the configurable parameter.
1670 */
1671 while (audit_q_len >= audit_qctrl.aq_hiwater) {
1672
1673 ret = wait_queue_assert_wait(audit_wait_queue,
1674 AUDIT_COMMIT_EVENT,
91447636
A
1675 THREAD_UNINT,
1676 0);
2d21ac55 1677 lck_mtx_unlock(audit_mtx);
e5568f75
A
1678
1679 assert(ret == THREAD_WAITING);
1680
1681 ret = thread_block(THREAD_CONTINUE_NULL);
1682 assert(ret == THREAD_AWAKENED);
2d21ac55 1683 lck_mtx_lock(audit_mtx);
e5568f75
A
1684 }
1685
55e303ae 1686 TAILQ_INSERT_TAIL(&audit_q, ar, k_q);
e5568f75
A
1687 audit_q_len++;
1688 audit_pre_q_len--;
1689 wait_queue_wakeup_one(audit_wait_queue, AUDIT_WORKER_EVENT, THREAD_AWAKENED);
2d21ac55
A
1690 lck_mtx_unlock(audit_mtx);
1691}
1692
1693/*
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.
1697 */
1698static void
1699audit_new_wait(int audit_event, proc_t proc, struct uthread *uthread)
1700{
1701 int ret;
1702
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");
1710 }
1711 uthread->uu_ar = audit_new(audit_event, proc, uthread);
55e303ae
A
1712}
1713
1714/*
1715 * Calls to set up and tear down audit structures associated with
1716 * each system call.
1717 */
1718void
2d21ac55 1719audit_syscall_enter(unsigned short code, proc_t proc,
55e303ae
A
1720 struct uthread *uthread)
1721{
1722 int audit_event;
e5568f75 1723 struct au_mask *aumask;
2d21ac55 1724 kauth_cred_t my_cred;
55e303ae
A
1725
1726 audit_event = sys_au_event[code];
e5568f75
A
1727 if (audit_event == AUE_NULL)
1728 return;
1729
1730 assert(uthread->uu_ar == NULL);
55e303ae 1731
e5568f75
A
1732 /* Check which audit mask to use; either the kernel non-attributable
1733 * event mask or the process audit mask.
1734 */
2d21ac55
A
1735 my_cred = kauth_cred_proc_ref(proc);
1736
1737 if (my_cred->cr_au.ai_auid == AU_DEFAUDITID)
e5568f75
A
1738 aumask = &audit_nae_mask;
1739 else
2d21ac55 1740 aumask = &my_cred->cr_au.ai_mask;
91447636 1741
55e303ae 1742 /*
e5568f75
A
1743 * Allocate an audit record, if preselection allows it, and store
1744 * in the BSD thread for later use.
55e303ae 1745 */
e5568f75 1746
2d21ac55
A
1747#if CONFIG_MACF
1748 do {
1749 int error;
1750
1751 error = mac_audit_check_preselect(my_cred, code,
1752 (void *) uthread->uu_arg);
1753
1754 if (error == MAC_AUDIT_YES) {
91447636 1755 uthread->uu_ar = audit_new(audit_event, proc, uthread);
2d21ac55
A
1756 uthread->uu_ar->k_ar.ar_forced_by_mac = 1;
1757 au_to_text("Forced by a MAC policy");
1758 }
1759 else if (error == MAC_AUDIT_NO) {
91447636
A
1760 uthread->uu_ar = NULL;
1761 }
2d21ac55
A
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);
1766 } while (0);
1767#else
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);
1771 } else {
1772 uthread->uu_ar = NULL;
91447636 1773 }
2d21ac55
A
1774#endif
1775 kauth_cred_unref(&my_cred);
1776}
55e303ae 1777
2d21ac55
A
1778/*
1779 * Note: The audit_syscall_exit() parameter list was modified to support
1780 * mac_audit_check_postselect(), which requires the Darwin syscall number.
1781 */
1782#if CONFIG_MACF
1783void
1784audit_syscall_exit(unsigned short code, int error, AUDIT_PRINTF_ONLY proc_t proc, struct uthread *uthread)
1785#else
55e303ae 1786void
2d21ac55
A
1787audit_syscall_exit(int error, AUDIT_PRINTF_ONLY proc_t proc, struct uthread *uthread)
1788#endif
55e303ae
A
1789{
1790 int retval;
1791
1792 /*
1793 * Commit the audit record as desired; once we pass the record
1794 * into audit_commit(), the memory is owned by the audit
1795 * subsystem.
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.
1799 */
1800 if (error)
1801 retval = -1;
1802 else
1803 retval = uthread->uu_rval[0];
1804
2d21ac55
A
1805#if CONFIG_MACF
1806 do {
1807 int mac_error;
1808
1809 if (uthread->uu_ar == NULL) /* syscall wasn't audited */
1810 goto out;
1811
1812 /*
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.
1819 */
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);
1823
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);
1828 goto out;
1829 }
1830
1831 } while (0);
1832
1833#endif
55e303ae 1834 audit_commit(uthread->uu_ar, error, retval);
91447636 1835 if (uthread->uu_ar != NULL) {
55e303ae 1836 AUDIT_PRINTF(("audit record committed by pid %d\n", proc->p_pid));
91447636 1837 }
2d21ac55
A
1838
1839#if CONFIG_MACF
1840out:
1841#endif
55e303ae
A
1842 uthread->uu_ar = NULL;
1843
1844}
1845
e5568f75
A
1846/*
1847 * Calls to set up and tear down audit structures used during Mach
1848 * system calls.
1849 */
1850void
1851audit_mach_syscall_enter(unsigned short audit_event)
1852{
1853 struct uthread *uthread;
2d21ac55 1854 proc_t proc;
e5568f75 1855 struct au_mask *aumask;
2d21ac55 1856 kauth_cred_t my_cred;
e5568f75
A
1857
1858 if (audit_event == AUE_NULL)
1859 return;
1860
1861 uthread = curuthread();
1862 if (uthread == NULL)
1863 return;
1864
1865 proc = current_proc();
1866 if (proc == NULL)
1867 return;
1868
1869 assert(uthread->uu_ar == NULL);
1870
2d21ac55
A
1871 my_cred = kauth_cred_proc_ref(proc);
1872
e5568f75
A
1873 /* Check which audit mask to use; either the kernel non-attributable
1874 * event mask or the process audit mask.
1875 */
2d21ac55 1876 if (my_cred->cr_au.ai_auid == AU_DEFAUDITID)
e5568f75
A
1877 aumask = &audit_nae_mask;
1878 else
2d21ac55
A
1879 aumask = &my_cred->cr_au.ai_mask;
1880
1881 kauth_cred_unref(&my_cred);
e5568f75
A
1882
1883 /*
1884 * Allocate an audit record, if desired, and store in the BSD
1885 * thread for later use.
1886 */
1887 if (au_preselect(audit_event, aumask,
1888 AU_PRS_FAILURE | AU_PRS_SUCCESS)) {
1889 uthread->uu_ar = audit_new(audit_event, proc, uthread);
1890 } else {
1891 uthread->uu_ar = NULL;
1892 }
1893}
1894
1895void
1896audit_mach_syscall_exit(int retval, struct uthread *uthread)
1897{
1898 /* The error code from Mach system calls is the same as the
1899 * return value
1900 */
1901 /* XXX Is the above statement always true? */
1902 audit_commit(uthread->uu_ar, retval, retval);
1903 uthread->uu_ar = NULL;
1904
1905}
1906
55e303ae
A
1907/*
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.
1914 */
1915void
91447636 1916audit_arg_addr(user_addr_t addr)
55e303ae
A
1917{
1918 struct kaudit_record *ar;
1919
1920 ar = currecord();
1921 if (ar == NULL)
1922 return;
1923
91447636 1924 ar->k_ar.ar_arg_addr = CAST_DOWN(void *, addr); /* XXX */
e5568f75 1925 ar->k_ar.ar_valid_arg |= ARG_ADDR;
55e303ae
A
1926}
1927
1928void
91447636 1929audit_arg_len(user_size_t len)
55e303ae
A
1930{
1931 struct kaudit_record *ar;
1932
1933 ar = currecord();
1934 if (ar == NULL)
1935 return;
1936
91447636 1937 ar->k_ar.ar_arg_len = CAST_DOWN(int, len); /* XXX */
e5568f75 1938 ar->k_ar.ar_valid_arg |= ARG_LEN;
55e303ae
A
1939}
1940
1941void
1942audit_arg_fd(int fd)
1943{
1944 struct kaudit_record *ar;
1945
1946 ar = currecord();
1947 if (ar == NULL)
1948 return;
1949
1950 ar->k_ar.ar_arg_fd = fd;
1951 ar->k_ar.ar_valid_arg |= ARG_FD;
1952}
1953
1954void
1955audit_arg_fflags(int fflags)
1956{
1957 struct kaudit_record *ar;
1958
1959 ar = currecord();
1960 if (ar == NULL)
1961 return;
1962
1963 ar->k_ar.ar_arg_fflags = fflags;
1964 ar->k_ar.ar_valid_arg |= ARG_FFLAGS;
1965}
1966
1967void
1968audit_arg_gid(gid_t gid, gid_t egid, gid_t rgid, gid_t sgid)
1969{
1970 struct kaudit_record *ar;
1971
1972 ar = currecord();
1973 if (ar == NULL)
1974 return;
1975
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);
1981}
1982
1983void
1984audit_arg_uid(uid_t uid, uid_t euid, uid_t ruid, uid_t suid)
1985{
1986 struct kaudit_record *ar;
1987
1988 ar = currecord();
1989 if (ar == NULL)
1990 return;
1991
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);
1997}
1998
1999void
91447636 2000audit_arg_groupset(const gid_t *gidset, u_int gidset_size)
55e303ae 2001{
91447636 2002 uint i;
55e303ae
A
2003 struct kaudit_record *ar;
2004
2005 ar = currecord();
2006 if (ar == NULL)
2007 return;
2008
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;
2013}
2014
2015void
91447636 2016audit_arg_login(const char *login)
55e303ae
A
2017{
2018 struct kaudit_record *ar;
2019
2020 ar = currecord();
2021 if (ar == NULL)
2022 return;
2023
55e303ae 2024 strlcpy(ar->k_ar.ar_arg_login, login, MAXLOGNAME);
55e303ae
A
2025
2026 ar->k_ar.ar_valid_arg |= ARG_LOGIN;
2027}
2028
e5568f75 2029void
91447636 2030audit_arg_ctlname(const int *name, int namelen)
e5568f75
A
2031{
2032 struct kaudit_record *ar;
2033
2034 ar = currecord();
2035 if (ar == NULL)
2036 return;
2037
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);
2041}
2042
55e303ae
A
2043void
2044audit_arg_mask(int mask)
2045{
2046 struct kaudit_record *ar;
2047
2048 ar = currecord();
2049 if (ar == NULL)
2050 return;
2051
2052 ar->k_ar.ar_arg_mask = mask;
2053 ar->k_ar.ar_valid_arg |= ARG_MASK;
2054}
2055
2056void
2057audit_arg_mode(mode_t mode)
2058{
2059 struct kaudit_record *ar;
2060
2061 ar = currecord();
2062 if (ar == NULL)
2063 return;
2064
2065 ar->k_ar.ar_arg_mode = mode;
2066 ar->k_ar.ar_valid_arg |= ARG_MODE;
2067}
2068
2069void
2070audit_arg_dev(int dev)
2071{
2072 struct kaudit_record *ar;
2073
2074 ar = currecord();
2075 if (ar == NULL)
2076 return;
2077
2078 ar->k_ar.ar_arg_dev = dev;
2079 ar->k_ar.ar_valid_arg |= ARG_DEV;
2080}
2081
e5568f75
A
2082void
2083audit_arg_value(long value)
2084{
2085 struct kaudit_record *ar;
2086
2087 ar = currecord();
2088 if (ar == NULL)
2089 return;
2090
2091 ar->k_ar.ar_arg_value = value;
2092 ar->k_ar.ar_valid_arg |= ARG_VALUE;
2093}
2094
55e303ae
A
2095void
2096audit_arg_owner(uid_t uid, gid_t gid)
2097{
2098 struct kaudit_record *ar;
2099
2100 ar = currecord();
2101 if (ar == NULL)
2102 return;
2103
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);
2107}
2108
2109void
2110audit_arg_pid(pid_t pid)
2111{
2112 struct kaudit_record *ar;
2113
2114 ar = currecord();
2115 if (ar == NULL)
2116 return;
2117
2118 ar->k_ar.ar_arg_pid = pid;
2119 ar->k_ar.ar_valid_arg |= ARG_PID;
e5568f75
A
2120}
2121
2122void
2d21ac55 2123audit_arg_process(proc_t p)
e5568f75
A
2124{
2125 struct kaudit_record *ar;
2d21ac55 2126 kauth_cred_t my_cred;
e5568f75
A
2127
2128 ar = currecord();
2129 if ((ar == NULL) || (p == NULL))
2130 return;
2131
2d21ac55
A
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);
e5568f75
A
2141
2142 ar->k_ar.ar_valid_arg |= ARG_AUID | ARG_EUID | ARG_EGID | ARG_RUID |
2143 ARG_RGID | ARG_ASID | ARG_TERMID | ARG_PROCESS;
55e303ae
A
2144}
2145
2146void
2147audit_arg_signum(u_int signum)
2148{
2149 struct kaudit_record *ar;
2150
2151 ar = currecord();
2152 if (ar == NULL)
2153 return;
2154
2155 ar->k_ar.ar_arg_signum = signum;
2156 ar->k_ar.ar_valid_arg |= ARG_SIGNUM;
2157}
2158
2159void
2160audit_arg_socket(int sodomain, int sotype, int soprotocol)
2161{
2162
2163 struct kaudit_record *ar;
2164
2165 ar = currecord();
2166 if (ar == NULL)
2167 return;
2168
e5568f75
A
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;
55e303ae
A
2172 ar->k_ar.ar_valid_arg |= ARG_SOCKINFO;
2173}
2174
2d21ac55
A
2175/*
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.
2181 */
55e303ae 2182void
2d21ac55 2183audit_arg_sockaddr(struct vnode *cwd_vp, struct sockaddr *so)
55e303ae
A
2184{
2185 struct kaudit_record *ar;
2186
2187 ar = currecord();
2d21ac55 2188 if (ar == NULL || cwd_vp == NULL || so == NULL)
55e303ae
A
2189 return;
2190
2191 bcopy(so, &ar->k_ar.ar_arg_sockaddr, sizeof(ar->k_ar.ar_arg_sockaddr));
2192 switch (so->sa_family) {
2193 case AF_INET:
2194 ar->k_ar.ar_valid_arg |= ARG_SADDRINET;
2195 break;
2196 case AF_INET6:
2197 ar->k_ar.ar_valid_arg |= ARG_SADDRINET6;
2198 break;
2199 case AF_UNIX:
2d21ac55 2200 audit_arg_upath(cwd_vp, ((struct sockaddr_un *)so)->sun_path,
55e303ae
A
2201 ARG_UPATH1);
2202 ar->k_ar.ar_valid_arg |= ARG_SADDRUNIX;
2203 break;
2204 }
2205}
2206
2207void
2208audit_arg_auid(uid_t auid)
2209{
2210 struct kaudit_record *ar;
2211
2212 ar = currecord();
2213 if (ar == NULL)
2214 return;
2215
2216 ar->k_ar.ar_arg_auid = auid;
2217 ar->k_ar.ar_valid_arg |= ARG_AUID;
2218}
2219
e5568f75 2220void
91447636 2221audit_arg_auditinfo(const struct auditinfo *au_info)
e5568f75
A
2222{
2223 struct kaudit_record *ar;
2224
2225 ar = currecord();
2226 if (ar == NULL)
2227 return;
2228
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;
2236}
2237
55e303ae 2238void
91447636 2239audit_arg_text(const char *text)
55e303ae
A
2240{
2241 struct kaudit_record *ar;
2242
2243 ar = currecord();
2244 if (ar == NULL)
2245 return;
2246
2247 /* Invalidate the text string */
2248 ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_TEXT);
2249 if (text == NULL)
2250 return;
2251
2252 if (ar->k_ar.ar_arg_text == NULL) {
e5568f75 2253 ar->k_ar.ar_arg_text = (char *)kalloc(MAXPATHLEN);
55e303ae
A
2254 if (ar->k_ar.ar_arg_text == NULL)
2255 return;
2256 }
2257
2d21ac55 2258 strlcpy(ar->k_ar.ar_arg_text, text, MAXPATHLEN);
55e303ae
A
2259 ar->k_ar.ar_valid_arg |= ARG_TEXT;
2260}
2261
2262void
2263audit_arg_cmd(int cmd)
2264{
2265 struct kaudit_record *ar;
2266
2267 ar = currecord();
2268 if (ar == NULL)
2269 return;
2270
2271 ar->k_ar.ar_arg_cmd = cmd;
2272 ar->k_ar.ar_valid_arg |= ARG_CMD;
2273}
2274
2275void
2276audit_arg_svipc_cmd(int cmd)
2277{
2278 struct kaudit_record *ar;
2279
2280 ar = currecord();
2281 if (ar == NULL)
2282 return;
2283
2284 ar->k_ar.ar_arg_svipc_cmd = cmd;
2285 ar->k_ar.ar_valid_arg |= ARG_SVIPC_CMD;
2286}
2287
2288void
91447636 2289audit_arg_svipc_perm(const struct ipc_perm *perm)
55e303ae
A
2290{
2291 struct kaudit_record *ar;
2292
2293 ar = currecord();
2294 if (ar == NULL)
2295 return;
2296
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;
2300}
2301
2302void
2303audit_arg_svipc_id(int id)
2304{
2305 struct kaudit_record *ar;
2306
2307 ar = currecord();
2308 if (ar == NULL)
2309 return;
2310
2311 ar->k_ar.ar_arg_svipc_id = id;
2312 ar->k_ar.ar_valid_arg |= ARG_SVIPC_ID;
2313}
2314
2315void
2d21ac55 2316audit_arg_svipc_addr(user_addr_t addr)
55e303ae
A
2317{
2318 struct kaudit_record *ar;
2319
2320 ar = currecord();
2321 if (ar == NULL)
2322 return;
2323
2324 ar->k_ar.ar_arg_svipc_addr = addr;
2325 ar->k_ar.ar_valid_arg |= ARG_SVIPC_ADDR;
2326}
2327
e5568f75
A
2328void
2329audit_arg_posix_ipc_perm(uid_t uid, gid_t gid, mode_t mode)
2330{
2331 struct kaudit_record *ar;
2332
2333 ar = currecord();
2334 if (ar == NULL)
2335 return;
2336
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;
2341}
2342
2343void
91447636 2344audit_arg_auditon(const union auditon_udata *udata)
e5568f75
A
2345{
2346 struct kaudit_record *ar;
2347
2348 ar = currecord();
2349 if (ar == NULL)
2350 return;
2351
91447636 2352 bcopy((const void *)udata, &ar->k_ar.ar_arg_auditon,
e5568f75
A
2353 sizeof(ar->k_ar.ar_arg_auditon));
2354 ar->k_ar.ar_valid_arg |= ARG_AUDITON;
2355}
2356
91447636 2357/*
e5568f75
A
2358 * Audit information about a file, either the file's vnode info, or its
2359 * socket address info.
2360 */
2361void
2d21ac55 2362audit_arg_file(__unused proc_t p, const struct fileproc *fp)
e5568f75
A
2363{
2364 struct kaudit_record *ar;
2365 struct socket *so;
2366 struct inpcb *pcb;
2367
91447636
A
2368 if (fp->f_fglob->fg_type == DTYPE_VNODE) {
2369 audit_arg_vnpath_withref((struct vnode *)fp->f_fglob->fg_data, ARG_VNODE1);
e5568f75
A
2370 return;
2371 }
2372
91447636 2373 if (fp->f_fglob->fg_type == DTYPE_SOCKET) {
e5568f75
A
2374 ar = currecord();
2375 if (ar == NULL)
2376 return;
91447636 2377 so = (struct socket *)fp->f_fglob->fg_data;
e5568f75
A
2378 if (INP_CHECK_SOCKAF(so, PF_INET)) {
2379 if (so->so_pcb == NULL)
2380 return;
2381 ar->k_ar.ar_arg_sockinfo.so_type =
2382 so->so_type;
2383 ar->k_ar.ar_arg_sockinfo.so_domain =
2384 INP_SOCKAF(so);
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 =
2393 pcb->inp_fport;
2394 ar->k_ar.ar_arg_sockinfo.so_lport =
2395 pcb->inp_lport;
2396 ar->k_ar.ar_valid_arg |= ARG_SOCKINFO;
2397 }
2398 }
2399
2400}
2401
55e303ae
A
2402
2403/*
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
2d21ac55
A
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.
55e303ae
A
2412 */
2413void
2d21ac55 2414audit_arg_upath(struct vnode *cwd_vp, char *upath, u_int64_t flags)
55e303ae
A
2415{
2416 struct kaudit_record *ar;
2417 char **pathp;
2418
2d21ac55 2419 if (cwd_vp == NULL || upath == NULL)
55e303ae
A
2420 return; /* nothing to do! */
2421
91447636 2422 if ((flags & (ARG_UPATH1 | ARG_UPATH2)) == 0)
55e303ae
A
2423 return;
2424
2425 ar = currecord();
2426 if (ar == NULL) /* This will be the case for unaudited system calls */
2427 return;
2428
2429 if (flags & ARG_UPATH1) {
2430 ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_UPATH1);
2431 pathp = &ar->k_ar.ar_arg_upath1;
2432 }
2433 else {
2434 ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_UPATH2);
2435 pathp = &ar->k_ar.ar_arg_upath2;
2436 }
2437
2438 if (*pathp == NULL) {
e5568f75 2439 *pathp = (char *)kalloc(MAXPATHLEN);
55e303ae
A
2440 if (*pathp == NULL)
2441 return;
2442 }
2443
2d21ac55 2444 if (canon_path(cwd_vp, upath, *pathp) == 0) {
e5568f75
A
2445 if (flags & ARG_UPATH1)
2446 ar->k_ar.ar_valid_arg |= ARG_UPATH1;
2447 else
2448 ar->k_ar.ar_valid_arg |= ARG_UPATH2;
91447636
A
2449 } else {
2450 kfree(*pathp, MAXPATHLEN);
2451 *pathp = NULL;
e5568f75 2452 }
55e303ae
A
2453}
2454
2455/*
2456 * Function to save the path and vnode attr information into the audit
2457 * record.
2458 *
2459 * It is assumed that the caller will hold any vnode locks necessary to
91447636 2460 * perform a VNOP_GETATTR() on the passed vnode.
55e303ae
A
2461 *
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.
2468 */
2469void
2470audit_arg_vnpath(struct vnode *vp, u_int64_t flags)
2471{
2472 struct kaudit_record *ar;
91447636 2473 struct vnode_attr va;
55e303ae
A
2474 int error;
2475 int len;
2476 char **pathp;
2477 struct vnode_au_info *vnp;
2d21ac55
A
2478 proc_t p;
2479#if CONFIG_MACF
2480 char **vnode_mac_labelp;
2481 struct mac mac;
2482#endif
55e303ae
A
2483
2484 if (vp == NULL)
2485 return;
2486
2487 ar = currecord();
2488 if (ar == NULL) /* This will be the case for unaudited system calls */
2489 return;
2490
91447636 2491 if ((flags & (ARG_VNODE1 | ARG_VNODE2)) == 0)
55e303ae
A
2492 return;
2493
2494 p = current_proc();
2495
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;
2d21ac55
A
2501#if CONFIG_MACF
2502 vnode_mac_labelp = &ar->k_ar.ar_vnode1_mac_labels;
2503#endif
55e303ae
A
2504 }
2505 else {
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;
2d21ac55
A
2510#if CONFIG_MACF
2511 vnode_mac_labelp = &ar->k_ar.ar_vnode2_mac_labels;
2512#endif
55e303ae
A
2513 }
2514
2515 if (*pathp == NULL) {
e5568f75 2516 *pathp = (char *)kalloc(MAXPATHLEN);
55e303ae
A
2517 if (*pathp == NULL)
2518 return;
2519 }
2520
e5568f75
A
2521 /*
2522 * If vn_getpath() succeeds, place it in a string buffer
2523 * attached to the audit record, and set a flag indicating
2524 * it is present.
2525 */
55e303ae 2526 len = MAXPATHLEN;
e5568f75 2527 if (vn_getpath(vp, *pathp, &len) == 0) {
91447636
A
2528 if (flags & ARG_VNODE1)
2529 ar->k_ar.ar_valid_arg |= ARG_KPATH1;
2530 else
2531 ar->k_ar.ar_valid_arg |= ARG_KPATH2;
e5568f75 2532 } else {
91447636 2533 kfree(*pathp, MAXPATHLEN);
e5568f75
A
2534 *pathp = NULL;
2535 }
55e303ae 2536
91447636
A
2537 VATTR_INIT(&va);
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);
2d21ac55 2545 error = vnode_getattr(vp, &va, vfs_context_current());
55e303ae
A
2546 if (error) {
2547 /* XXX: How to handle this case? */
2548 return;
2549 }
2550
2d21ac55
A
2551#if CONFIG_MACF
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);
2558 }
2559
2560
2561
2562 }
2563#endif
2564
91447636
A
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;
55e303ae
A
2573 if (flags & ARG_VNODE1)
2574 ar->k_ar.ar_valid_arg |= ARG_VNODE1;
2575 else
2576 ar->k_ar.ar_valid_arg |= ARG_VNODE2;
2577
2578}
2579
e5568f75 2580void
91447636
A
2581audit_arg_vnpath_withref(struct vnode *vp, u_int64_t flags)
2582{
2583 if (vp == NULL || vnode_getwithref(vp))
2584 return;
2585 audit_arg_vnpath(vp, flags);
2586 (void)vnode_put(vp);
2587}
2588
2589void
2590audit_arg_mach_port1(mach_port_name_t port)
e5568f75
A
2591{
2592 struct kaudit_record *ar;
2593
2594 ar = currecord();
2595 if (ar == NULL)
2596 return;
2597
2598 ar->k_ar.ar_arg_mach_port1 = port;
2599 ar->k_ar.ar_valid_arg |= ARG_MACHPORT1;
2600}
2601
2602void
91447636 2603audit_arg_mach_port2(mach_port_name_t port)
e5568f75
A
2604{
2605 struct kaudit_record *ar;
2606
2607 ar = currecord();
2608 if (ar == NULL)
2609 return;
2610
2611 ar->k_ar.ar_arg_mach_port2 = port;
2612 ar->k_ar.ar_valid_arg |= ARG_MACHPORT2;
2613}
2614
2615/*
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.
2619 */
2620void
2d21ac55 2621audit_sysclose(proc_t p, int fd)
e5568f75 2622{
91447636
A
2623 struct fileproc *fp;
2624 struct vnode *vp;
e5568f75
A
2625
2626 audit_arg_fd(fd);
2627
91447636 2628 if (fp_getfvp(p, fd, &fp, &vp) != 0)
e5568f75
A
2629 return;
2630
91447636
A
2631 audit_arg_vnpath_withref((struct vnode *)fp->f_fglob->fg_data, ARG_VNODE1);
2632 file_drop(fd);
e5568f75
A
2633}
2634
2d21ac55
A
2635#if CONFIG_MACF
2636/*
2637 * This function is called by the MAC Framework to add audit data
2638 * from a policy to the current audit record.
2639 */
2640int
2641audit_mac_data(int type, int len, u_char *data) {
2642 struct kaudit_record *cur;
2643 struct mac_audit_record *record;
2644 int ret = 0;
2645
2646 if (audit_enabled == 0) {
2647 ret = ENOTSUP;
2648 goto out_fail;
2649 }
2650
2651 cur = currecord();
2652 if (cur == NULL) {
2653 ret = ENOTSUP;
2654 goto out_fail;
2655 }
2656
2657 /*
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.
2661 */
2662 record = (struct mac_audit_record *)kalloc(sizeof(*record));
2663 if (record == NULL)
2664 goto out_fail;
2665
2666 record->type = type;
2667 record->length = len;
2668 record->data = data;
2669 LIST_INSERT_HEAD(cur->k_ar.ar_mac_records, record, records);
2670
2671 return (0);
2672
2673out_fail:
2674 kfree(data, len);
2675 return (ret);
2676}
2677
2678void
2679audit_arg_mac_string(const char *string)
2680{
2681 struct kaudit_record *ar;
2682
2683 ar = currecord();
2684 if (ar == NULL)
2685 return;
2686
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).
2693 */
2694 if (ar->k_ar.ar_arg_mac_string == NULL)
2695 return;
2696 }
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;
2700
2701}
2702#endif /* MAC */
2703
2704/*
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.
2708 */
2709
2710int
2711kau_will_audit(void)
2712{
2713
2714 return (audit_enabled && currecord() != NULL);
2715}
2716
55e303ae
A
2717#else /* !AUDIT */
2718
2719void
2720audit_init(void)
2721{
2722
2723}
2724
2725void
2726audit_shutdown(void)
2727{
2728
2729}
2730
2731int
2d21ac55 2732audit(proc_t p, struct audit_args *uap, register_t *retval)
55e303ae
A
2733{
2734 return (ENOSYS);
2735}
2736
2737int
2d21ac55 2738auditon(proc_t p, struct auditon_args *uap, register_t *retval)
55e303ae
A
2739{
2740 return (ENOSYS);
2741}
2742
55e303ae 2743int
2d21ac55 2744getauid(proc_t p, struct getauid_args *uap, register_t *retval)
55e303ae
A
2745{
2746 return (ENOSYS);
2747}
2748
2749int
2d21ac55 2750setauid(proc_t p, struct setauid_args *uap, register_t *retval)
55e303ae
A
2751{
2752 return (ENOSYS);
2753}
2754
2755int
2d21ac55 2756getaudit(proc_t p, struct getaudit_args *uap, register_t *retval)
55e303ae
A
2757{
2758 return (ENOSYS);
2759}
2760
2761int
2d21ac55 2762setaudit(proc_t p, struct setaudit_args *uap, register_t *retval)
55e303ae
A
2763{
2764 return (ENOSYS);
2765}
2766
2767int
2d21ac55 2768getaudit_addr(proc_t p, struct getaudit_addr_args *uap, register_t *retval)
55e303ae
A
2769{
2770 return (ENOSYS);
2771}
2772
2773int
2d21ac55 2774setaudit_addr(proc_t p, struct setaudit_addr_args *uap, register_t *retval)
55e303ae
A
2775{
2776 return (ENOSYS);
2777}
2778
2779int
2d21ac55 2780auditctl(proc_t p, struct auditctl_args *uap, register_t *retval)
55e303ae
A
2781{
2782 return (ENOSYS);
2783}
2784
2d21ac55
A
2785#if CONFIG_MACF
2786void
2787audit_mac_data(int type, int len, u_char *data)
2788{
2789}
2790
2791int
2792kau_will_audit()
2793{
2794 return (0);
2795}
2796#endif
2797
55e303ae 2798#endif /* AUDIT */