xref: /titanic_52/usr/src/uts/common/c2/audit_syscalls.c (revision 1d53067866b073ea6710000ba4dd448441361988)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * This file contains the auditing system call code.
28  *
29  */
30 
31 #pragma ident	"%Z%%M%	%I%	%E% SMI"
32 
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/user.h>
36 #include <sys/vnode.h>
37 #include <sys/vfs.h>
38 #include <sys/session.h>	/* for session structure (auditctl(2) */
39 #include <sys/kmem.h>		/* for KM_SLEEP */
40 #include <sys/cred_impl.h>
41 #include <sys/types.h>
42 #include <sys/proc.h>
43 #include <sys/uio.h>
44 #include <sys/file.h>
45 #include <sys/stat.h>
46 #include <sys/pathname.h>
47 #include <sys/acct.h>
48 #include <sys/stropts.h>
49 #include <sys/exec.h>
50 #include <sys/thread.h>
51 #include <sys/cmn_err.h>
52 #include <sys/debug.h>
53 #include <sys/disp.h>
54 #include <sys/kobj.h>
55 #include <sys/sysmacros.h>
56 #include <sys/policy.h>
57 #include <sys/taskq.h>
58 #include <sys/zone.h>
59 
60 #include <c2/audit.h>
61 #include <c2/audit_kernel.h>
62 #include <c2/audit_record.h>
63 
64 #define	CLEAR_VAL	-1
65 
66 #define	HEADER_SIZE64	1;
67 #define	HEADER_SIZE32	0;
68 #define	AU_MIN_FILE_SZ	0x80000	/* minumum audit file size */
69 #define	AUDIT_REC_SIZE	0x8000	/* maximum user audit record size */
70 
71 extern kmutex_t pidlock;
72 
73 extern pri_t		minclsyspri;		/* priority for taskq */
74 
75 extern int audit_load;		/* defined in audit_start.c */
76 
77 int		au_auditstate = AUC_UNSET;	/* global audit state */
78 int		audit_policy;	/* global audit policies in force */
79 static clock_t	au_resid = 15;	/* wait .15 sec before droping a rec */
80 
81 static int	getauid(caddr_t);
82 static int	setauid(caddr_t);
83 static int	getaudit(caddr_t);
84 static int	getaudit_addr(caddr_t, int);
85 static int	setaudit(caddr_t);
86 static int	setaudit_addr(caddr_t, int);
87 static int	auditdoor(int);
88 static int	auditsvc(int, int);
89 static int	auditctl(int, caddr_t, int);
90 static int	audit_modsysent(char *, int, int (*)());
91 static void	au_output_thread();
92 /*
93  * This is the loadable module wrapper.
94  */
95 #include <sys/modctl.h>
96 #include "sys/syscall.h"
97 
98 static struct sysent auditsysent = {
99 	6,
100 	0,
101 	_auditsys
102 };
103 
104 /*
105  * Module linkage information for the kernel.
106  */
107 extern struct mod_ops mod_syscallops;
108 
109 static struct modlsys modlsys = {
110 	&mod_syscallops, "C2 system call", &auditsysent
111 };
112 
113 static struct modlinkage modlinkage = {
114 	MODREV_1, (void *)&modlsys, 0
115 };
116 
117 int
118 _init()
119 {
120 	int retval;
121 
122 	if (audit_load == 0)
123 		return (-1);
124 
125 	/*
126 	 * We are going to do an ugly thing here.
127 	 *  Because auditsys is already defined as a regular
128 	 *  syscall we have to change the definition for syscall
129 	 *  auditsys. Basically or in the SE_LOADABLE flag for
130 	 *  auditsys. We no have a static loadable syscall. Also
131 	 *  create an rw_lock.
132 	 */
133 
134 	if ((audit_modsysent("c2audit",
135 		SE_LOADABLE|SE_NOUNLOAD,
136 		_auditsys)) == -1)
137 		return (-1);
138 
139 	if ((retval = mod_install(&modlinkage)) != 0)
140 		return (retval);
141 
142 	return (0);
143 }
144 
145 int
146 _fini()
147 {
148 	return (EBUSY);
149 }
150 
151 int
152 _info(struct modinfo *modinfop)
153 {
154 	return (mod_info(&modlinkage, modinfop));
155 }
156 
157 /*
158  * when auditing is updated to allow enable/disable without
159  * reboot (and when the audit stubs are removed) *most* of these
160  * calls should return an error when auditing is off -- some
161  * for local zones only.
162  */
163 
164 int
165 _auditsys(struct auditcalls *uap, rval_t *rvp)
166 {
167 	int result = 0;
168 
169 	switch (uap->code) {
170 	case BSM_GETAUID:
171 		result = getauid((caddr_t)uap->a1);
172 		break;
173 	case BSM_SETAUID:
174 		result = setauid((caddr_t)uap->a1);
175 		break;
176 	case BSM_GETAUDIT:
177 		result = getaudit((caddr_t)uap->a1);
178 		break;
179 	case BSM_GETAUDIT_ADDR:
180 
181 		result = getaudit_addr((caddr_t)uap->a1, (int)uap->a2);
182 		break;
183 	case BSM_SETAUDIT:
184 		result = setaudit((caddr_t)uap->a1);
185 		break;
186 	case BSM_SETAUDIT_ADDR:
187 		result = setaudit_addr((caddr_t)uap->a1, (int)uap->a2);
188 		break;
189 	case BSM_AUDIT:
190 		result = audit((caddr_t)uap->a1, (int)uap->a2);
191 		break;
192 	case BSM_AUDITSVC:
193 		result = auditsvc((int)uap->a1, (int)uap->a2);
194 		break;
195 	case BSM_AUDITDOOR:
196 		result = auditdoor((int)uap->a1);
197 		break;
198 	case BSM_AUDITON:
199 	case BSM_AUDITCTL:
200 		result = auditctl((int)uap->a1, (caddr_t)uap->a2, (int)uap->a3);
201 		break;
202 	default:
203 		result = EINVAL;
204 	}
205 	rvp->r_vals = result;
206 	return (result);
207 }
208 
209 /*
210  * Return the audit user ID for the current process.  Currently only
211  * the privileged processes may see the audit id.  That may change.
212  * If copyout is unsucessful return EFAULT.
213  */
214 static int
215 getauid(caddr_t auid_p)
216 {
217 	const auditinfo_addr_t	*ainfo;
218 
219 	if (secpolicy_audit_getattr(CRED()) != 0)
220 		return (EPERM);
221 
222 	ainfo = crgetauinfo(CRED());
223 	if (ainfo == NULL)
224 		return (EINVAL);
225 
226 	if (copyout(&ainfo->ai_auid, auid_p, sizeof (au_id_t)))
227 		return (EFAULT);
228 
229 	return (0);
230 }
231 
232 /*
233  * Set the audit userid, for a process.  This can only be changed by
234  * privileged processes.  The audit userid is inherited across forks & execs.
235  * Passed in is a pointer to the au_id_t; if copyin unsuccessful return EFAULT.
236  */
237 static int
238 setauid(caddr_t auid_p)
239 {
240 	proc_t *p;
241 	au_id_t	auid;
242 	cred_t *newcred;
243 	auditinfo_addr_t *auinfo;
244 
245 	if (secpolicy_audit_config(CRED()) != 0)
246 		return (EPERM);
247 
248 	if (copyin(auid_p, &auid, sizeof (au_id_t))) {
249 		return (EFAULT);
250 	}
251 
252 	newcred = cralloc();
253 	if ((auinfo = crgetauinfo_modifiable(newcred)) == NULL) {
254 		crfree(newcred);
255 		return (EINVAL);
256 	}
257 
258 	/* grab p_crlock and switch to new cred */
259 	p = curproc;
260 	mutex_enter(&p->p_crlock);
261 	crcopy_to(p->p_cred, newcred);
262 	p->p_cred = newcred;
263 
264 	auinfo->ai_auid = auid;			/* update the auid */
265 
266 	/* unlock and broadcast the cred changes */
267 	mutex_exit(&p->p_crlock);
268 	crset(p, newcred);
269 
270 	return (0);
271 }
272 
273 /*
274  * Get the audit state information from the current process.
275  * Return EFAULT if copyout fails.
276  */
277 static int
278 getaudit(caddr_t info_p)
279 {
280 	STRUCT_DECL(auditinfo, info);
281 	const auditinfo_addr_t	*ainfo;
282 	model_t	model;
283 
284 	if (secpolicy_audit_getattr(CRED()) != 0)
285 		return (EPERM);
286 
287 	model = get_udatamodel();
288 	STRUCT_INIT(info, model);
289 
290 	ainfo = crgetauinfo(CRED());
291 	if (ainfo == NULL)
292 		return (EINVAL);
293 
294 	/* trying to read a process with an IPv6 address? */
295 	if (ainfo->ai_termid.at_type == AU_IPv6)
296 		return (EOVERFLOW);
297 
298 	STRUCT_FSET(info, ai_auid, ainfo->ai_auid);
299 	STRUCT_FSET(info, ai_mask, ainfo->ai_mask);
300 #ifdef _LP64
301 	if (model == DATAMODEL_ILP32) {
302 		dev32_t dev;
303 		/* convert internal 64 bit form to 32 bit version */
304 		if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
305 			return (EOVERFLOW);
306 		}
307 		STRUCT_FSET(info, ai_termid.port, dev);
308 	} else
309 		STRUCT_FSET(info, ai_termid.port, ainfo->ai_termid.at_port);
310 #else
311 	STRUCT_FSET(info, ai_termid.port, ainfo->ai_termid.at_port);
312 #endif
313 	STRUCT_FSET(info, ai_termid.machine, ainfo->ai_termid.at_addr[0]);
314 	STRUCT_FSET(info, ai_asid, ainfo->ai_asid);
315 
316 	if (copyout(STRUCT_BUF(info), info_p, STRUCT_SIZE(info)))
317 		return (EFAULT);
318 
319 	return (0);
320 }
321 
322 /*
323  * Get the audit state information from the current process.
324  * Return EFAULT if copyout fails.
325  */
326 static int
327 getaudit_addr(caddr_t info_p, int len)
328 {
329 	STRUCT_DECL(auditinfo_addr, info);
330 	const auditinfo_addr_t	*ainfo;
331 	model_t	model;
332 
333 	if (secpolicy_audit_getattr(CRED()) != 0)
334 		return (EPERM);
335 
336 	model = get_udatamodel();
337 	STRUCT_INIT(info, model);
338 
339 	if (len < STRUCT_SIZE(info))
340 		return (EOVERFLOW);
341 
342 	ainfo = crgetauinfo(CRED());
343 
344 	if (ainfo == NULL)
345 		return (EINVAL);
346 
347 	STRUCT_FSET(info, ai_auid, ainfo->ai_auid);
348 	STRUCT_FSET(info, ai_mask, ainfo->ai_mask);
349 #ifdef _LP64
350 	if (model == DATAMODEL_ILP32) {
351 		dev32_t dev;
352 		/* convert internal 64 bit form to 32 bit version */
353 		if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
354 			return (EOVERFLOW);
355 		}
356 		STRUCT_FSET(info, ai_termid.at_port, dev);
357 	} else
358 		STRUCT_FSET(info, ai_termid.at_port, ainfo->ai_termid.at_port);
359 #else
360 	STRUCT_FSET(info, ai_termid.at_port, ainfo->ai_termid.at_port);
361 #endif
362 	STRUCT_FSET(info, ai_termid.at_type, ainfo->ai_termid.at_type);
363 	STRUCT_FSET(info, ai_termid.at_addr[0], ainfo->ai_termid.at_addr[0]);
364 	STRUCT_FSET(info, ai_termid.at_addr[1], ainfo->ai_termid.at_addr[1]);
365 	STRUCT_FSET(info, ai_termid.at_addr[2], ainfo->ai_termid.at_addr[2]);
366 	STRUCT_FSET(info, ai_termid.at_addr[3], ainfo->ai_termid.at_addr[3]);
367 	STRUCT_FSET(info, ai_asid, ainfo->ai_asid);
368 
369 	if (copyout(STRUCT_BUF(info), info_p, STRUCT_SIZE(info)))
370 		return (EFAULT);
371 
372 	return (0);
373 }
374 
375 /*
376  * Set the audit state information for the current process.
377  * Return EFAULT if copyout fails.
378  */
379 static int
380 setaudit(caddr_t info_p)
381 {
382 	STRUCT_DECL(auditinfo, info);
383 	proc_t *p;
384 	cred_t	*newcred;
385 	model_t	model;
386 	auditinfo_addr_t *ainfo;
387 
388 	if (secpolicy_audit_config(CRED()) != 0)
389 		return (EPERM);
390 
391 	model = get_udatamodel();
392 	STRUCT_INIT(info, model);
393 
394 	if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info)))
395 		return (EFAULT);
396 
397 	newcred = cralloc();
398 	if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) {
399 		crfree(newcred);
400 		return (EINVAL);
401 	}
402 
403 	/* grab p_crlock and switch to new cred */
404 	p = curproc;
405 	mutex_enter(&p->p_crlock);
406 	crcopy_to(p->p_cred, newcred);
407 	p->p_cred = newcred;
408 
409 	/* Set audit mask, id, termid and session id as specified */
410 	ainfo->ai_auid = STRUCT_FGET(info, ai_auid);
411 #ifdef _LP64
412 	/* only convert to 64 bit if coming from a 32 bit binary */
413 	if (model == DATAMODEL_ILP32)
414 		ainfo->ai_termid.at_port =
415 			DEVEXPL(STRUCT_FGET(info, ai_termid.port));
416 	else
417 		ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.port);
418 #else
419 	ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.port);
420 #endif
421 	ainfo->ai_termid.at_type = AU_IPv4;
422 	ainfo->ai_termid.at_addr[0] = STRUCT_FGET(info, ai_termid.machine);
423 	ainfo->ai_asid = STRUCT_FGET(info, ai_asid);
424 	ainfo->ai_mask = STRUCT_FGET(info, ai_mask);
425 
426 	/* unlock and broadcast the cred changes */
427 	mutex_exit(&p->p_crlock);
428 	crset(p, newcred);
429 
430 	return (0);
431 }
432 
433 /*
434  * Set the audit state information for the current process.
435  * Return EFAULT if copyin fails.
436  */
437 static int
438 setaudit_addr(caddr_t info_p, int len)
439 {
440 	STRUCT_DECL(auditinfo_addr, info);
441 	proc_t *p;
442 	cred_t	*newcred;
443 	model_t	model;
444 	int i;
445 	int type;
446 	auditinfo_addr_t *ainfo;
447 
448 	if (secpolicy_audit_config(CRED()) != 0)
449 		return (EPERM);
450 
451 	model = get_udatamodel();
452 	STRUCT_INIT(info, model);
453 
454 	if (len < STRUCT_SIZE(info))
455 		return (EOVERFLOW);
456 
457 	if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info)))
458 		return (EFAULT);
459 
460 	type = STRUCT_FGET(info, ai_termid.at_type);
461 	if ((type != AU_IPv4) && (type != AU_IPv6))
462 		return (EINVAL);
463 
464 	newcred = cralloc();
465 	if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) {
466 		crfree(newcred);
467 		return (EINVAL);
468 	}
469 
470 	/* grab p_crlock and switch to new cred */
471 	p = curproc;
472 	mutex_enter(&p->p_crlock);
473 	crcopy_to(p->p_cred, newcred);
474 	p->p_cred = newcred;
475 
476 	/* Set audit mask, id, termid and session id as specified */
477 	ainfo->ai_auid = STRUCT_FGET(info, ai_auid);
478 	ainfo->ai_mask = STRUCT_FGET(info, ai_mask);
479 #ifdef _LP64
480 	/* only convert to 64 bit if coming from a 32 bit binary */
481 	if (model == DATAMODEL_ILP32)
482 		ainfo->ai_termid.at_port =
483 			DEVEXPL(STRUCT_FGET(info, ai_termid.at_port));
484 	else
485 		ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port);
486 #else
487 	ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port);
488 #endif
489 	ainfo->ai_termid.at_type = type;
490 	bzero(&ainfo->ai_termid.at_addr[0], sizeof (ainfo->ai_termid.at_addr));
491 	for (i = 0; i < (type/sizeof (int)); i++)
492 		ainfo->ai_termid.at_addr[i] =
493 			STRUCT_FGET(info, ai_termid.at_addr[i]);
494 
495 	if (ainfo->ai_termid.at_type == AU_IPv6 &&
496 	    IN6_IS_ADDR_V4MAPPED(((in6_addr_t *)ainfo->ai_termid.at_addr))) {
497 		ainfo->ai_termid.at_type = AU_IPv4;
498 		ainfo->ai_termid.at_addr[0] = ainfo->ai_termid.at_addr[3];
499 		ainfo->ai_termid.at_addr[1] = 0;
500 		ainfo->ai_termid.at_addr[2] = 0;
501 		ainfo->ai_termid.at_addr[3] = 0;
502 	}
503 
504 	ainfo->ai_asid = STRUCT_FGET(info, ai_asid);
505 
506 	/* unlock and broadcast the cred changes */
507 	mutex_exit(&p->p_crlock);
508 	crset(p, newcred);
509 
510 	return (0);
511 }
512 
513 /*
514  * The audit system call. Trust what the user has sent down and save it
515  * away in the audit file. User passes a complete audit record and its
516  * length.  We will fill in the time stamp, check the header and the length
517  * Put a trailer and a sequence token if policy requires.
518  * In the future length might become size_t instead of an int.
519  *
520  * The call is valid whether or not AUDIT_PERZONE is set (think of
521  * login to a zone).  When the local audit state (auk_auditstate) is
522  * AUC_INIT_AUDIT, records are accepted even though auditd isn't
523  * running.
524  */
525 int
526 audit(caddr_t record, int length)
527 {
528 	char	c;
529 	int	count, l;
530 	token_t	*m, *n, *s, *ad;
531 	int	hdrlen, delta;
532 	adr_t	hadr;
533 	adr_t	sadr;
534 	int	size;	/* 0: 32 bit utility  1: 64 bit utility */
535 	int	host_len;
536 	size_t	zlen;
537 	au_kcontext_t	*kctx = SET_KCTX_PZ;
538 
539 	ASSERT(kctx != NULL);
540 
541 	/* if auditing not enabled, then don't generate an audit record */
542 	if (kctx->auk_auditstate != AUC_AUDITING &&
543 	    kctx->auk_auditstate != AUC_INIT_AUDIT)
544 		return (0);
545 
546 	/* Only privileged processes can audit */
547 	if (secpolicy_audit_modify(CRED()) != 0)
548 		return (EPERM);
549 
550 	/* Max user record size is 32K */
551 	if (length > AUDIT_REC_SIZE)
552 		return (E2BIG);
553 
554 	/*
555 	 * The specified length must be at least as big as the smallest
556 	 * possible header token. Later after beginning to scan the
557 	 * header we'll determine the true minimum length according to
558 	 * the header type and attributes.
559 	 */
560 #define	AU_MIN_HEADER_LEN	(sizeof (char) + sizeof (int32_t) + \
561 	sizeof (char) + sizeof (short) + sizeof (short) + \
562 	(sizeof (int32_t) * 2))
563 
564 	if (length < AU_MIN_HEADER_LEN)
565 		return (EINVAL);
566 
567 	/* Read in user's audit record */
568 	count = length;
569 	m = n = s = ad = NULL;
570 	while (count) {
571 		m = au_getclr();
572 		if (!s)
573 			s = n = m;
574 		else {
575 			n->next_buf = m;
576 			n = m;
577 		}
578 		l = MIN(count, AU_BUFSIZE);
579 		if (copyin(record, memtod(m, caddr_t),
580 			(size_t)l)) {
581 				/* copyin failed release au_membuf */
582 				au_free_rec(s);
583 				return (EFAULT);
584 		}
585 		record += l;
586 		count -= l;
587 		m->len = (uchar_t)l;
588 	}
589 
590 	/* Now attach the entire thing to ad */
591 	au_write((caddr_t *)&(ad), s);
592 
593 	/* validate header token type. trust everything following it */
594 	adr_start(&hadr, memtod(s, char *));
595 	(void) adr_getchar(&hadr, &c);
596 	switch (c) {
597 	case AUT_HEADER32:
598 		/* size vers+event_ID+event_modifier fields */
599 		delta = 1 + 2 + 2;
600 		hdrlen = 1 + 4 + delta + (sizeof (int32_t) * 2);
601 		size = HEADER_SIZE32;
602 		break;
603 
604 #ifdef _LP64
605 	case AUT_HEADER64:
606 		/* size vers+event_ID+event_modifier fields */
607 		delta = 1 + 2 + 2;
608 		hdrlen = 1 + 4 + delta + (sizeof (int64_t) * 2);
609 		size = HEADER_SIZE64;
610 		break;
611 #endif
612 
613 	case AUT_HEADER32_EX:
614 		/*
615 		 * Skip over the length/version/type/mod fields and
616 		 * grab the host address type (length), then rewind.
617 		 * This is safe per the previous minimum length check.
618 		 */
619 		hadr.adr_now += 9;
620 		(void) adr_getint32(&hadr, &host_len);
621 		hadr.adr_now -= 9 + sizeof (int32_t);
622 
623 		/* size: vers+event_ID+event_modifier+IP_type+IP_addr_array */
624 		delta = 1 + 2 + 2 + 4 + host_len;
625 		hdrlen = 1 + 4 + delta + (sizeof (int32_t) * 2);
626 		size = HEADER_SIZE32;
627 		break;
628 
629 #ifdef _LP64
630 	case AUT_HEADER64_EX:
631 		/*
632 		 * Skip over the length/version/type/mod fields and grab
633 		 * the host address type (length), then rewind.
634 		 * This is safe per the previous minimum length check.
635 		 */
636 		hadr.adr_now += 9;
637 		(void) adr_getint32(&hadr, &host_len);
638 		hadr.adr_now -= 9 + sizeof (int32_t);
639 
640 		/* size: vers+event_ID+event_modifier+IP_type+IP_addr_array */
641 		delta = 1 + 2 + 2 + 4 + host_len;
642 		hdrlen = 1 + 4 + delta + (sizeof (int64_t) * 2);
643 		size = HEADER_SIZE64;
644 		break;
645 #endif
646 
647 	default:
648 		/* Header is wrong, reject message */
649 		au_free_rec(s);
650 		return (EINVAL);
651 	}
652 
653 	if (length < hdrlen) {
654 		au_free_rec(s);
655 		return (0);
656 	}
657 
658 	/* advance over header token length field */
659 	hadr.adr_now += 4;
660 
661 	/* validate version */
662 	(void) adr_getchar(&hadr, &c);
663 	if (c != TOKEN_VERSION) {
664 		/* version is wrong, reject message */
665 		au_free_rec(s);
666 		return (EINVAL);
667 	}
668 
669 	/* backup to header length field (including version field) */
670 	hadr.adr_now -= 5;
671 
672 	/*
673 	 * add on the zonename token if policy AUDIT_ZONENAME is set
674 	 */
675 	if (kctx->auk_policy & AUDIT_ZONENAME) {
676 		zlen = au_zonename_length();
677 		if (zlen > 0) {
678 			length += zlen;
679 			m = au_to_zonename(zlen);
680 			(void) au_append_rec(ad, m, AU_PACK);
681 		}
682 	}
683 	/* Add an (optional) sequence token. NULL offset if none */
684 	if (kctx->auk_policy & AUDIT_SEQ) {
685 		/* get the sequnce token */
686 		m = au_to_seq();
687 
688 		/* sequence token 5 bytes long */
689 		length += 5;
690 
691 		/* link to audit record (i.e. don't pack the data) */
692 		(void) au_append_rec(ad, m, AU_LINK);
693 
694 		/* advance to count field of token */
695 		adr_start(&sadr, memtod(m, char *));
696 		sadr.adr_now += 1;
697 	} else
698 		sadr.adr_now = (char *)NULL;
699 
700 	/* add the (optional) trailer token */
701 	if (kctx->auk_policy & AUDIT_TRAIL) {
702 		/* trailer token is 7 bytes long */
703 		length += 7;
704 
705 		/* append to audit record */
706 		(void) au_append_rec(ad, au_to_trailer(length), AU_PACK);
707 	}
708 
709 	/* audit record completely assembled. set the length */
710 	adr_int32(&hadr, (int32_t *)&length, 1);
711 
712 	/* advance to date/time field of header */
713 	hadr.adr_now += delta;
714 
715 	/* We are done  put it on the queue */
716 	AS_INC(as_generated, 1, kctx);
717 	AS_INC(as_audit, 1, kctx);
718 
719 	au_enqueue(kctx, s, &hadr, &sadr, size, 0);
720 
721 	AS_INC(as_totalsize, length, kctx);
722 
723 	return (0);
724 }
725 
726 static void
727 audit_dont_stop(void *kctx)
728 {
729 
730 	if ((((au_kcontext_t *)kctx)->auk_valid != AUK_VALID) ||
731 	    (((au_kcontext_t *)kctx)->auk_auditstate == AUC_NOAUDIT))
732 		return;
733 
734 	mutex_enter(&(((au_kcontext_t *)kctx)->auk_queue.lock));
735 	cv_broadcast(&(((au_kcontext_t *)kctx)->auk_queue.write_cv));
736 	mutex_exit(&(((au_kcontext_t *)kctx)->auk_queue.lock));
737 }
738 
739 /*
740  * auditdoor starts a kernel thread to generate output from the audit
741  * queue.  The thread terminates when it detects auditing being turned
742  * off, such as when auditd exits with a SIGTERM.  If a subsequent
743  * auditdoor arrives while the thread is running, the door descriptor
744  * of the last auditdoor in will be used for output.  auditd is responsible
745  * for insuring that multiple copies are not running.
746  */
747 
748 static int
749 auditdoor(int fd)
750 {
751 	struct file	*fp;
752 	struct vnode	*vp;
753 	int		error = 0;
754 	int		do_create = 0;
755 	au_kcontext_t	*kctx;
756 
757 	if (secpolicy_audit_config(CRED()) != 0)
758 		return (EPERM);
759 
760 	if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
761 		return (EINVAL);
762 
763 	kctx = SET_KCTX_LZ;
764 
765 	/*
766 	 * Prevent a second audit daemon from running this code.
767 	 * auk_svc_busy == 2 until the output thread terminates.
768 	 * Multiple calls to auditdoor() are valid but a call
769 	 * to auditsvc() while au_output_thread() is running
770 	 * or a call to auditdoor() while auditsvc is running
771 	 * is blocked.
772 	 */
773 	mutex_enter(&(kctx->auk_svc_lock));
774 	if (kctx->auk_svc_busy == 1) {		/* active auditsvc? */
775 		mutex_exit(&(kctx->auk_svc_lock));
776 		return (EBUSY);
777 	}
778 	kctx->auk_svc_busy = 2;
779 	mutex_exit(&(kctx->auk_svc_lock));
780 	/*
781 	 * convert file pointer to file descriptor
782 	 *   Note: fd ref count incremented here.
783 	 */
784 	if ((fp = (struct file *)getf(fd)) == NULL) {
785 		error = EBADF;
786 		goto svc_exit;
787 	}
788 	vp = fp->f_vnode;
789 	if (vp->v_type != VDOOR) {
790 		cmn_err(CE_WARN,
791 		    "auditdoor() did not get the expected door descriptor\n");
792 		error = EINVAL;
793 		releasef(fd);
794 		goto svc_exit;
795 	}
796 	/*
797 	 * If the output thread is already running, then replace the
798 	 * door descriptor with the new one and continue; otherwise
799 	 * create the thread too.  Since au_output_thread makes a call
800 	 * to au_doorio() which also does
801 	 * mutex_lock(&(kctx->auk_svc_lock)), the create/dispatch is
802 	 * done after the unlock...
803 	 */
804 	mutex_enter(&(kctx->auk_svc_lock));
805 
806 	if (kctx->auk_current_vp != NULL)
807 		VN_RELE(kctx->auk_current_vp);
808 
809 	kctx->auk_current_vp = vp;
810 	VN_HOLD(kctx->auk_current_vp);
811 	releasef(fd);
812 
813 	if (!kctx->auk_output_active) {
814 		kctx->auk_output_active = 1;
815 		do_create = 1;
816 	}
817 	mutex_exit(&(kctx->auk_svc_lock));
818 	if (do_create) {
819 		kctx->auk_taskq =
820 		    taskq_create("output_master", 1, minclsyspri, 1, 1, 0);
821 		(void) taskq_dispatch(kctx->auk_taskq,
822 		    (task_func_t *)au_output_thread,
823 		    kctx, TQ_SLEEP);
824 	}
825 svc_exit:
826 	if (error) {
827 		mutex_enter(&(kctx->auk_svc_lock));
828 		kctx->auk_svc_busy = 2;
829 		mutex_exit(&(kctx->auk_svc_lock));
830 	}
831 	return (error);
832 }
833 
834 /*
835  * au_queue_kick -- wake up the output queue after delay ticks
836  */
837 static void
838 au_queue_kick(void *kctx)
839 {
840 	/*
841 	 * wakeup reader if its not running and there is something
842 	 * to do.  It also helps that kctx still be valid...
843 	 */
844 
845 	if ((((au_kcontext_t *)kctx)->auk_valid != AUK_VALID) ||
846 	    (((au_kcontext_t *)kctx)->auk_auditstate == AUC_NOAUDIT))
847 		return;
848 
849 	if (((au_kcontext_t *)kctx)->auk_queue.cnt &&
850 	    ((au_kcontext_t *)kctx)->auk_queue.rd_block)
851 		cv_broadcast(&((au_kcontext_t *)kctx)->auk_queue.read_cv);
852 
853 	/* fire off timeout event to kick audit queue awake */
854 	(void) timeout(au_queue_kick, kctx,
855 	    ((au_kcontext_t *)kctx)->auk_queue.delay);
856 }
857 
858 /*
859  * output thread
860  *
861  * this runs "forever" where "forever" means until either auk_auditstate
862  * changes from AUC_AUDITING or if the door descriptor becomes invalid.
863  *
864  * there is one thread per active zone if AUC_PERZONE is set.  Since
865  * there is the possibility that a zone may go down without auditd
866  * terminating properly, a zone shutdown kills its au_output_thread()
867  * via taskq_destroy().
868  */
869 
870 static void
871 au_output_thread(au_kcontext_t *kctx)
872 {
873 	int		error = 0;
874 
875 	(void) timeout(au_queue_kick, kctx, kctx->auk_queue.delay);
876 
877 	/*
878 	 * Wait for work, until a signal arrives,
879 	 * or until auditing is disabled.
880 	 */
881 
882 	while (!error) {
883 	    if (kctx->auk_auditstate == AUC_AUDITING) {
884 		mutex_enter(&(kctx->auk_queue.lock));
885 		while (kctx->auk_queue.head == NULL) {
886 		    /* safety check. kick writer awake */
887 		    if (kctx->auk_queue.wt_block)
888 			cv_broadcast(&(kctx->auk_queue.write_cv));
889 
890 		    kctx->auk_queue.rd_block = 1;
891 		    AS_INC(as_rblocked, 1, kctx);
892 
893 		    cv_wait(&(kctx->auk_queue.read_cv),
894 			&(kctx->auk_queue.lock));
895 
896 		    kctx->auk_queue.rd_block = 0;
897 
898 		    if (kctx->auk_auditstate != AUC_AUDITING) {
899 			mutex_exit(&(kctx->auk_queue.lock));
900 			(void) timeout(audit_dont_stop, kctx, au_resid);
901 			goto output_exit;
902 		    }
903 		    kctx->auk_queue.rd_block = 0;
904 		}
905 		mutex_exit(&(kctx->auk_queue.lock));
906 		/*
907 		 * au_doorio() calls au_door_upcall which holds auk_svc_lock;
908 		 * au_doorio empties the queue before returning.
909 		 */
910 
911 		error = au_doorio(kctx);
912 	    } else	/* auditing turned off while we slept */
913 		break;
914 	}
915 output_exit:
916 	mutex_enter(&(kctx->auk_svc_lock));
917 
918 	VN_RELE(kctx->auk_current_vp);
919 	kctx->auk_current_vp = NULL;
920 
921 	kctx->auk_output_active = 0;
922 	kctx->auk_svc_busy = 0;
923 
924 	mutex_exit(&(kctx->auk_svc_lock));
925 }
926 
927 
928 /*
929  * Get the global policy flag
930  */
931 
932 static int
933 getpolicy(caddr_t data)
934 {
935 	int	policy;
936 	au_kcontext_t	*kctx = SET_KCTX_PZ;
937 
938 	policy = audit_policy | kctx->auk_policy;
939 
940 	if (copyout(&policy, data, sizeof (int)))
941 		return (EFAULT);
942 	return (0);
943 }
944 
945 /*
946  * Set the global and local policy flags
947  *
948  * The global flags only make sense from the global zone;
949  * the local flags depend on the AUDIT_PERZONE policy:
950  * if the perzone policy is set, then policy is set separately
951  * per zone, else held only in the global zone.
952  *
953  * The initial value of a local zone's policy flag is determined
954  * by the value of the global zone's flags at the time the
955  * local zone is created.
956  *
957  * While auditconfig(1M) allows setting and unsetting policies one bit
958  * at a time, the mask passed in from auditconfig() is created by a
959  * syscall to getpolicy and then modified based on the auditconfig()
960  * cmd line, so the input policy value is used to replace the existing
961  * policy.
962  */
963 
964 
965 static int
966 setpolicy(caddr_t data)
967 {
968 	int	policy;
969 	au_kcontext_t	*kctx;
970 
971 	if (copyin(data, &policy, sizeof (int)))
972 		return (EFAULT);
973 
974 	kctx = SET_KCTX_LZ;
975 	ASSERT(kctx != NULL);
976 
977 	if (INGLOBALZONE(curproc)) {
978 		if (policy & ~(AUDIT_GLOBAL | AUDIT_LOCAL))
979 			return (EINVAL);
980 
981 		audit_policy = policy & AUDIT_GLOBAL;
982 	} else {
983 		if (!(audit_policy & AUDIT_PERZONE))
984 			return (EINVAL);
985 
986 		if (policy & ~AUDIT_LOCAL)	/* global bits are a no-no */
987 			return (EINVAL);
988 	}
989 	kctx->auk_policy = policy & AUDIT_LOCAL;
990 
991 	/*
992 	 * auk_current_vp is NULL before auditd starts (or during early
993 	 * auditd starup) or if auditd is halted; in either case,
994 	 * notification of a policy change is not needed, since auditd
995 	 * reads policy as it comes up.  The error return from au_doormsg()
996 	 * is ignored to avoid a race condition -- for example if auditd
997 	 * segv's, the audit state may be "auditing" but the door may
998 	 * be closed.  Returning an error if the door is open makes it
999 	 * impossible for Greenline to restart auditd.
1000 	 */
1001 	if (kctx->auk_current_vp != NULL)
1002 		(void) au_doormsg(kctx, AU_DBUF_POLICY, &policy);
1003 
1004 	/*
1005 	 * Wake up anyone who might have blocked on full audit
1006 	 * partitions. audit daemons need to set AUDIT_FULL when no
1007 	 * space so we can tell if we should start dropping records.
1008 	 */
1009 	mutex_enter(&(kctx->auk_queue.lock));
1010 
1011 	if ((policy & (AUDIT_CNT | AUDIT_SCNT) &&
1012 	    (kctx->auk_queue.cnt >= kctx->auk_queue.hiwater)))
1013 		cv_broadcast(&(kctx->auk_queue.write_cv));
1014 
1015 	mutex_exit(&(kctx->auk_queue.lock));
1016 
1017 	return (0);
1018 }
1019 
1020 static int
1021 getkmask(caddr_t data)
1022 {
1023 	au_kcontext_t	*kctx;
1024 
1025 	kctx = SET_KCTX_PZ;
1026 
1027 	if (copyout(&kctx->auk_info.ai_mask, data, sizeof (au_mask_t)))
1028 		return (EFAULT);
1029 	return (0);
1030 }
1031 
1032 static int
1033 setkmask(caddr_t data)
1034 {
1035 	au_mask_t	mask;
1036 	au_kcontext_t	*kctx;
1037 
1038 	if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
1039 		return (EINVAL);
1040 
1041 	kctx = SET_KCTX_LZ;
1042 
1043 	if (copyin(data, &mask, sizeof (au_mask_t)))
1044 		return (EFAULT);
1045 
1046 	kctx->auk_info.ai_mask = mask;
1047 	return (0);
1048 }
1049 
1050 static int
1051 getkaudit(caddr_t info_p, int len)
1052 {
1053 	STRUCT_DECL(auditinfo_addr, info);
1054 	model_t model;
1055 	au_kcontext_t	*kctx = SET_KCTX_PZ;
1056 
1057 	model = get_udatamodel();
1058 	STRUCT_INIT(info, model);
1059 
1060 	if (len < STRUCT_SIZE(info))
1061 		return (EOVERFLOW);
1062 
1063 	STRUCT_FSET(info, ai_auid, kctx->auk_info.ai_auid);
1064 	STRUCT_FSET(info, ai_mask, kctx->auk_info.ai_mask);
1065 #ifdef _LP64
1066 	if (model == DATAMODEL_ILP32) {
1067 		dev32_t dev;
1068 		/* convert internal 64 bit form to 32 bit version */
1069 		if (cmpldev(&dev, kctx->auk_info.ai_termid.at_port) == 0) {
1070 			return (EOVERFLOW);
1071 		}
1072 		STRUCT_FSET(info, ai_termid.at_port, dev);
1073 	} else
1074 		STRUCT_FSET(info, ai_termid.at_port,
1075 			kctx->auk_info.ai_termid.at_port);
1076 #else
1077 	STRUCT_FSET(info, ai_termid.at_port,
1078 		kctx->auk_info.ai_termid.at_port);
1079 #endif
1080 	STRUCT_FSET(info, ai_termid.at_type,
1081 	    kctx->auk_info.ai_termid.at_type);
1082 	STRUCT_FSET(info, ai_termid.at_addr[0],
1083 	    kctx->auk_info.ai_termid.at_addr[0]);
1084 	STRUCT_FSET(info, ai_termid.at_addr[1],
1085 	    kctx->auk_info.ai_termid.at_addr[1]);
1086 	STRUCT_FSET(info, ai_termid.at_addr[2],
1087 	    kctx->auk_info.ai_termid.at_addr[2]);
1088 	STRUCT_FSET(info, ai_termid.at_addr[3],
1089 	    kctx->auk_info.ai_termid.at_addr[3]);
1090 	STRUCT_FSET(info, ai_asid, kctx->auk_info.ai_asid);
1091 
1092 	if (copyout(STRUCT_BUF(info), info_p, STRUCT_SIZE(info)))
1093 		return (EFAULT);
1094 
1095 	return (0);
1096 }
1097 
1098 /*
1099  * the host address for AUDIT_PERZONE == 0 is that of the global
1100  * zone and for local zones it is of the current zone.
1101  */
1102 
1103 static int
1104 setkaudit(caddr_t info_p, int len)
1105 {
1106 	STRUCT_DECL(auditinfo_addr, info);
1107 	model_t model;
1108 	au_kcontext_t	*kctx;
1109 
1110 	if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
1111 		return (EINVAL);
1112 
1113 	kctx = SET_KCTX_LZ;
1114 
1115 	model = get_udatamodel();
1116 	STRUCT_INIT(info, model);
1117 
1118 	if (len < STRUCT_SIZE(info))
1119 		return (EOVERFLOW);
1120 
1121 	if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info)))
1122 		return (EFAULT);
1123 
1124 	if ((STRUCT_FGET(info, ai_termid.at_type) != AU_IPv4) &&
1125 	    (STRUCT_FGET(info, ai_termid.at_type) != AU_IPv6))
1126 		return (EINVAL);
1127 
1128 	/* Set audit mask, termid and session id as specified */
1129 	kctx->auk_info.ai_auid = STRUCT_FGET(info, ai_auid);
1130 	kctx->auk_info.ai_mask = STRUCT_FGET(info, ai_mask);
1131 #ifdef _LP64
1132 	/* only convert to 64 bit if coming from a 32 bit binary */
1133 	if (model == DATAMODEL_ILP32)
1134 		kctx->auk_info.ai_termid.at_port =
1135 			DEVEXPL(STRUCT_FGET(info, ai_termid.at_port));
1136 	else
1137 		kctx->auk_info.ai_termid.at_port =
1138 			STRUCT_FGET(info, ai_termid.at_port);
1139 #else
1140 	kctx->auk_info.ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port);
1141 #endif
1142 	kctx->auk_info.ai_termid.at_type = STRUCT_FGET(info, ai_termid.at_type);
1143 	bzero(&kctx->auk_info.ai_termid.at_addr[0],
1144 		sizeof (kctx->auk_info.ai_termid.at_addr));
1145 	kctx->auk_info.ai_termid.at_addr[0] =
1146 	    STRUCT_FGET(info, ai_termid.at_addr[0]);
1147 	kctx->auk_info.ai_termid.at_addr[1] =
1148 	    STRUCT_FGET(info, ai_termid.at_addr[1]);
1149 	kctx->auk_info.ai_termid.at_addr[2] =
1150 	    STRUCT_FGET(info, ai_termid.at_addr[2]);
1151 	kctx->auk_info.ai_termid.at_addr[3] =
1152 	    STRUCT_FGET(info, ai_termid.at_addr[3]);
1153 	kctx->auk_info.ai_asid = STRUCT_FGET(info, ai_asid);
1154 
1155 	if (kctx->auk_info.ai_termid.at_type == AU_IPv6 &&
1156 	    IN6_IS_ADDR_V4MAPPED(
1157 	    ((in6_addr_t *)kctx->auk_info.ai_termid.at_addr))) {
1158 		kctx->auk_info.ai_termid.at_type = AU_IPv4;
1159 		kctx->auk_info.ai_termid.at_addr[0] =
1160 		    kctx->auk_info.ai_termid.at_addr[3];
1161 		kctx->auk_info.ai_termid.at_addr[1] = 0;
1162 		kctx->auk_info.ai_termid.at_addr[2] = 0;
1163 		kctx->auk_info.ai_termid.at_addr[3] = 0;
1164 	}
1165 	if (kctx->auk_info.ai_termid.at_type == AU_IPv6)
1166 		kctx->auk_hostaddr_valid = IN6_IS_ADDR_UNSPECIFIED(
1167 		    (in6_addr_t *)kctx->auk_info.ai_termid.at_addr) ? 0 : 1;
1168 	else
1169 		kctx->auk_hostaddr_valid =
1170 		    (kctx->auk_info.ai_termid.at_addr[0] ==
1171 		    htonl(INADDR_ANY)) ? 0 : 1;
1172 
1173 	return (0);
1174 }
1175 
1176 static int
1177 getqctrl(caddr_t data)
1178 {
1179 	au_kcontext_t	*kctx = SET_KCTX_PZ;
1180 	STRUCT_DECL(au_qctrl, qctrl);
1181 	STRUCT_INIT(qctrl, get_udatamodel());
1182 
1183 	mutex_enter(&(kctx->auk_queue.lock));
1184 	STRUCT_FSET(qctrl, aq_hiwater, kctx->auk_queue.hiwater);
1185 	STRUCT_FSET(qctrl, aq_lowater, kctx->auk_queue.lowater);
1186 	STRUCT_FSET(qctrl, aq_bufsz, kctx->auk_queue.bufsz);
1187 	STRUCT_FSET(qctrl, aq_delay, kctx->auk_queue.delay);
1188 	mutex_exit(&(kctx->auk_queue.lock));
1189 
1190 	if (copyout(STRUCT_BUF(qctrl), data, STRUCT_SIZE(qctrl)))
1191 		return (EFAULT);
1192 
1193 	return (0);
1194 }
1195 
1196 static int
1197 setqctrl(caddr_t data)
1198 {
1199 	au_kcontext_t	*kctx;
1200 	struct au_qctrl qctrl_tmp;
1201 	STRUCT_DECL(au_qctrl, qctrl);
1202 	STRUCT_INIT(qctrl, get_udatamodel());
1203 
1204 	if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
1205 		return (EINVAL);
1206 	kctx = SET_KCTX_LZ;
1207 
1208 	if (copyin(data, STRUCT_BUF(qctrl), STRUCT_SIZE(qctrl)))
1209 		return (EFAULT);
1210 
1211 	qctrl_tmp.aq_hiwater = (size_t)STRUCT_FGET(qctrl, aq_hiwater);
1212 	qctrl_tmp.aq_lowater = (size_t)STRUCT_FGET(qctrl, aq_lowater);
1213 	qctrl_tmp.aq_bufsz = (size_t)STRUCT_FGET(qctrl, aq_bufsz);
1214 	qctrl_tmp.aq_delay = (clock_t)STRUCT_FGET(qctrl, aq_delay);
1215 
1216 	/* enforce sane values */
1217 
1218 	if (qctrl_tmp.aq_hiwater <= qctrl_tmp.aq_lowater)
1219 		return (EINVAL);
1220 
1221 	if (qctrl_tmp.aq_hiwater < AQ_LOWATER)
1222 		return (EINVAL);
1223 
1224 	if (qctrl_tmp.aq_hiwater > AQ_MAXHIGH)
1225 		return (EINVAL);
1226 
1227 	if (qctrl_tmp.aq_bufsz < AQ_BUFSZ)
1228 		return (EINVAL);
1229 
1230 	if (qctrl_tmp.aq_bufsz > AQ_MAXBUFSZ)
1231 		return (EINVAL);
1232 
1233 	if (qctrl_tmp.aq_delay == 0)
1234 		return (EINVAL);
1235 
1236 	if (qctrl_tmp.aq_delay > AQ_MAXDELAY)
1237 		return (EINVAL);
1238 
1239 	/* update everything at once so things are consistant */
1240 	mutex_enter(&(kctx->auk_queue.lock));
1241 	kctx->auk_queue.hiwater = qctrl_tmp.aq_hiwater;
1242 	kctx->auk_queue.lowater = qctrl_tmp.aq_lowater;
1243 	kctx->auk_queue.bufsz = qctrl_tmp.aq_bufsz;
1244 	kctx->auk_queue.delay = qctrl_tmp.aq_delay;
1245 
1246 	if (kctx->auk_queue.rd_block &&
1247 	    kctx->auk_queue.cnt > kctx->auk_queue.lowater)
1248 		cv_broadcast(&(kctx->auk_queue.read_cv));
1249 
1250 	if (kctx->auk_queue.wt_block &&
1251 	    kctx->auk_queue.cnt < kctx->auk_queue.hiwater)
1252 		cv_broadcast(&(kctx->auk_queue.write_cv));
1253 
1254 	mutex_exit(&(kctx->auk_queue.lock));
1255 
1256 	return (0);
1257 }
1258 
1259 static int
1260 getcwd(caddr_t data, int length)
1261 {
1262 	struct p_audit_data	*pad;
1263 	struct audit_path	*app;
1264 	int	pathlen;
1265 
1266 	pad = P2A(curproc);
1267 	ASSERT(pad != NULL);
1268 
1269 	mutex_enter(&(pad->pad_lock));
1270 	app = pad->pad_cwd;
1271 	au_pathhold(app);
1272 	mutex_exit(&(pad->pad_lock));
1273 
1274 	pathlen = app->audp_sect[1] - app->audp_sect[0];
1275 	if (pathlen > length) {
1276 		au_pathrele(app);
1277 		return (E2BIG);
1278 	}
1279 
1280 	if (copyout(app->audp_sect[0], data, pathlen)) {
1281 		au_pathrele(app);
1282 		return (EFAULT);
1283 	}
1284 
1285 	au_pathrele(app);
1286 	return (0);
1287 }
1288 
1289 static int
1290 getcar(caddr_t data, int length)
1291 {
1292 	struct p_audit_data	*pad;
1293 	struct audit_path	*app;
1294 	int	pathlen;
1295 
1296 	pad = P2A(curproc);
1297 	ASSERT(pad != NULL);
1298 
1299 	mutex_enter(&(pad->pad_lock));
1300 	app = pad->pad_root;
1301 	au_pathhold(app);
1302 	mutex_exit(&(pad->pad_lock));
1303 
1304 	pathlen = app->audp_sect[1] - app->audp_sect[0];
1305 	if (pathlen > length) {
1306 		au_pathrele(app);
1307 		return (E2BIG);
1308 	}
1309 
1310 	if (copyout(app->audp_sect[0], data, pathlen)) {
1311 		au_pathrele(app);
1312 		return (EFAULT);
1313 	}
1314 
1315 	au_pathrele(app);
1316 	return (0);
1317 }
1318 
1319 static int
1320 getstat(caddr_t data)
1321 {
1322 	au_kcontext_t	*kctx = SET_KCTX_PZ;
1323 
1324 	membar_consumer();
1325 
1326 	if (copyout((caddr_t)&(kctx->auk_statistics), data, sizeof (au_stat_t)))
1327 		return (EFAULT);
1328 	return (0);
1329 }
1330 
1331 
1332 static int
1333 setstat(caddr_t data)
1334 {
1335 	au_kcontext_t	*kctx = SET_KCTX_PZ;
1336 	au_stat_t au_stat;
1337 
1338 	if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
1339 		return (EINVAL);
1340 
1341 	if (copyin(data, &au_stat, sizeof (au_stat_t)))
1342 		return (EFAULT);
1343 
1344 	if (au_stat.as_generated == CLEAR_VAL)
1345 		kctx->auk_statistics.as_generated = 0;
1346 	if (au_stat.as_nonattrib == CLEAR_VAL)
1347 		kctx->auk_statistics.as_nonattrib = 0;
1348 	if (au_stat.as_kernel == CLEAR_VAL)
1349 		kctx->auk_statistics.as_kernel = 0;
1350 	if (au_stat.as_audit == CLEAR_VAL)
1351 		kctx->auk_statistics.as_audit = 0;
1352 	if (au_stat.as_auditctl == CLEAR_VAL)
1353 		kctx->auk_statistics.as_auditctl = 0;
1354 	if (au_stat.as_enqueue == CLEAR_VAL)
1355 		kctx->auk_statistics.as_enqueue = 0;
1356 	if (au_stat.as_written == CLEAR_VAL)
1357 		kctx->auk_statistics.as_written = 0;
1358 	if (au_stat.as_wblocked == CLEAR_VAL)
1359 		kctx->auk_statistics.as_wblocked = 0;
1360 	if (au_stat.as_rblocked == CLEAR_VAL)
1361 		kctx->auk_statistics.as_rblocked = 0;
1362 	if (au_stat.as_dropped == CLEAR_VAL)
1363 		kctx->auk_statistics.as_dropped = 0;
1364 	if (au_stat.as_totalsize == CLEAR_VAL)
1365 		kctx->auk_statistics.as_totalsize = 0;
1366 
1367 	membar_producer();
1368 
1369 	return (0);
1370 
1371 }
1372 
1373 static int
1374 setumask(caddr_t data)
1375 {
1376 	STRUCT_DECL(auditinfo, user_info);
1377 	struct proc *p;
1378 	const auditinfo_addr_t	*ainfo;
1379 	model_t	model;
1380 
1381 	model = get_udatamodel();
1382 	STRUCT_INIT(user_info, model);
1383 
1384 	if (copyin(data, STRUCT_BUF(user_info), STRUCT_SIZE(user_info)))
1385 		return (EFAULT);
1386 
1387 	mutex_enter(&pidlock);	/* lock the process queue against updates */
1388 	for (p = practive; p != NULL; p = p->p_next) {
1389 		cred_t	*cr;
1390 
1391 		mutex_enter(&p->p_lock);	/* so process doesn't go away */
1392 		mutex_enter(&p->p_crlock);
1393 		crhold(cr = p->p_cred);
1394 		mutex_exit(&p->p_crlock);
1395 		ainfo = crgetauinfo(cr);
1396 		if (ainfo == NULL) {
1397 			mutex_exit(&p->p_lock);
1398 			crfree(cr);
1399 			continue;
1400 		}
1401 
1402 		if (ainfo->ai_auid == STRUCT_FGET(user_info, ai_auid)) {
1403 			au_mask_t	mask;
1404 			int		err;
1405 
1406 			/*
1407 			 * Here's a process which matches the specified auid.
1408 			 * If its mask doesn't already match the new mask,
1409 			 * save the new mask in the pad, to be picked up
1410 			 * next syscall.
1411 			 */
1412 			mask = STRUCT_FGET(user_info, ai_mask);
1413 			err = bcmp(&mask, &ainfo->ai_mask, sizeof (au_mask_t));
1414 			crfree(cr);
1415 			if (err != 0) {
1416 				struct p_audit_data *pad = P2A(p);
1417 				ASSERT(pad != NULL);
1418 
1419 				mutex_enter(&(pad->pad_lock));
1420 				pad->pad_flags |= PAD_SETMASK;
1421 				pad->pad_newmask = mask;
1422 				mutex_exit(&(pad->pad_lock));
1423 
1424 				/*
1425 				 * No need to call set_proc_pre_sys(), since
1426 				 * t_pre_sys is ALWAYS on when audit is
1427 				 * enabled...due to syscall auditing.
1428 				 */
1429 			}
1430 		} else {
1431 			crfree(cr);
1432 		}
1433 		mutex_exit(&p->p_lock);
1434 	}
1435 	mutex_exit(&pidlock);
1436 
1437 	return (0);
1438 }
1439 
1440 static int
1441 setsmask(caddr_t data)
1442 {
1443 	STRUCT_DECL(auditinfo, user_info);
1444 	struct proc *p;
1445 	const auditinfo_addr_t	*ainfo;
1446 	model_t	model;
1447 
1448 	model = get_udatamodel();
1449 	STRUCT_INIT(user_info, model);
1450 
1451 	if (copyin(data, STRUCT_BUF(user_info), STRUCT_SIZE(user_info)))
1452 		return (EFAULT);
1453 
1454 	mutex_enter(&pidlock);	/* lock the process queue against updates */
1455 	for (p = practive; p != NULL; p = p->p_next) {
1456 		cred_t	*cr;
1457 
1458 		mutex_enter(&p->p_lock);	/* so process doesn't go away */
1459 		mutex_enter(&p->p_crlock);
1460 		crhold(cr = p->p_cred);
1461 		mutex_exit(&p->p_crlock);
1462 		ainfo = crgetauinfo(cr);
1463 		if (ainfo == NULL) {
1464 			mutex_exit(&p->p_lock);
1465 			crfree(cr);
1466 			continue;
1467 		}
1468 
1469 		if (ainfo->ai_asid == STRUCT_FGET(user_info, ai_asid)) {
1470 			au_mask_t	mask;
1471 			int		err;
1472 
1473 			/*
1474 			 * Here's a process which matches the specified asid.
1475 			 * If its mask doesn't already match the new mask,
1476 			 * save the new mask in the pad, to be picked up
1477 			 * next syscall.
1478 			 */
1479 			mask = STRUCT_FGET(user_info, ai_mask);
1480 			err = bcmp(&mask, &ainfo->ai_mask, sizeof (au_mask_t));
1481 			crfree(cr);
1482 			if (err != 0) {
1483 				struct p_audit_data *pad = P2A(p);
1484 				ASSERT(pad != NULL);
1485 
1486 				mutex_enter(&(pad->pad_lock));
1487 				pad->pad_flags |= PAD_SETMASK;
1488 				pad->pad_newmask = mask;
1489 				mutex_exit(&(pad->pad_lock));
1490 
1491 				/*
1492 				 * No need to call set_proc_pre_sys(), since
1493 				 * t_pre_sys is ALWAYS on when audit is
1494 				 * enabled...due to syscall auditing.
1495 				 */
1496 			}
1497 		} else {
1498 			crfree(cr);
1499 		}
1500 		mutex_exit(&p->p_lock);
1501 	}
1502 	mutex_exit(&pidlock);
1503 
1504 	return (0);
1505 }
1506 
1507 /*
1508  * Get the current audit state of the system
1509  */
1510 static int
1511 getcond(caddr_t data)
1512 {
1513 	au_kcontext_t	*kctx;
1514 
1515 	if (au_auditstate == AUC_DISABLED)
1516 		if (copyout(&au_auditstate, data, sizeof (int)))
1517 			return (EFAULT);
1518 
1519 	kctx = SET_KCTX_PZ;
1520 
1521 	if (copyout(&(kctx->auk_auditstate), data, sizeof (int)))
1522 		return (EFAULT);
1523 
1524 	return (0);
1525 }
1526 
1527 /*
1528  * Set the current audit state of the system to on (AUC_AUDITING) or
1529  * off (AUC_NOAUDIT).
1530  */
1531 /* ARGSUSED */
1532 static int
1533 setcond(caddr_t data)
1534 {
1535 	int	auditstate;
1536 	au_kcontext_t	*kctx;
1537 
1538 	if (!(audit_policy & AUDIT_PERZONE) && (!INGLOBALZONE(curproc)))
1539 		return (EINVAL);
1540 
1541 	kctx = SET_KCTX_LZ;
1542 
1543 	if (copyin(data, &auditstate, sizeof (int)))
1544 		return (EFAULT);
1545 
1546 	switch (auditstate) {
1547 	case AUC_AUDITING:		/* Turn auditing on */
1548 		kctx->auk_auditstate = AUC_AUDITING;
1549 		au_auditstate = AUC_ENABLED;
1550 		break;
1551 
1552 	case AUC_NOAUDIT:		/* Turn auditing off */
1553 		if (kctx->auk_auditstate == AUC_NOAUDIT)
1554 			break;
1555 		kctx->auk_auditstate = AUC_NOAUDIT;
1556 
1557 		/* clear out the audit queue */
1558 
1559 		mutex_enter(&(kctx->auk_queue.lock));
1560 		if (kctx->auk_queue.wt_block)
1561 			cv_broadcast(&(kctx->auk_queue.write_cv));
1562 
1563 		/* unblock au_output_thread */
1564 		cv_broadcast(&(kctx->auk_queue.read_cv));
1565 
1566 		mutex_exit(&(kctx->auk_queue.lock));
1567 		break;
1568 
1569 	default:
1570 		return (EINVAL);
1571 	}
1572 
1573 	return (0);
1574 }
1575 
1576 static int
1577 getclass(caddr_t data)
1578 {
1579 	au_evclass_map_t event;
1580 	au_kcontext_t	*kctx = SET_KCTX_PZ;
1581 
1582 	if (copyin(data, &event, sizeof (au_evclass_map_t)))
1583 		return (EFAULT);
1584 
1585 	if (event.ec_number < 0 || event.ec_number > (au_naevent - 1))
1586 		return (EINVAL);
1587 
1588 	event.ec_class = kctx->auk_ets[event.ec_number];
1589 
1590 	if (copyout(&event, data, sizeof (au_evclass_map_t)))
1591 		return (EFAULT);
1592 
1593 	return (0);
1594 }
1595 
1596 static int
1597 setclass(caddr_t data)
1598 {
1599 	au_evclass_map_t event;
1600 	au_kcontext_t	*kctx;
1601 
1602 	if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
1603 		return (EINVAL);
1604 
1605 	kctx = SET_KCTX_LZ;
1606 
1607 	if (copyin(data, &event, sizeof (au_evclass_map_t)))
1608 		return (EFAULT);
1609 
1610 	if (event.ec_number < 0 || event.ec_number > (au_naevent - 1))
1611 		return (EINVAL);
1612 
1613 	kctx->auk_ets[event.ec_number] = event.ec_class;
1614 
1615 	return (0);
1616 }
1617 
1618 static int
1619 getpinfo(caddr_t data)
1620 {
1621 	STRUCT_DECL(auditpinfo, apinfo);
1622 	proc_t *proc;
1623 	const auditinfo_addr_t	*ainfo;
1624 	model_t	model;
1625 	cred_t	*cr, *newcred;
1626 
1627 	model = get_udatamodel();
1628 	STRUCT_INIT(apinfo, model);
1629 
1630 	if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo)))
1631 		return (EFAULT);
1632 
1633 	newcred = cralloc();
1634 
1635 	mutex_enter(&pidlock);
1636 	if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) {
1637 		mutex_exit(&pidlock);
1638 		crfree(newcred);
1639 		return (ESRCH);		/* no such process */
1640 	}
1641 	mutex_enter(&proc->p_lock);	/* so process doesn't go away */
1642 	mutex_exit(&pidlock);
1643 
1644 	audit_update_context(proc, newcred);	/* make sure it's up-to-date */
1645 
1646 	mutex_enter(&proc->p_crlock);
1647 	crhold(cr = proc->p_cred);
1648 	mutex_exit(&proc->p_crlock);
1649 	mutex_exit(&proc->p_lock);
1650 
1651 	ainfo = crgetauinfo(cr);
1652 	if (ainfo == NULL) {
1653 		crfree(cr);
1654 		return (EINVAL);
1655 	}
1656 
1657 	/* designated process has an ipv6 address? */
1658 	if (ainfo->ai_termid.at_type == AU_IPv6) {
1659 		crfree(cr);
1660 		return (EOVERFLOW);
1661 	}
1662 
1663 	STRUCT_FSET(apinfo, ap_auid, ainfo->ai_auid);
1664 	STRUCT_FSET(apinfo, ap_asid, ainfo->ai_asid);
1665 #ifdef _LP64
1666 	if (model == DATAMODEL_ILP32) {
1667 		dev32_t dev;
1668 		/* convert internal 64 bit form to 32 bit version */
1669 		if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
1670 			crfree(cr);
1671 			return (EOVERFLOW);
1672 		}
1673 		STRUCT_FSET(apinfo, ap_termid.port, dev);
1674 	} else
1675 		STRUCT_FSET(apinfo, ap_termid.port, ainfo->ai_termid.at_port);
1676 #else
1677 	STRUCT_FSET(apinfo, ap_termid.port, ainfo->ai_termid.at_port);
1678 #endif
1679 	STRUCT_FSET(apinfo, ap_termid.machine, ainfo->ai_termid.at_addr[0]);
1680 	STRUCT_FSET(apinfo, ap_mask, ainfo->ai_mask);
1681 
1682 	crfree(cr);
1683 
1684 	if (copyout(STRUCT_BUF(apinfo), data, STRUCT_SIZE(apinfo)))
1685 		return (EFAULT);
1686 
1687 	return (0);
1688 }
1689 
1690 static int
1691 getpinfo_addr(caddr_t data, int len)
1692 {
1693 	STRUCT_DECL(auditpinfo_addr, apinfo);
1694 	proc_t *proc;
1695 	const auditinfo_addr_t	*ainfo;
1696 	model_t	model;
1697 	cred_t	*cr, *newcred;
1698 
1699 	model = get_udatamodel();
1700 	STRUCT_INIT(apinfo, model);
1701 
1702 	if (len < STRUCT_SIZE(apinfo))
1703 		return (EOVERFLOW);
1704 
1705 	if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo)))
1706 		return (EFAULT);
1707 
1708 	newcred = cralloc();
1709 
1710 	mutex_enter(&pidlock);
1711 	if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) {
1712 		mutex_exit(&pidlock);
1713 		crfree(newcred);
1714 		return (ESRCH);
1715 	}
1716 	mutex_enter(&proc->p_lock);	/* so process doesn't go away */
1717 	mutex_exit(&pidlock);
1718 
1719 	audit_update_context(proc, newcred);	/* make sure it's up-to-date */
1720 
1721 	mutex_enter(&proc->p_crlock);
1722 	crhold(cr = proc->p_cred);
1723 	mutex_exit(&proc->p_crlock);
1724 	mutex_exit(&proc->p_lock);
1725 
1726 	ainfo = crgetauinfo(cr);
1727 	if (ainfo == NULL) {
1728 		crfree(cr);
1729 		return (EINVAL);
1730 	}
1731 
1732 	STRUCT_FSET(apinfo, ap_auid, ainfo->ai_auid);
1733 	STRUCT_FSET(apinfo, ap_asid, ainfo->ai_asid);
1734 #ifdef _LP64
1735 	if (model == DATAMODEL_ILP32) {
1736 		dev32_t dev;
1737 		/* convert internal 64 bit form to 32 bit version */
1738 		if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
1739 			crfree(cr);
1740 			return (EOVERFLOW);
1741 		}
1742 		STRUCT_FSET(apinfo, ap_termid.at_port, dev);
1743 	} else
1744 		STRUCT_FSET(apinfo, ap_termid.at_port,
1745 		    ainfo->ai_termid.at_port);
1746 #else
1747 	STRUCT_FSET(apinfo, ap_termid.at_port, ainfo->ai_termid.at_port);
1748 #endif
1749 	STRUCT_FSET(apinfo, ap_termid.at_type, ainfo->ai_termid.at_type);
1750 	STRUCT_FSET(apinfo, ap_termid.at_addr[0], ainfo->ai_termid.at_addr[0]);
1751 	STRUCT_FSET(apinfo, ap_termid.at_addr[1], ainfo->ai_termid.at_addr[1]);
1752 	STRUCT_FSET(apinfo, ap_termid.at_addr[2], ainfo->ai_termid.at_addr[2]);
1753 	STRUCT_FSET(apinfo, ap_termid.at_addr[3], ainfo->ai_termid.at_addr[3]);
1754 	STRUCT_FSET(apinfo, ap_mask, ainfo->ai_mask);
1755 
1756 	crfree(cr);
1757 
1758 	if (copyout(STRUCT_BUF(apinfo), data, STRUCT_SIZE(apinfo)))
1759 		return (EFAULT);
1760 
1761 	return (0);
1762 }
1763 
1764 static int
1765 setpmask(caddr_t data)
1766 {
1767 	STRUCT_DECL(auditpinfo, apinfo);
1768 	proc_t *proc;
1769 	cred_t	*newcred;
1770 	auditinfo_addr_t	*ainfo;
1771 	struct p_audit_data	*pad;
1772 
1773 	model_t	model;
1774 
1775 	model = get_udatamodel();
1776 	STRUCT_INIT(apinfo, model);
1777 
1778 	if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo)))
1779 		return (EFAULT);
1780 
1781 	mutex_enter(&pidlock);
1782 	if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) {
1783 		mutex_exit(&pidlock);
1784 		return (ESRCH);
1785 	}
1786 	mutex_enter(&proc->p_lock);	/* so process doesn't go away */
1787 	mutex_exit(&pidlock);
1788 
1789 	newcred = cralloc();
1790 	if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) {
1791 		mutex_exit(&proc->p_lock);
1792 		crfree(newcred);
1793 		return (EINVAL);
1794 	}
1795 
1796 	mutex_enter(&proc->p_crlock);
1797 	crcopy_to(proc->p_cred, newcred);
1798 	proc->p_cred = newcred;
1799 
1800 	ainfo->ai_mask = STRUCT_FGET(apinfo, ap_mask);
1801 
1802 	/*
1803 	 * Unlock. No need to broadcast changes via set_proc_pre_sys(),
1804 	 * since t_pre_sys is ALWAYS on when audit is enabled... due to
1805 	 * syscall auditing.
1806 	 */
1807 	crfree(newcred);
1808 	mutex_exit(&proc->p_crlock);
1809 
1810 	/* Reset flag for any previous pending mask change; this supercedes */
1811 	pad = P2A(proc);
1812 	ASSERT(pad != NULL);
1813 	mutex_enter(&(pad->pad_lock));
1814 	pad->pad_flags &= ~PAD_SETMASK;
1815 	mutex_exit(&(pad->pad_lock));
1816 
1817 	mutex_exit(&proc->p_lock);
1818 
1819 	return (0);
1820 }
1821 
1822 static int
1823 getfsize(caddr_t data)
1824 {
1825 	au_fstat_t fstat;
1826 	au_kcontext_t	*kctx = SET_KCTX_PZ;
1827 
1828 	mutex_enter(&(kctx->auk_fstat_lock));
1829 	fstat.af_filesz = kctx->auk_file_stat.af_filesz;
1830 	fstat.af_currsz = kctx->auk_file_stat.af_currsz;
1831 	mutex_exit(&(kctx->auk_fstat_lock));
1832 
1833 	if (copyout(&fstat, data, sizeof (au_fstat_t)))
1834 		return (EFAULT);
1835 
1836 	return (0);
1837 }
1838 
1839 static int
1840 setfsize(caddr_t data)
1841 {
1842 	au_fstat_t fstat;
1843 	au_kcontext_t	*kctx;
1844 
1845 	if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
1846 		return (EINVAL);
1847 
1848 	kctx = SET_KCTX_LZ;
1849 
1850 	if (copyin(data, &fstat, sizeof (au_fstat_t)))
1851 		return (EFAULT);
1852 
1853 	if ((fstat.af_filesz != 0) && (fstat.af_filesz < AU_MIN_FILE_SZ))
1854 		return (EINVAL);
1855 
1856 	mutex_enter(&(kctx->auk_fstat_lock));
1857 	kctx->auk_file_stat.af_filesz = fstat.af_filesz;
1858 	mutex_exit(&(kctx->auk_fstat_lock));
1859 
1860 	return (0);
1861 }
1862 /*
1863  * The out of control system call
1864  * This is audit kitchen sink aka auditadm, aka auditon
1865  */
1866 static int
1867 auditctl(
1868 	int	cmd,
1869 	caddr_t data,
1870 	int	length)
1871 {
1872 	int result;
1873 
1874 	if (!audit_active)
1875 		return (EINVAL);
1876 
1877 	switch (cmd) {
1878 	case A_GETCOND:
1879 	case A_GETCAR:
1880 	case A_GETCLASS:
1881 	case A_GETCWD:
1882 	case A_GETFSIZE:
1883 	case A_GETKAUDIT:
1884 	case A_GETKMASK:
1885 	case A_GETPINFO:
1886 	case A_GETPINFO_ADDR:
1887 	case A_GETPOLICY:
1888 	case A_GETQCTRL:
1889 	case A_GETSTAT:
1890 		if (secpolicy_audit_getattr(CRED()) != 0)
1891 			return (EPERM);
1892 		break;
1893 	default:
1894 		if (secpolicy_audit_config(CRED()) != 0)
1895 			return (EPERM);
1896 		break;
1897 	}
1898 
1899 	switch (cmd) {
1900 	case A_GETPOLICY:
1901 		result = getpolicy(data);
1902 		break;
1903 	case A_SETPOLICY:
1904 		result = setpolicy(data);
1905 		break;
1906 	case A_GETKMASK:
1907 		result = getkmask(data);
1908 		break;
1909 	case A_SETKMASK:
1910 		result = setkmask(data);
1911 		break;
1912 	case A_GETKAUDIT:
1913 		result = getkaudit(data, length);
1914 		break;
1915 	case A_SETKAUDIT:
1916 		result = setkaudit(data, length);
1917 		break;
1918 	case A_GETQCTRL:
1919 		result = getqctrl(data);
1920 		break;
1921 	case A_SETQCTRL:
1922 		result = setqctrl(data);
1923 		break;
1924 	case A_GETCWD:
1925 		result = getcwd(data, length);
1926 		break;
1927 	case A_GETCAR:
1928 		result = getcar(data, length);
1929 		break;
1930 	case A_GETSTAT:
1931 		result = getstat(data);
1932 		break;
1933 	case A_SETSTAT:
1934 		result = setstat(data);
1935 		break;
1936 	case A_SETUMASK:
1937 		result = setumask(data);
1938 		break;
1939 	case A_SETSMASK:
1940 		result = setsmask(data);
1941 		break;
1942 	case A_GETCOND:
1943 		result = getcond(data);
1944 		break;
1945 	case A_SETCOND:
1946 		result = setcond(data);
1947 		break;
1948 	case A_GETCLASS:
1949 		result = getclass(data);
1950 		break;
1951 	case A_SETCLASS:
1952 		result = setclass(data);
1953 		break;
1954 	case A_GETPINFO:
1955 		result = getpinfo(data);
1956 		break;
1957 	case A_GETPINFO_ADDR:
1958 		result = getpinfo_addr(data, length);
1959 		break;
1960 	case A_SETPMASK:
1961 		result = setpmask(data);
1962 		break;
1963 	case A_SETFSIZE:
1964 		result = setfsize(data);
1965 		break;
1966 	case A_GETFSIZE:
1967 		result = getfsize(data);
1968 		break;
1969 	default:
1970 		result = EINVAL;
1971 		break;
1972 	}
1973 	return (result);
1974 }
1975 
1976 /*
1977  * auditsvc was EOL'd effective Sol 10
1978  */
1979 static int
1980 auditsvc(int fd, int limit)
1981 {
1982 	struct file *fp;
1983 	struct vnode *vp;
1984 	int error = 0;
1985 	au_kcontext_t	*kctx;
1986 
1987 	if (secpolicy_audit_config(CRED()) != 0)
1988 		return (EPERM);
1989 
1990 	if (!INGLOBALZONE(curproc))
1991 		return (EINVAL);
1992 
1993 	kctx = SET_KCTX_GZ;
1994 
1995 	if (limit < 0 ||
1996 	    (!(kctx->auk_auditstate == AUC_AUDITING ||
1997 	    kctx->auk_auditstate == AUC_NOSPACE)))
1998 		return (EINVAL);
1999 
2000 	/*
2001 	 * Prevent a second audit daemon from running this code
2002 	 */
2003 	mutex_enter(&(kctx->auk_svc_lock));
2004 	if (kctx->auk_svc_busy) {
2005 		mutex_exit(&(kctx->auk_svc_lock));
2006 		return (EBUSY);
2007 	}
2008 	kctx->auk_svc_busy = 1;
2009 	mutex_exit(&(kctx->auk_svc_lock));
2010 
2011 	/*
2012 	 * convert file pointer to file descriptor
2013 	 *   Note: fd ref count incremented here.
2014 	 */
2015 	if ((fp = (struct file *)getf(fd)) == NULL) {
2016 		mutex_enter(&(kctx->auk_svc_lock));
2017 		kctx->auk_svc_busy = 0;
2018 		mutex_exit(&(kctx->auk_svc_lock));
2019 		return (EBADF);
2020 	}
2021 
2022 	vp = fp->f_vnode;
2023 
2024 	kctx->auk_file_stat.af_currsz = 0;
2025 
2026 	/*
2027 	 * Wait for work, until a signal arrives,
2028 	 * or until auditing is disabled.
2029 	 */
2030 	while (!error) {
2031 	    if (kctx->auk_auditstate == AUC_AUDITING) {
2032 		mutex_enter(&(kctx->auk_queue.lock));
2033 		    /* nothing on the audit queue */
2034 		while (kctx->auk_queue.head == NULL) {
2035 			/* safety check. kick writer awake */
2036 		    if (kctx->auk_queue.wt_block)
2037 			cv_broadcast(&(kctx->auk_queue.write_cv));
2038 			/* sleep waiting for things to to */
2039 		    kctx->auk_queue.rd_block = 1;
2040 		    AS_INC(as_rblocked, 1, kctx);
2041 		    if (!cv_wait_sig(&(kctx->auk_queue.read_cv),
2042 			&(kctx->auk_queue.lock))) {
2043 				/* interrupted system call */
2044 			kctx->auk_queue.rd_block = 0;
2045 			mutex_exit(&(kctx->auk_queue.lock));
2046 			error = ((kctx->auk_auditstate == AUC_AUDITING) ||
2047 			    (kctx->auk_auditstate == AUC_NOSPACE)) ?
2048 			    EINTR : EINVAL;
2049 			mutex_enter(&(kctx->auk_svc_lock));
2050 			kctx->auk_svc_busy = 0;
2051 			mutex_exit(&(kctx->auk_svc_lock));
2052 
2053 		/* decrement file descriptor reference count */
2054 			releasef(fd);
2055 			(void) timeout(audit_dont_stop, kctx, au_resid);
2056 			return (error);
2057 		    }
2058 		    kctx->auk_queue.rd_block = 0;
2059 		}
2060 		mutex_exit(&(kctx->auk_queue.lock));
2061 
2062 			/* do as much as we can */
2063 		error = au_doio(vp, limit);
2064 
2065 		/* if we ran out of space, be sure to fire off timeout */
2066 		if (error == ENOSPC)
2067 			(void) timeout(audit_dont_stop, kctx, au_resid);
2068 
2069 	    } else	/* auditing turned off while we slept */
2070 		    break;
2071 	}
2072 
2073 	/*
2074 	 * decrement file descriptor reference count
2075 	 */
2076 	releasef(fd);
2077 
2078 	/*
2079 	 * If auditing has been disabled quit processing
2080 	 */
2081 	if (!(kctx->auk_auditstate == AUC_AUDITING ||
2082 	    kctx->auk_auditstate == AUC_NOSPACE))
2083 		error = EINVAL;
2084 
2085 	mutex_enter(&(kctx->auk_svc_lock));
2086 	kctx->auk_svc_busy = 0;
2087 	mutex_exit(&(kctx->auk_svc_lock));
2088 
2089 	return (error);
2090 }
2091 
2092 static int
2093 audit_modsysent(char *modname, int flags, int (*func)())
2094 {
2095 	struct sysent *sysp;
2096 	int sysnum;
2097 	krwlock_t *kl;
2098 
2099 	if ((sysnum = mod_getsysnum(modname)) == -1) {
2100 		cmn_err(CE_WARN, "system call missing from bind file");
2101 		return (-1);
2102 	}
2103 
2104 	kl = (krwlock_t *)kobj_zalloc(sizeof (krwlock_t), KM_SLEEP);
2105 
2106 	sysp = &sysent[sysnum];
2107 	sysp->sy_narg = auditsysent.sy_narg;
2108 #ifdef _LP64
2109 	sysp->sy_flags = (unsigned short)flags;
2110 #else
2111 	sysp->sy_flags = (unsigned char)flags;
2112 #endif
2113 	sysp->sy_call = func;
2114 	sysp->sy_lock = kl;
2115 
2116 #ifdef _SYSCALL32_IMPL
2117 	sysp = &sysent32[sysnum];
2118 	sysp->sy_narg = auditsysent.sy_narg;
2119 	sysp->sy_flags = (unsigned short)flags;
2120 	sysp->sy_call = func;
2121 	sysp->sy_lock = kl;
2122 #endif
2123 
2124 	rw_init(sysp->sy_lock, NULL, RW_DEFAULT, NULL);
2125 
2126 	return (0);
2127 }
2128