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