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