2 * Copyright (c) 1999-2009 Apple Inc.
3 * Copyright (c) 2005 Robert N. M. Watson
6 * @APPLE_BSD_LICENSE_HEADER_START@
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of Apple Inc. ("Apple") nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
24 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
29 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
32 * @APPLE_BSD_LICENSE_HEADER_END@
35 * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce
36 * support for mandatory and extensible security protections. This notice
37 * is included in support of clause 2.2 (b) of the Apple Public License,
41 #include <sys/systm.h>
42 #include <sys/sysent.h>
43 #include <sys/types.h>
44 #include <sys/proc_internal.h>
45 #include <sys/vnode_internal.h>
46 #include <sys/fcntl.h>
47 #include <sys/filedesc.h>
49 #include <sys/syscall.h>
51 #include <bsm/audit.h>
52 #include <bsm/audit_kevents.h>
53 #include <security/audit/audit.h>
54 #include <security/audit/audit_bsd.h>
55 #include <security/audit/audit_private.h>
59 * Hash table functions for the audit event number to event class mask
62 #define EVCLASSMAP_HASH_TABLE_SIZE 251
66 LIST_ENTRY(evclass_elem
) entry
;
69 LIST_HEAD(, evclass_elem
) head
;
72 static MALLOC_DEFINE(M_AUDITEVCLASS
, "audit_evclass", "Audit event class");
73 static struct rwlock evclass_lock
;
74 static struct evclass_list evclass_hash
[EVCLASSMAP_HASH_TABLE_SIZE
];
76 #define EVCLASS_LOCK_INIT() rw_init(&evclass_lock, "evclass_lock")
77 #define EVCLASS_RLOCK() rw_rlock(&evclass_lock)
78 #define EVCLASS_RUNLOCK() rw_runlock(&evclass_lock)
79 #define EVCLASS_WLOCK() rw_wlock(&evclass_lock)
80 #define EVCLASS_WUNLOCK() rw_wunlock(&evclass_lock)
83 * Look up the class for an audit event in the class mapping table.
86 au_event_class(au_event_t event
)
88 struct evclass_list
*evcl
;
89 struct evclass_elem
*evc
;
93 evcl
= &evclass_hash
[event
% EVCLASSMAP_HASH_TABLE_SIZE
];
95 LIST_FOREACH(evc
, &evcl
->head
, entry
) {
96 if (evc
->event
== event
) {
107 * Insert a event to class mapping. If the event already exists in the
108 * mapping, then replace the mapping with the new one.
110 * XXX There is currently no constraints placed on the number of mappings.
111 * May want to either limit to a number, or in terms of memory usage.
114 au_evclassmap_insert(au_event_t event
, au_class_t
class)
116 struct evclass_list
*evcl
;
117 struct evclass_elem
*evc
, *evc_new
;
120 * If this event requires auditing a system call then add it to our
121 * audit kernel event mask. We use audit_kevent_mask to check to see
122 * if the audit syscalls flag needs to be set when preselection masks
125 if (AUE_IS_A_KEVENT(event
))
126 audit_kevent_mask
|= class;
129 * Pessimistically, always allocate storage before acquiring mutex.
130 * Free if there is already a mapping for this event.
132 evc_new
= malloc(sizeof(*evc
), M_AUDITEVCLASS
, M_WAITOK
);
135 evcl
= &evclass_hash
[event
% EVCLASSMAP_HASH_TABLE_SIZE
];
136 LIST_FOREACH(evc
, &evcl
->head
, entry
) {
137 if (evc
->event
== event
) {
140 free(evc_new
, M_AUDITEVCLASS
);
147 LIST_INSERT_HEAD(&evcl
->head
, evc
, entry
);
152 au_evclassmap_init(void)
157 for (i
= 0; i
< EVCLASSMAP_HASH_TABLE_SIZE
; i
++)
158 LIST_INIT(&evclass_hash
[i
].head
);
161 * Set up the initial event to class mapping for system calls.
163 for (i
= 0; i
< nsysent
; i
++) {
164 if (sys_au_event
[i
] != AUE_NULL
)
165 au_evclassmap_insert(sys_au_event
[i
], 0);
170 * Add the Mach system call events. These are not in sys_au_event[].
172 au_evclassmap_insert(AUE_TASKFORPID
, 0);
173 au_evclassmap_insert(AUE_PIDFORTASK
, 0);
174 au_evclassmap_insert(AUE_SWAPON
, 0);
175 au_evclassmap_insert(AUE_SWAPOFF
, 0);
176 au_evclassmap_insert(AUE_MAPFD
, 0);
177 au_evclassmap_insert(AUE_INITPROCESS
, 0);
181 * Check whether an event is aditable by comparing the mask of classes this
182 * event is part of against the given mask.
185 au_preselect(__unused au_event_t event
, au_class_t
class, au_mask_t
*mask_p
,
188 au_class_t effmask
= 0;
194 * Perform the actual check of the masks against the event.
196 if (sorf
& AU_PRS_SUCCESS
)
197 effmask
|= (mask_p
->am_success
& class);
199 if (sorf
& AU_PRS_FAILURE
)
200 effmask
|= (mask_p
->am_failure
& class);
209 * Convert sysctl names and present arguments to events.
212 audit_ctlname_to_sysctlevent(int name
[], uint64_t valid_arg
)
215 /* can't parse it - so return the worst case */
216 if ((valid_arg
& (ARG_CTLNAME
| ARG_LEN
)) != (ARG_CTLNAME
| ARG_LEN
))
220 /* non-admin "lookups" treat them special */
230 case KERN_JOB_CONTROL
:
235 case KERN_SHREG_PRIVATIZABLE
:
237 return (AUE_SYSCTL_NONADMIN
);
239 /* only treat the changeable controls as admin */
243 case KERN_MAXPROCPERUID
:
244 case KERN_MAXFILESPERPROC
:
247 case KERN_AIOPROCMAX
:
248 case KERN_AIOTHREADS
:
250 case KERN_SUGID_COREDUMP
:
251 case KERN_NX_PROTECTION
:
252 return ((valid_arg
& ARG_VALUE32
) ?
253 AUE_SYSCTL
: AUE_SYSCTL_NONADMIN
);
262 * Convert an open flags specifier into a specific type of open event for
266 audit_flags_and_error_to_openevent(int oflags
, int error
)
271 * Need to check only those flags we care about.
273 oflags
= oflags
& (O_RDONLY
| O_CREAT
| O_TRUNC
| O_RDWR
| O_WRONLY
);
276 * These checks determine what flags are on with the condition that
277 * ONLY that combination is on, and no other flags are on.
284 case (O_RDONLY
| O_CREAT
):
285 aevent
= AUE_OPEN_RC
;
288 case (O_RDONLY
| O_CREAT
| O_TRUNC
):
289 aevent
= AUE_OPEN_RTC
;
292 case (O_RDONLY
| O_TRUNC
):
293 aevent
= AUE_OPEN_RT
;
297 aevent
= AUE_OPEN_RW
;
300 case (O_RDWR
| O_CREAT
):
301 aevent
= AUE_OPEN_RWC
;
304 case (O_RDWR
| O_CREAT
| O_TRUNC
):
305 aevent
= AUE_OPEN_RWTC
;
308 case (O_RDWR
| O_TRUNC
):
309 aevent
= AUE_OPEN_RWT
;
316 case (O_WRONLY
| O_CREAT
):
317 aevent
= AUE_OPEN_WC
;
320 case (O_WRONLY
| O_CREAT
| O_TRUNC
):
321 aevent
= AUE_OPEN_WTC
;
324 case (O_WRONLY
| O_TRUNC
):
325 aevent
= AUE_OPEN_WT
;
334 * Convert chatty errors to better matching events. Failures to
335 * find a file are really just attribute events -- so recast them as
338 * XXXAUDIT: Solaris defines that AUE_OPEN will never be returned, it
339 * is just a placeholder. However, in Darwin we return that in
340 * preference to other events.
342 * XXXRW: This behavior differs from FreeBSD, so possibly revise this
343 * code or this comment.
359 * Convert an open flags specifier into a specific type of open_extended event
360 * for auditing purposes.
363 audit_flags_and_error_to_openextendedevent(int oflags
, int error
)
368 * Need to check only those flags we care about.
370 oflags
= oflags
& (O_RDONLY
| O_CREAT
| O_TRUNC
| O_RDWR
| O_WRONLY
);
373 * These checks determine what flags are on with the condition that
374 * ONLY that combination is on, and no other flags are on.
378 aevent
= AUE_OPEN_EXTENDED_R
;
381 case (O_RDONLY
| O_CREAT
):
382 aevent
= AUE_OPEN_EXTENDED_RC
;
385 case (O_RDONLY
| O_CREAT
| O_TRUNC
):
386 aevent
= AUE_OPEN_EXTENDED_RTC
;
389 case (O_RDONLY
| O_TRUNC
):
390 aevent
= AUE_OPEN_EXTENDED_RT
;
394 aevent
= AUE_OPEN_EXTENDED_RW
;
397 case (O_RDWR
| O_CREAT
):
398 aevent
= AUE_OPEN_EXTENDED_RWC
;
401 case (O_RDWR
| O_CREAT
| O_TRUNC
):
402 aevent
= AUE_OPEN_EXTENDED_RWTC
;
405 case (O_RDWR
| O_TRUNC
):
406 aevent
= AUE_OPEN_EXTENDED_RWT
;
410 aevent
= AUE_OPEN_EXTENDED_W
;
413 case (O_WRONLY
| O_CREAT
):
414 aevent
= AUE_OPEN_EXTENDED_WC
;
417 case (O_WRONLY
| O_CREAT
| O_TRUNC
):
418 aevent
= AUE_OPEN_EXTENDED_WTC
;
421 case (O_WRONLY
| O_TRUNC
):
422 aevent
= AUE_OPEN_EXTENDED_WT
;
426 aevent
= AUE_OPEN_EXTENDED
;
431 * Convert chatty errors to better matching events. Failures to
432 * find a file are really just attribute events -- so recast them as
435 * XXXAUDIT: Solaris defines that AUE_OPEN will never be returned, it
436 * is just a placeholder. However, in Darwin we return that in
437 * preference to other events.
439 * XXXRW: This behavior differs from FreeBSD, so possibly revise this
440 * code or this comment.
443 case AUE_OPEN_EXTENDED_R
:
444 case AUE_OPEN_EXTENDED_RT
:
445 case AUE_OPEN_EXTENDED_RW
:
446 case AUE_OPEN_EXTENDED_RWT
:
447 case AUE_OPEN_EXTENDED_W
:
448 case AUE_OPEN_EXTENDED_WT
:
450 aevent
= AUE_OPEN_EXTENDED
;
456 * Convert an open flags specifier into a specific type of open_extended event
457 * for auditing purposes.
460 audit_flags_and_error_to_openatevent(int oflags
, int error
)
465 * Need to check only those flags we care about.
467 oflags
= oflags
& (O_RDONLY
| O_CREAT
| O_TRUNC
| O_RDWR
| O_WRONLY
);
470 * These checks determine what flags are on with the condition that
471 * ONLY that combination is on, and no other flags are on.
475 aevent
= AUE_OPENAT_R
;
478 case (O_RDONLY
| O_CREAT
):
479 aevent
= AUE_OPENAT_RC
;
482 case (O_RDONLY
| O_CREAT
| O_TRUNC
):
483 aevent
= AUE_OPENAT_RTC
;
486 case (O_RDONLY
| O_TRUNC
):
487 aevent
= AUE_OPENAT_RT
;
491 aevent
= AUE_OPENAT_RW
;
494 case (O_RDWR
| O_CREAT
):
495 aevent
= AUE_OPENAT_RWC
;
498 case (O_RDWR
| O_CREAT
| O_TRUNC
):
499 aevent
= AUE_OPENAT_RWTC
;
502 case (O_RDWR
| O_TRUNC
):
503 aevent
= AUE_OPENAT_RWT
;
507 aevent
= AUE_OPENAT_W
;
510 case (O_WRONLY
| O_CREAT
):
511 aevent
= AUE_OPENAT_WC
;
514 case (O_WRONLY
| O_CREAT
| O_TRUNC
):
515 aevent
= AUE_OPENAT_WTC
;
518 case (O_WRONLY
| O_TRUNC
):
519 aevent
= AUE_OPENAT_WT
;
528 * Convert chatty errors to better matching events. Failures to
529 * find a file are really just attribute events -- so recast them as
532 * XXXAUDIT: Solaris defines that AUE_OPENAT will never be returned, it
533 * is just a placeholder. However, in Darwin we return that in
534 * preference to other events.
536 * XXXRW: This behavior differs from FreeBSD, so possibly revise this
537 * code or this comment.
553 * Convert an open flags specifier into a specific type of openbyid event
554 * for auditing purposes.
557 audit_flags_and_error_to_openbyidevent(int oflags
, int error
)
562 * Need to check only those flags we care about.
564 oflags
= oflags
& (O_RDONLY
| O_TRUNC
| O_RDWR
| O_WRONLY
);
567 * These checks determine what flags are on with the condition that
568 * ONLY that combination is on, and no other flags are on.
572 aevent
= AUE_OPENBYID_R
;
575 case (O_RDONLY
| O_TRUNC
):
576 aevent
= AUE_OPENBYID_RT
;
580 aevent
= AUE_OPENBYID_RW
;
583 case (O_RDWR
| O_TRUNC
):
584 aevent
= AUE_OPENBYID_RWT
;
588 aevent
= AUE_OPENBYID_W
;
591 case (O_WRONLY
| O_TRUNC
):
592 aevent
= AUE_OPENBYID_WT
;
596 aevent
= AUE_OPENBYID
;
601 * Convert chatty errors to better matching events. Failures to
602 * find a file are really just attribute events -- so recast them as
607 case AUE_OPENBYID_RT
:
608 case AUE_OPENBYID_RW
:
609 case AUE_OPENBYID_RWT
:
611 case AUE_OPENBYID_WT
:
613 aevent
= AUE_OPENBYID
;
619 * Convert a MSGCTL command to a specific event.
622 audit_msgctl_to_event(int cmd
)
627 return (AUE_MSGCTL_RMID
);
630 return (AUE_MSGCTL_SET
);
633 return (AUE_MSGCTL_STAT
);
636 /* We will audit a bad command. */
642 * Convert a SEMCTL command to a specific event.
645 audit_semctl_to_event(int cmd
)
650 return (AUE_SEMCTL_GETALL
);
653 return (AUE_SEMCTL_GETNCNT
);
656 return (AUE_SEMCTL_GETPID
);
659 return (AUE_SEMCTL_GETVAL
);
662 return (AUE_SEMCTL_GETZCNT
);
665 return (AUE_SEMCTL_RMID
);
668 return (AUE_SEMCTL_SET
);
671 return (AUE_SEMCTL_SETALL
);
674 return (AUE_SEMCTL_SETVAL
);
677 return (AUE_SEMCTL_STAT
);
680 /* We will audit a bad command. */
686 * Convert a command for the auditon() system call to a audit event.
689 auditon_command_event(int cmd
)
694 return (AUE_AUDITON_GPOLICY
);
697 return (AUE_AUDITON_SPOLICY
);
700 return (AUE_AUDITON_GETKMASK
);
703 return (AUE_AUDITON_SETKMASK
);
706 return (AUE_AUDITON_GQCTRL
);
709 return (AUE_AUDITON_SQCTRL
);
712 return (AUE_AUDITON_GETCWD
);
715 return (AUE_AUDITON_GETCAR
);
718 return (AUE_AUDITON_GETSTAT
);
721 return (AUE_AUDITON_SETSTAT
);
724 return (AUE_AUDITON_SETUMASK
);
727 return (AUE_AUDITON_SETSMASK
);
730 return (AUE_AUDITON_GETCOND
);
733 return (AUE_AUDITON_SETCOND
);
736 return (AUE_AUDITON_GETCLASS
);
739 return (AUE_AUDITON_SETCLASS
);
745 case A_GETPINFO_ADDR
:
748 case A_GETSINFO_ADDR
:
750 return (AUE_AUDITON
); /* No special record */
755 * For darwin we rewrite events generated by fcntl(F_OPENFROM,...) and
756 * fcntl(F_UNLINKFROM,...) system calls to AUE_OPENAT_* and AUE_UNLINKAT audit
760 audit_fcntl_command_event(int cmd
, int oflags
, int error
)
764 return (audit_flags_and_error_to_openatevent(oflags
, error
));
767 return (AUE_UNLINKAT
);
770 return (AUE_FCNTL
); /* Don't change from AUE_FCNTL. */
775 * Create a canonical path from given path by prefixing either the root
776 * directory, or the current working directory.
779 audit_canon_path(struct vnode
*cwd_vp
, char *path
, char *cpath
)
786 * Convert multiple leading '/' into a single '/' if the cwd_vp is
787 * NULL (i.e. an absolute path), and strip them entirely if the
788 * cwd_vp represents a chroot directory (i.e. the caller checked for
789 * an initial '/' character itself, saw one, and passed fdp->fd_rdir).
790 * Somewhat complicated, but it places the onus for locking structs
791 * involved on the caller, and makes proxy operations explicit rather
794 if (*(path
) == '/') {
795 while (*(bufp
) == '/')
796 bufp
++; /* skip leading '/'s */
798 bufp
--; /* restore one '/' */
800 if (cwd_vp
!= NULL
) {
802 ret
= vn_getpath(cwd_vp
, cpath
, &len
);
807 if (len
< MAXPATHLEN
)
809 strlcpy(cpath
+ len
, bufp
, MAXPATHLEN
- len
);
811 strlcpy(cpath
, bufp
, MAXPATHLEN
);
815 #endif /* CONFIG_AUDIT */