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