]> git.saurik.com Git - apple/xnu.git/blame - bsd/kern/kern_bsm_klib.c
xnu-792.6.56.tar.gz
[apple/xnu.git] / bsd / kern / kern_bsm_klib.c
CommitLineData
55e303ae 1/*
e5568f75 2 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
55e303ae
A
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
ff6e181a
A
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. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
55e303ae 12 *
ff6e181a
A
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
55e303ae
A
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
ff6e181a
A
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
55e303ae
A
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
91447636 24#include <sys/systm.h>
55e303ae 25#include <sys/types.h>
91447636
A
26#include <sys/proc_internal.h>
27#include <sys/vnode_internal.h>
55e303ae
A
28#include <sys/fcntl.h>
29#include <sys/filedesc.h>
30#include <sys/sem.h>
e5568f75
A
31
32#include <bsm/audit.h>
33#include <bsm/audit_kernel.h>
34#include <bsm/audit_kevents.h>
35#include <bsm/audit_klib.h>
55e303ae
A
36
37/*
38 * Initialize the system call to audit event mapping table. This table
39 * must be kept in sync with the system call table. This table is meant to
40 * be directly accessed.
41 * XXX This should be improved, though, to make it independent of the syscall
42 * table (but we don't want to traverse a large table for every system call
43 * to find a match). Ultimately, it would be best to place the audit event
44 * number in the system call table.
45 */
46au_event_t sys_au_event[] = {
47 AUE_NULL, /* 0 = indir */
48 AUE_EXIT, /* 1 = exit */
e5568f75 49 AUE_FORK, /* 2 = fork */
55e303ae
A
50 AUE_NULL, /* 3 = read */
51 AUE_NULL, /* 4 = write */
e5568f75
A
52 AUE_OPEN_RWTC, /* 5 = open */
53 AUE_CLOSE, /* 6 = close */
55e303ae 54 AUE_NULL, /* 7 = wait4 */
e5568f75 55 AUE_O_CREAT, /* 8 = old creat */
55e303ae
A
56 AUE_LINK, /* 9 = link */
57 AUE_UNLINK, /* 10 = unlink */
58 AUE_NULL, /* 11 was obsolete execv */
59 AUE_CHDIR, /* 12 = chdir */
60 AUE_FCHDIR, /* 13 = fchdir */
61 AUE_MKNOD, /* 14 = mknod */
62 AUE_CHMOD, /* 15 = chmod */
63 AUE_CHOWN, /* 16 = chown; now 3 args */
64 AUE_NULL, /* 17 = old break */
65#if COMPAT_GETFSSTAT
55e303ae 66 AUE_GETFSSTAT, /* 18 = getfsstat */
e5568f75
A
67#else
68 AUE_NULL, /* 18 = ogetfsstat */
55e303ae
A
69#endif
70 AUE_NULL, /* 19 = old lseek */
71 AUE_NULL, /* 20 = getpid */
72 AUE_NULL, /* 21 was obsolete mount */
73 AUE_NULL, /* 22 was obsolete umount */
74 AUE_SETUID, /* 23 = setuid */
75 AUE_NULL, /* 24 = getuid */
76 AUE_NULL, /* 25 = geteuid */
e5568f75 77 AUE_PTRACE, /* 26 = ptrace */
55e303ae
A
78 AUE_RECVMSG, /* 27 = recvmsg */
79 AUE_SENDMSG, /* 28 = sendmsg */
80 AUE_RECVFROM, /* 29 = recvfrom */
81 AUE_ACCEPT, /* 30 = accept */
82 AUE_NULL, /* 31 = getpeername */
83 AUE_NULL, /* 32 = getsockname */
84 AUE_ACCESS, /* 33 = access */
85 AUE_CHFLAGS, /* 34 = chflags */
86 AUE_FCHFLAGS, /* 35 = fchflags */
87 AUE_NULL, /* 36 = sync */
e5568f75
A
88 AUE_KILL, /* 37 = kill */
89 AUE_O_STAT, /* 38 = old stat */
55e303ae 90 AUE_NULL, /* 39 = getppid */
e5568f75 91 AUE_O_LSTAT, /* 40 = old lstat */
55e303ae
A
92 AUE_NULL, /* 41 = dup */
93 AUE_PIPE, /* 42 = pipe */
94 AUE_NULL, /* 43 = getegid */
95 AUE_NULL, /* 44 = profil */
e5568f75 96 AUE_KTRACE, /* 45 = ktrace */
55e303ae
A
97 AUE_NULL, /* 46 = sigaction */
98 AUE_NULL, /* 47 = getgid */
99 AUE_NULL, /* 48 = sigprocmask */
100 AUE_NULL, /* 49 = getlogin */
e5568f75
A
101 AUE_SETLOGIN, /* 50 = setlogin */
102 AUE_ACCT, /* 51 = turn acct off/on */
55e303ae
A
103 AUE_NULL, /* 52 = sigpending */
104 AUE_NULL, /* 53 = sigaltstack */
e5568f75
A
105 AUE_IOCTL, /* 54 = ioctl */
106 AUE_REBOOT, /* 55 = reboot */
55e303ae
A
107 AUE_REVOKE, /* 56 = revoke */
108 AUE_SYMLINK, /* 57 = symlink */
109 AUE_READLINK, /* 58 = readlink */
110 AUE_EXECVE, /* 59 = execve */
111 AUE_UMASK, /* 60 = umask */
112 AUE_CHROOT, /* 61 = chroot */
e5568f75 113 AUE_O_FSTAT, /* 62 = old fstat */
55e303ae
A
114 AUE_NULL, /* 63 = used internally, reserved */
115 AUE_NULL, /* 64 = old getpagesize */
116 AUE_NULL, /* 65 = msync */
e5568f75 117 AUE_VFORK, /* 66 = vfork */
55e303ae
A
118 AUE_NULL, /* 67 was obsolete vread */
119 AUE_NULL, /* 68 was obsolete vwrite */
120 AUE_NULL, /* 69 = sbrk */
121 AUE_NULL, /* 70 = sstk */
e5568f75 122 AUE_O_MMAP, /* 71 = old mmap */
55e303ae 123 AUE_NULL, /* 72 = old vadvise */
e5568f75
A
124 AUE_MUNMAP, /* 73 = munmap */
125 AUE_MPROTECT, /* 74 = mprotect */
55e303ae
A
126 AUE_NULL, /* 75 = madvise */
127 AUE_NULL, /* 76 was obsolete vhangup */
128 AUE_NULL, /* 77 was obsolete vlimit */
129 AUE_NULL, /* 78 = mincore */
130 AUE_NULL, /* 79 = getgroups */
131 AUE_SETGROUPS, /* 80 = setgroups */
132 AUE_NULL, /* 81 = getpgrp */
133 AUE_SETPGRP, /* 82 = setpgid */
134 AUE_NULL, /* 83 = setitimer */
135 AUE_NULL, /* 84 = old wait */
136 AUE_NULL, /* 85 = swapon */
137 AUE_NULL, /* 86 = getitimer */
138 AUE_NULL, /* 87 = old gethostname */
e5568f75 139 AUE_O_SETHOSTNAME, /* 88 = old sethostname */
55e303ae
A
140 AUE_NULL, /* 89 getdtablesize */
141 AUE_NULL, /* 90 = dup2 */
142 AUE_NULL, /* 91 was obsolete getdopt */
143 AUE_FCNTL, /* 92 = fcntl */
144 AUE_NULL, /* 93 = select */
145 AUE_NULL, /* 94 was obsolete setdopt */
146 AUE_NULL, /* 95 = fsync */
e5568f75 147 AUE_SETPRIORITY, /* 96 = setpriority */
55e303ae
A
148 AUE_SOCKET, /* 97 = socket */
149 AUE_CONNECT, /* 98 = connect */
150 AUE_NULL, /* 99 = accept */
151 AUE_NULL, /* 100 = getpriority */
e5568f75
A
152 AUE_O_SEND, /* 101 = old send */
153 AUE_O_RECV, /* 102 = old recv */
55e303ae
A
154 AUE_NULL, /* 103 = sigreturn */
155 AUE_BIND, /* 104 = bind */
156 AUE_SETSOCKOPT, /* 105 = setsockopt */
157 AUE_NULL, /* 106 = listen */
158 AUE_NULL, /* 107 was vtimes */
159 AUE_NULL, /* 108 = sigvec */
160 AUE_NULL, /* 109 = sigblock */
161 AUE_NULL, /* 110 = sigsetmask */
162 AUE_NULL, /* 111 = sigpause */
163 AUE_NULL, /* 112 = sigstack */
e5568f75
A
164 AUE_O_RECVMSG, /* 113 = recvmsg */
165 AUE_O_SENDMSG, /* 114 = sendmsg */
55e303ae
A
166 AUE_NULL, /* 115 = old vtrace */
167 AUE_NULL, /* 116 = gettimeofday */
168 AUE_NULL, /* 117 = getrusage */
169 AUE_NULL, /* 118 = getsockopt */
170 AUE_NULL, /* 119 = old resuba */
171 AUE_NULL, /* 120 = readv */
172 AUE_NULL, /* 121 = writev */
e5568f75 173 AUE_SETTIMEOFDAY, /* 122 = settimeofday */
55e303ae
A
174 AUE_FCHOWN, /* 123 = fchown */
175 AUE_FCHMOD, /* 124 = fchmod */
e5568f75 176 AUE_O_RECVFROM, /* 125 = recvfrom */
55e303ae
A
177 AUE_NULL, /* 126 = setreuid */
178 AUE_NULL, /* 127 = setregid */
179 AUE_RENAME, /* 128 = rename */
e5568f75
A
180 AUE_O_TRUNCATE, /* 129 = old truncate */
181 AUE_O_FTRUNCATE, /* 130 = old ftruncate */
55e303ae
A
182 AUE_FLOCK, /* 131 = flock */
183 AUE_MKFIFO, /* 132 = mkfifo */
184 AUE_SENDTO, /* 133 = sendto */
185 AUE_SHUTDOWN, /* 134 = shutdown */
186 AUE_SOCKETPAIR, /* 135 = socketpair */
187 AUE_MKDIR, /* 136 = mkdir */
188 AUE_RMDIR, /* 137 = rmdir */
189 AUE_UTIMES, /* 138 = utimes */
190 AUE_FUTIMES, /* 139 = futimes */
191 AUE_ADJTIME, /* 140 = adjtime */
192 AUE_NULL, /* 141 = getpeername */
193 AUE_NULL, /* 142 = old gethostid */
194 AUE_NULL, /* 143 = old sethostid */
195 AUE_NULL, /* 144 = old getrlimit */
e5568f75
A
196 AUE_O_SETRLIMIT, /* 145 = old setrlimit */
197 AUE_O_KILLPG, /* 146 = old killpg */
198 AUE_SETSID, /* 147 = setsid */
55e303ae
A
199 AUE_NULL, /* 148 was setquota */
200 AUE_NULL, /* 149 was qquota */
201 AUE_NULL, /* 150 = getsockname */
202 AUE_NULL, /* 151 = getpgid */
e5568f75 203 AUE_SETPRIVEXEC, /* 152 = setprivexec */
55e303ae
A
204 AUE_NULL, /* 153 = pread */
205 AUE_NULL, /* 154 = pwrite */
ccc36f2f 206 AUE_NFSSVC, /* 155 = nfs_svc */
e5568f75 207 AUE_O_GETDIRENTRIES, /* 156 = old getdirentries */
55e303ae
A
208 AUE_STATFS, /* 157 = statfs */
209 AUE_FSTATFS, /* 158 = fstatfs */
ccc36f2f 210 AUE_UNMOUNT, /* 159 = unmount */
55e303ae
A
211 AUE_NULL, /* 160 was async_daemon */
212 AUE_GETFH, /* 161 = get file handle */
213 AUE_NULL, /* 162 = getdomainname */
e5568f75 214 AUE_O_SETDOMAINNAME, /* 163 = setdomainname */
55e303ae
A
215 AUE_NULL, /* 164 */
216#if QUOTA
217 AUE_QUOTACTL, /* 165 = quotactl */
218#else /* QUOTA */
219 AUE_NULL, /* 165 = not configured */
220#endif /* QUOTA */
221 AUE_NULL, /* 166 was exportfs */
222 AUE_MOUNT, /* 167 = mount */
223 AUE_NULL, /* 168 was ustat */
224 AUE_NULL, /* 169 = nosys */
225 AUE_NULL, /* 170 was table */
226 AUE_NULL, /* 171 = old wait3 */
227 AUE_NULL, /* 172 was rpause */
228 AUE_NULL, /* 173 = nosys */
229 AUE_NULL, /* 174 was getdents */
230 AUE_NULL, /* 175 was gc_control */
231 AUE_NULL, /* 176 = add_profil */
232 AUE_NULL, /* 177 */
233 AUE_NULL, /* 178 */
234 AUE_NULL, /* 179 */
235 AUE_NULL, /* 180 */
236 AUE_SETGID, /* 181 */
237 AUE_SETEGID, /* 182 */
238 AUE_SETEUID, /* 183 */
239 AUE_NULL, /* 184 = nosys */
240 AUE_NULL, /* 185 = nosys */
241 AUE_NULL, /* 186 = nosys */
242 AUE_NULL, /* 187 = nosys */
243 AUE_STAT, /* 188 = stat */
244 AUE_FSTAT, /* 189 = fstat */
245 AUE_LSTAT, /* 190 = lstat */
246 AUE_PATHCONF, /* 191 = pathconf */
247 AUE_FPATHCONF, /* 192 = fpathconf */
55e303ae
A
248#if COMPAT_GETFSSTAT
249 AUE_GETFSSTAT, /* 193 = getfsstat */
250#else
251 AUE_NULL, /* 193 is unused */
252#endif
253 AUE_NULL, /* 194 = getrlimit */
254 AUE_SETRLIMIT, /* 195 = setrlimit */
255 AUE_GETDIRENTRIES, /* 196 = getdirentries */
e5568f75 256 AUE_MMAP, /* 197 = mmap */
55e303ae
A
257 AUE_NULL, /* 198 = __syscall */
258 AUE_NULL, /* 199 = lseek */
259 AUE_TRUNCATE, /* 200 = truncate */
260 AUE_FTRUNCATE, /* 201 = ftruncate */
e5568f75
A
261 AUE_SYSCTL, /* 202 = __sysctl */
262 AUE_MLOCK, /* 203 = mlock */
263 AUE_MUNLOCK, /* 204 = munlock */
55e303ae
A
264 AUE_UNDELETE, /* 205 = undelete */
265 AUE_NULL, /* 206 = ATsocket */
266 AUE_NULL, /* 207 = ATgetmsg*/
267 AUE_NULL, /* 208 = ATputmsg*/
268 AUE_NULL, /* 209 = ATPsndreq*/
269 AUE_NULL, /* 210 = ATPsndrsp*/
270 AUE_NULL, /* 211 = ATPgetreq*/
271 AUE_NULL, /* 212 = ATPgetrsp*/
272 AUE_NULL, /* 213 = Reserved for AppleTalk */
273 AUE_NULL, /* 214 = Reserved for AppleTalk */
274 AUE_NULL, /* 215 = Reserved for AppleTalk */
275
276 AUE_NULL, /* 216 = HFS make complex file call (multipel forks */
277 AUE_NULL, /* 217 = HFS statv extended stat call for HFS */
278 AUE_NULL, /* 218 = HFS lstatv extended lstat call for HFS */
279 AUE_NULL, /* 219 = HFS fstatv extended fstat call for HFS */
280 AUE_GETATTRLIST,/* 220 = HFS getarrtlist get attribute list cal */
281 AUE_SETATTRLIST,/* 221 = HFS setattrlist set attribute list */
282 AUE_GETDIRENTRIESATTR,/* 222 = HFS getdirentriesattr get directory attributes */
283 AUE_EXCHANGEDATA,/* 223 = HFS exchangedata exchange file contents */
ccc36f2f 284 AUE_CHECKUSERACCESS,/* 224 = HFS checkuseraccess check access to file */
55e303ae 285 AUE_SEARCHFS, /* 225 = HFS searchfs to implement catalog searching */
ccc36f2f 286 AUE_DELETE, /* 226 = private delete (Carbon semantics) */
55e303ae
A
287 AUE_NULL, /* 227 = copyfile - orignally for AFP */
288 AUE_NULL, /* 228 */
289 AUE_NULL, /* 229 */
290 AUE_NULL, /* 230 */
291 AUE_NULL, /* 231 */
292 AUE_NULL, /* 232 */
293 AUE_NULL, /* 233 */
294 AUE_NULL, /* 234 */
295 AUE_NULL, /* 235 */
296 AUE_NULL, /* 236 */
297 AUE_NULL, /* 237 */
298 AUE_NULL, /* 238 */
299 AUE_NULL, /* 239 */
300 AUE_NULL, /* 240 */
301 AUE_NULL, /* 241 */
302 AUE_NULL, /* 242 = fsctl */
303 AUE_NULL, /* 243 */
304 AUE_NULL, /* 244 */
305 AUE_NULL, /* 245 */
306 AUE_NULL, /* 246 */
307 AUE_NULL, /* 247 = nfsclnt*/
308 AUE_NULL, /* 248 = fhopen */
309 AUE_NULL, /* 249 */
e5568f75 310 AUE_MINHERIT, /* 250 = minherit */
55e303ae
A
311 AUE_NULL, /* 251 = semsys */
312 AUE_NULL, /* 252 = msgsys */
313 AUE_NULL, /* 253 = shmsys */
314 AUE_SEMCTL, /* 254 = semctl */
315 AUE_SEMGET, /* 255 = semget */
316 AUE_SEMOP, /* 256 = semop */
317 AUE_NULL, /* 257 = semconfig */
318 AUE_MSGCTL, /* 258 = msgctl */
319 AUE_MSGGET, /* 259 = msgget */
320 AUE_MSGSND, /* 260 = msgsnd */
321 AUE_MSGRCV, /* 261 = msgrcv */
322 AUE_SHMAT, /* 262 = shmat */
323 AUE_SHMCTL, /* 263 = shmctl */
324 AUE_SHMDT, /* 264 = shmdt */
325 AUE_SHMGET, /* 265 = shmget */
e5568f75
A
326 AUE_SHMOPEN, /* 266 = shm_open */
327 AUE_SHMUNLINK, /* 267 = shm_unlink */
328 AUE_SEMOPEN, /* 268 = sem_open */
329 AUE_SEMCLOSE, /* 269 = sem_close */
330 AUE_SEMUNLINK, /* 270 = sem_unlink */
55e303ae
A
331 AUE_NULL, /* 271 = sem_wait */
332 AUE_NULL, /* 272 = sem_trywait */
333 AUE_NULL, /* 273 = sem_post */
334 AUE_NULL, /* 274 = sem_getvalue */
335 AUE_NULL, /* 275 = sem_init */
336 AUE_NULL, /* 276 = sem_destroy */
337 AUE_NULL, /* 277 */
338 AUE_NULL, /* 278 */
339 AUE_NULL, /* 279 */
340 AUE_NULL, /* 280 */
341 AUE_NULL, /* 281 */
342 AUE_NULL, /* 282 */
343 AUE_NULL, /* 283 */
344 AUE_NULL, /* 284 */
345 AUE_NULL, /* 285 */
346 AUE_NULL, /* 286 */
347 AUE_NULL, /* 287 */
348 AUE_NULL, /* 288 */
349 AUE_NULL, /* 289 */
350 AUE_NULL, /* 290 */
351 AUE_NULL, /* 291 */
352 AUE_NULL, /* 292 */
353 AUE_NULL, /* 293 */
354 AUE_NULL, /* 294 */
355 AUE_NULL, /* 295 */
e5568f75
A
356 AUE_LOADSHFILE, /* 296 = load_shared_file */
357 AUE_RESETSHFILE, /* 297 = reset_shared_file */
91447636 358 AUE_NEWSYSTEMSHREG, /* 298 = new_system_shared_regions */
55e303ae
A
359 AUE_NULL, /* 299 */
360 AUE_NULL, /* 300 */
361 AUE_NULL, /* 301 */
362 AUE_NULL, /* 302 */
363 AUE_NULL, /* 303 */
364 AUE_NULL, /* 304 */
365 AUE_NULL, /* 305 */
366 AUE_NULL, /* 306 */
367 AUE_NULL, /* 307 */
368 AUE_NULL, /* 308 */
369 AUE_NULL, /* 309 */
370 AUE_NULL, /* 310 = getsid */
371 AUE_NULL, /* 311 */
372 AUE_NULL, /* 312 */
373 AUE_NULL, /* 313 */
374 AUE_NULL, /* 314 */
375 AUE_NULL, /* 315 */
376 AUE_NULL, /* 316 */
377 AUE_NULL, /* 317 */
378 AUE_NULL, /* 318 */
379 AUE_NULL, /* 319 */
380 AUE_NULL, /* 320 */
381 AUE_NULL, /* 321 */
382 AUE_NULL, /* 322 */
383 AUE_NULL, /* 323 */
384 AUE_NULL, /* 324 = mlockall*/
385 AUE_NULL, /* 325 = munlockall*/
386 AUE_NULL, /* 326 */
387 AUE_NULL, /* 327 = issetugid */
388 AUE_NULL, /* 328 */
389 AUE_NULL, /* 329 */
390 AUE_NULL, /* 330 */
391 AUE_NULL, /* 331 */
392 AUE_NULL, /* 332 */
393 AUE_NULL, /* 333 */
394 AUE_NULL, /* 334 */
395 AUE_NULL, /* 335 = utrace */
396 AUE_NULL, /* 336 */
397 AUE_NULL, /* 337 */
398 AUE_NULL, /* 338 */
399 AUE_NULL, /* 339 */
400 AUE_NULL, /* 340 */
401 AUE_NULL, /* 341 */
402 AUE_NULL, /* 342 */
403 AUE_NULL, /* 343 */
404 AUE_NULL, /* 344 */
405 AUE_NULL, /* 345 */
406 AUE_NULL, /* 346 */
407 AUE_NULL, /* 347 */
408 AUE_NULL, /* 348 */
409 AUE_NULL, /* 349 */
410 AUE_AUDIT, /* 350 */
e5568f75 411 AUE_AUDITON, /* 351 */
55e303ae
A
412 AUE_NULL, /* 352 */
413 AUE_GETAUID, /* 353 */
414 AUE_SETAUID, /* 354 */
e5568f75
A
415 AUE_GETAUDIT, /* 355 */
416 AUE_SETAUDIT, /* 356 */
417 AUE_GETAUDIT_ADDR, /* 357 */
418 AUE_SETAUDIT_ADDR, /* 358 */
419 AUE_AUDITCTL, /* 359 */
55e303ae
A
420 AUE_NULL, /* 360 */
421 AUE_NULL, /* 361 */
422 AUE_NULL, /* 362 = kqueue */
423 AUE_NULL, /* 363 = kevent */
91447636 424 AUE_LCHOWN, /* 364 = lchown */
55e303ae
A
425 AUE_NULL, /* 365 */
426 AUE_NULL, /* 366 */
427 AUE_NULL, /* 367 */
428 AUE_NULL, /* 368 */
429 AUE_NULL /* 369 */
430};
431int nsys_au_event = sizeof(sys_au_event) / sizeof(sys_au_event[0]);
432
e5568f75
A
433/*
434 * Hash table functions for the audit event number to event class mask mapping.
435 */
436
437#define EVCLASSMAP_HASH_TABLE_SIZE 251
438struct evclass_elem {
439 au_event_t event;
440 au_class_t class;
441 LIST_ENTRY(evclass_elem) entry;
442};
443struct evclass_list {
444 LIST_HEAD(, evclass_elem) head;
445};
446
447struct evclass_list evclass_hash[EVCLASSMAP_HASH_TABLE_SIZE];
448
449au_class_t au_event_class(au_event_t event)
450{
451
452 struct evclass_list *evcl;
453 struct evclass_elem *evc;
454
455 evcl = &evclass_hash[event % EVCLASSMAP_HASH_TABLE_SIZE];
456
457 /* If an entry at our hash location matches the event, just return */
458 LIST_FOREACH(evc, &evcl->head, entry) {
459 if (evc->event == event)
460 return (evc->class);
461 }
462 return (AU_NULL);
463}
464
91447636 465 /*
e5568f75
A
466 * Insert a event to class mapping. If the event already exists in the
467 * mapping, then replace the mapping with the new one.
468 * XXX There is currently no constraints placed on the number of mappings.
469 * May want to either limit to a number, or in terms of memory usage.
91447636 470 */
e5568f75
A
471void au_evclassmap_insert(au_event_t event, au_class_t class)
472{
473 struct evclass_list *evcl;
474 struct evclass_elem *evc;
475
476 evcl = &evclass_hash[event % EVCLASSMAP_HASH_TABLE_SIZE];
477
478 LIST_FOREACH(evc, &evcl->head, entry) {
479 if (evc->event == event) {
480 evc->class = class;
481 return;
482 }
483 }
91447636 484 kmem_alloc(kernel_map, (vm_offset_t *)&evc, sizeof(*evc));
e5568f75
A
485 if (evc == NULL) {
486 return;
487 }
488 evc->event = event;
489 evc->class = class;
490 LIST_INSERT_HEAD(&evcl->head, evc, entry);
e5568f75
A
491}
492
493void au_evclassmap_init()
494{
495 int i;
496 for (i = 0; i < EVCLASSMAP_HASH_TABLE_SIZE; i++) {
497 LIST_INIT(&evclass_hash[i].head);
498 }
499
500 /* Set up the initial event to class mapping for system calls. */
501 for (i = 0; i < nsys_au_event; i++) {
502 if (sys_au_event[i] != AUE_NULL) {
503 au_evclassmap_insert(sys_au_event[i], AU_NULL);
91447636 504 }
e5568f75
A
505 }
506 /* Add the Mach system call events */
507 au_evclassmap_insert(AUE_TASKFORPID, AU_NULL);
508 au_evclassmap_insert(AUE_PIDFORTASK, AU_NULL);
509 au_evclassmap_insert(AUE_SWAPON, AU_NULL);
510 au_evclassmap_insert(AUE_SWAPOFF, AU_NULL);
511 au_evclassmap_insert(AUE_MAPFD, AU_NULL);
512 au_evclassmap_insert(AUE_INITPROCESS, AU_NULL);
91447636 513
e5568f75
A
514 /* Add the specific open events to the mapping. */
515 au_evclassmap_insert(AUE_OPEN_R, AU_FREAD);
91447636
A
516 au_evclassmap_insert(AUE_OPEN_RC, AU_FREAD|AU_FCREATE);
517 au_evclassmap_insert(AUE_OPEN_RTC, AU_FREAD|AU_FCREATE|AU_FDELETE);
518 au_evclassmap_insert(AUE_OPEN_RT, AU_FREAD|AU_FDELETE);
519 au_evclassmap_insert(AUE_OPEN_RW, AU_FREAD|AU_FWRITE);
520 au_evclassmap_insert(AUE_OPEN_RWC, AU_FREAD|AU_FWRITE|AU_FCREATE);
521 au_evclassmap_insert(AUE_OPEN_RWTC, AU_FREAD|AU_FWRITE|AU_FCREATE|AU_FDELETE);
522 au_evclassmap_insert(AUE_OPEN_RWT, AU_FREAD|AU_FWRITE|AU_FDELETE);
523 au_evclassmap_insert(AUE_OPEN_W, AU_FWRITE);
524 au_evclassmap_insert(AUE_OPEN_WC, AU_FWRITE|AU_FCREATE);
525 au_evclassmap_insert(AUE_OPEN_WTC, AU_FWRITE|AU_FCREATE|AU_FDELETE);
526 au_evclassmap_insert(AUE_OPEN_WT, AU_FWRITE|AU_FDELETE);
e5568f75
A
527}
528
91447636 529 /*
55e303ae 530 * Check whether an event is aditable by comparing the mask of classes this
e5568f75 531 * event is part of against the given mask.
91447636 532 */
55e303ae
A
533int au_preselect(au_event_t event, au_mask_t *mask_p, int sorf)
534{
55e303ae 535 au_class_t effmask = 0;
e5568f75 536 au_class_t ae_class;
55e303ae
A
537
538 if(mask_p == NULL)
539 return (-1);
540
e5568f75 541 ae_class = au_event_class(event);
91447636 542 /*
55e303ae
A
543 * Perform the actual check of the masks against the event.
544 */
91447636 545 if(sorf & AU_PRS_SUCCESS) {
55e303ae
A
546 effmask |= (mask_p->am_success & ae_class);
547 }
548
549 if(sorf & AU_PRS_FAILURE) {
550 effmask |= (mask_p->am_failure & ae_class);
551 }
552
553 if(effmask)
554 return (1);
555 else
556 return (0);
557}
558
e5568f75
A
559/*
560 * Convert sysctl names and present arguments to events
561 */
562au_event_t ctlname_to_sysctlevent(int name[], uint64_t valid_arg) {
563
564 /* can't parse it - so return the worst case */
565 if ((valid_arg & (ARG_CTLNAME | ARG_LEN)) !=
566 (ARG_CTLNAME | ARG_LEN))
567 return AUE_SYSCTL;
568
569 switch (name[0]) {
570 /* non-admin "lookups" treat them special */
571 case KERN_OSTYPE:
572 case KERN_OSRELEASE:
573 case KERN_OSREV:
574 case KERN_VERSION:
575 case KERN_ARGMAX:
576 case KERN_CLOCKRATE:
577 case KERN_BOOTTIME:
578 case KERN_POSIX1:
579 case KERN_NGROUPS:
580 case KERN_JOB_CONTROL:
581 case KERN_SAVED_IDS:
582 case KERN_NETBOOT:
583 case KERN_SYMFILE:
91447636 584 case KERN_SHREG_PRIVATIZABLE:
e5568f75
A
585 return AUE_SYSCTL_NONADMIN;
586
587 /* only treat the sets as admin */
588 case KERN_MAXVNODES:
589 case KERN_MAXPROC:
590 case KERN_MAXFILES:
591 case KERN_MAXPROCPERUID:
592 case KERN_MAXFILESPERPROC:
593 case KERN_HOSTID:
594 case KERN_AIOMAX:
595 case KERN_AIOPROCMAX:
596 case KERN_AIOTHREADS:
597 case KERN_COREDUMP:
598 case KERN_SUGID_COREDUMP:
599 return (valid_arg & ARG_VALUE) ?
600 AUE_SYSCTL : AUE_SYSCTL_NONADMIN;
601
602 default:
603 return AUE_SYSCTL;
604 }
605 /* NOTREACHED */
606}
607
55e303ae
A
608/*
609 * Convert an open flags specifier into a specific type of open event for
610 * auditing purposes.
611 */
e5568f75
A
612au_event_t flags_and_error_to_openevent(int oflags, int error) {
613 au_event_t aevent;
55e303ae
A
614
615 /* Need to check only those flags we care about. */
616 oflags = oflags & (O_RDONLY | O_CREAT | O_TRUNC | O_RDWR | O_WRONLY);
617
618 /* These checks determine what flags are on with the condition
619 * that ONLY that combination is on, and no other flags are on.
620 */
e5568f75
A
621 switch (oflags) {
622 case O_RDONLY:
623 aevent = AUE_OPEN_R;
624 break;
625 case (O_RDONLY | O_CREAT):
626 aevent = AUE_OPEN_RC;
627 break;
628 case (O_RDONLY | O_CREAT | O_TRUNC):
629 aevent = AUE_OPEN_RTC;
630 break;
631 case (O_RDONLY | O_TRUNC):
632 aevent = AUE_OPEN_RT;
633 break;
634 case O_RDWR:
635 aevent = AUE_OPEN_RW;
636 break;
637 case (O_RDWR | O_CREAT):
638 aevent = AUE_OPEN_RWC;
639 break;
640 case (O_RDWR | O_CREAT | O_TRUNC):
641 aevent = AUE_OPEN_RWTC;
642 break;
643 case (O_RDWR | O_TRUNC):
644 aevent = AUE_OPEN_RWT;
645 break;
646 case O_WRONLY:
647 aevent = AUE_OPEN_W;
648 break;
649 case (O_WRONLY | O_CREAT):
650 aevent = AUE_OPEN_WC;
651 break;
652 case (O_WRONLY | O_CREAT | O_TRUNC):
653 aevent = AUE_OPEN_WTC;
654 break;
655 case (O_WRONLY | O_TRUNC):
656 aevent = AUE_OPEN_WT;
657 break;
658 default:
659 aevent = AUE_OPEN;
660 break;
91447636 661}
55e303ae 662
91447636 663/*
e5568f75
A
664 * Convert chatty errors to better matching events.
665 * Failures to find a file are really just attribute
666 * events - so recast them as such.
91447636 667*/
e5568f75
A
668 switch (aevent) {
669 case AUE_OPEN_R:
670 case AUE_OPEN_RT:
671 case AUE_OPEN_RW:
672 case AUE_OPEN_RWT:
673 case AUE_OPEN_W:
674 case AUE_OPEN_WT:
675 if (error == ENOENT)
676 aevent = AUE_OPEN;
91447636 677}
e5568f75 678 return aevent;
55e303ae
A
679}
680
681/* Convert a MSGCTL command to a specific event. */
91447636 682au_event_t msgctl_to_event(int cmd)
55e303ae
A
683{
684 switch (cmd) {
685 case IPC_RMID:
686 return AUE_MSGCTL_RMID;
687 case IPC_SET:
688 return AUE_MSGCTL_SET;
689 case IPC_STAT:
690 return AUE_MSGCTL_STAT;
691 default:
692 return AUE_MSGCTL;
693 /* We will audit a bad command */
694 }
695}
696
697/* Convert a SEMCTL command to a specific event. */
91447636 698au_event_t semctl_to_event(int cmd)
55e303ae
A
699{
700 switch (cmd) {
701 case GETALL:
702 return AUE_SEMCTL_GETALL;
703 case GETNCNT:
704 return AUE_SEMCTL_GETNCNT;
705 case GETPID:
706 return AUE_SEMCTL_GETPID;
707 case GETVAL:
708 return AUE_SEMCTL_GETVAL;
709 case GETZCNT:
710 return AUE_SEMCTL_GETZCNT;
711 case IPC_RMID:
712 return AUE_SEMCTL_RMID;
713 case IPC_SET:
714 return AUE_SEMCTL_SET;
715 case SETALL:
716 return AUE_SEMCTL_SETALL;
717 case SETVAL:
718 return AUE_SEMCTL_SETVAL;
719 case IPC_STAT:
720 return AUE_SEMCTL_STAT;
721 default:
722 return AUE_SEMCTL;
723 /* We will audit a bad command */
724 }
725}
726
e5568f75
A
727/* Convert a command for the auditon() system call to a audit event. */
728int auditon_command_event(int cmd)
729{
730 switch(cmd) {
731 case A_GETPOLICY:
732 return AUE_AUDITON_GPOLICY;
733 break;
734 case A_SETPOLICY:
735 return AUE_AUDITON_SPOLICY;
736 break;
737 case A_GETKMASK:
738 return AUE_AUDITON_GETKMASK;
739 break;
740 case A_SETKMASK:
741 return AUE_AUDITON_SETKMASK;
742 break;
743 case A_GETQCTRL:
744 return AUE_AUDITON_GQCTRL;
745 break;
746 case A_SETQCTRL:
747 return AUE_AUDITON_SQCTRL;
748 break;
749 case A_GETCWD:
750 return AUE_AUDITON_GETCWD;
751 break;
752 case A_GETCAR:
753 return AUE_AUDITON_GETCAR;
754 break;
755 case A_GETSTAT:
756 return AUE_AUDITON_GETSTAT;
757 break;
758 case A_SETSTAT:
759 return AUE_AUDITON_SETSTAT;
760 break;
761 case A_SETUMASK:
762 return AUE_AUDITON_SETUMASK;
763 break;
764 case A_SETSMASK:
765 return AUE_AUDITON_SETSMASK;
766 break;
767 case A_GETCOND:
768 return AUE_AUDITON_GETCOND;
769 break;
770 case A_SETCOND:
771 return AUE_AUDITON_SETCOND;
772 break;
773 case A_GETCLASS:
774 return AUE_AUDITON_GETCLASS;
775 break;
776 case A_SETCLASS:
777 return AUE_AUDITON_SETCLASS;
778 break;
779 case A_GETPINFO:
780 case A_SETPMASK:
781 case A_SETFSIZE:
782 case A_GETFSIZE:
783 case A_GETPINFO_ADDR:
784 case A_GETKAUDIT:
785 case A_SETKAUDIT:
786 default:
787 return AUE_AUDITON; /* No special record */
788 break;
789 }
790}
791
55e303ae
A
792/*
793 * Create a canonical path from given path by prefixing either the
794 * root directory, or the current working directory.
795 * If the process working directory is NULL, we could use 'rootvnode'
796 * to obtain the root directoty, but this results in a volfs name
797 * written to the audit log. So we will leave the filename starting
798 * with '/' in the audit log in this case.
799 */
e5568f75 800int canon_path(struct proc *p, char *path, char *cpath)
55e303ae
A
801{
802 char *bufp;
803 int len;
804 struct vnode *vnp;
805 struct filedesc *fdp;
e5568f75 806 int ret;
55e303ae
A
807
808 fdp = p->p_fd;
809 bufp = path;
810 if (*(path) == '/') {
811 while (*(bufp) == '/')
812 bufp++; /* skip leading '/'s */
813 /* If no process root, or it is the same as the system root,
814 * audit the path as passed in with a single '/'.
815 */
816 if ((fdp->fd_rdir == NULL) ||
817 (fdp->fd_rdir == rootvnode)) {
818 vnp = NULL;
819 bufp--; /* restore one '/' */
820 } else {
821 vnp = fdp->fd_rdir; /* use process root */
822 }
823 } else {
824 vnp = fdp->fd_cdir; /* prepend the current dir */
825 bufp = path;
826 }
827 if (vnp != NULL) {
828 len = MAXPATHLEN;
e5568f75
A
829 ret = vn_getpath(vnp, cpath, &len);
830 if (ret != 0) {
831 cpath[0] = '\0';
832 return (ret);
833 }
55e303ae 834 if (len < MAXPATHLEN)
91447636
A
835 cpath[len-1] = '/';
836 strncpy(cpath + len, bufp, MAXPATHLEN - len);
55e303ae
A
837 } else {
838 strncpy(cpath, bufp, MAXPATHLEN);
839 }
e5568f75 840 return (0);
55e303ae 841}