audit_io.c revision 787b48eaa495c619f2cbed6175e0fead6a840516
d51e90740114c60620c0febffd4d3ce6e280a107ab/*
d51e90740114c60620c0febffd4d3ce6e280a107ab * CDDL HEADER START
d51e90740114c60620c0febffd4d3ce6e280a107ab *
d51e90740114c60620c0febffd4d3ce6e280a107ab * The contents of this file are subject to the terms of the
d51e90740114c60620c0febffd4d3ce6e280a107ab * Common Development and Distribution License (the "License").
d51e90740114c60620c0febffd4d3ce6e280a107ab * You may not use this file except in compliance with the License.
d51e90740114c60620c0febffd4d3ce6e280a107ab *
d51e90740114c60620c0febffd4d3ce6e280a107ab * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
d51e90740114c60620c0febffd4d3ce6e280a107ab * or http://www.opensolaris.org/os/licensing.
d51e90740114c60620c0febffd4d3ce6e280a107ab * See the License for the specific language governing permissions
d51e90740114c60620c0febffd4d3ce6e280a107ab * and limitations under the License.
d51e90740114c60620c0febffd4d3ce6e280a107ab *
d51e90740114c60620c0febffd4d3ce6e280a107ab * When distributing Covered Code, include this CDDL HEADER in each
d51e90740114c60620c0febffd4d3ce6e280a107ab * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
d51e90740114c60620c0febffd4d3ce6e280a107ab * If applicable, add the following below this CDDL HEADER, with the
d51e90740114c60620c0febffd4d3ce6e280a107ab * fields enclosed by brackets "[]" replaced with your own identifying
d51e90740114c60620c0febffd4d3ce6e280a107ab * information: Portions Copyright [yyyy] [name of copyright owner]
d51e90740114c60620c0febffd4d3ce6e280a107ab *
d51e90740114c60620c0febffd4d3ce6e280a107ab * CDDL HEADER END
d51e90740114c60620c0febffd4d3ce6e280a107ab */
d51e90740114c60620c0febffd4d3ce6e280a107ab/*
d51e90740114c60620c0febffd4d3ce6e280a107ab * Routines for writing audit records.
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz *
d51e90740114c60620c0febffd4d3ce6e280a107ab * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
d51e90740114c60620c0febffd4d3ce6e280a107ab * Use is subject to license terms.
d51e90740114c60620c0febffd4d3ce6e280a107ab */
beee6fc0eea41662170c4dea38a7e5605ab59507Bryan Cantrill
beee6fc0eea41662170c4dea38a7e5605ab59507Bryan Cantrill#pragma ident "%Z%%M% %I% %E% SMI"
beee6fc0eea41662170c4dea38a7e5605ab59507Bryan Cantrill
beee6fc0eea41662170c4dea38a7e5605ab59507Bryan Cantrill#include <sys/door.h>
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz#include <sys/param.h>
d51e90740114c60620c0febffd4d3ce6e280a107ab#include <sys/time.h>
d51e90740114c60620c0febffd4d3ce6e280a107ab#include <sys/types.h>
d51e90740114c60620c0febffd4d3ce6e280a107ab#include <sys/statvfs.h> /* for statfs */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz#include <sys/vnode.h>
d51e90740114c60620c0febffd4d3ce6e280a107ab#include <sys/file.h>
d51e90740114c60620c0febffd4d3ce6e280a107ab#include <sys/vfs.h>
d51e90740114c60620c0febffd4d3ce6e280a107ab#include <sys/user.h>
d51e90740114c60620c0febffd4d3ce6e280a107ab#include <sys/uio.h>
d51e90740114c60620c0febffd4d3ce6e280a107ab#include <sys/reboot.h>
d51e90740114c60620c0febffd4d3ce6e280a107ab#include <sys/kmem.h> /* for KM_SLEEP */
d51e90740114c60620c0febffd4d3ce6e280a107ab#include <sys/resource.h> /* for RLIM_INFINITY */
d51e90740114c60620c0febffd4d3ce6e280a107ab#include <sys/cmn_err.h> /* panic */
d51e90740114c60620c0febffd4d3ce6e280a107ab#include <sys/systm.h>
d51e90740114c60620c0febffd4d3ce6e280a107ab#include <sys/debug.h>
d51e90740114c60620c0febffd4d3ce6e280a107ab#include <sys/sysmacros.h>
d51e90740114c60620c0febffd4d3ce6e280a107ab#include <sys/syscall.h>
d51e90740114c60620c0febffd4d3ce6e280a107ab#include <sys/zone.h>
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab#include <c2/audit.h>
d51e90740114c60620c0febffd4d3ce6e280a107ab#include <c2/audit_kernel.h>
d51e90740114c60620c0febffd4d3ce6e280a107ab#include <c2/audit_record.h>
d51e90740114c60620c0febffd4d3ce6e280a107ab#include <c2/audit_kevents.h>
d51e90740114c60620c0febffd4d3ce6e280a107ab#include <c2/audit_door_infc.h>
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107abstatic void au_dequeue(au_kcontext_t *, au_buff_t *);
d51e90740114c60620c0febffd4d3ce6e280a107abstatic void audit_async_finish_backend(void *);
d51e90740114c60620c0febffd4d3ce6e280a107abstatic int audit_sync_block(au_kcontext_t *);
d51e90740114c60620c0febffd4d3ce6e280a107ab/*
d51e90740114c60620c0febffd4d3ce6e280a107ab * each of these two tables are indexed by the values AU_DBUF_COMPLETE
d51e90740114c60620c0febffd4d3ce6e280a107ab * through AU_DBUF_LAST; the content is the next state value. The
d51e90740114c60620c0febffd4d3ce6e280a107ab * first table determines the next state for a buffer which is not the
d51e90740114c60620c0febffd4d3ce6e280a107ab * end of a record and the second table determines the state for a
d51e90740114c60620c0febffd4d3ce6e280a107ab * buffer which is the end of a record. The initial state is
d51e90740114c60620c0febffd4d3ce6e280a107ab * AU_DBUF_COMPLETE.
d51e90740114c60620c0febffd4d3ce6e280a107ab */
d51e90740114c60620c0febffd4d3ce6e280a107abstatic int state_if_part[] = {
d51e90740114c60620c0febffd4d3ce6e280a107ab AU_DBUF_FIRST, AU_DBUF_MIDDLE, AU_DBUF_MIDDLE, AU_DBUF_FIRST};
d51e90740114c60620c0febffd4d3ce6e280a107abstatic int state_if_not_part[] = {
d51e90740114c60620c0febffd4d3ce6e280a107ab AU_DBUF_COMPLETE, AU_DBUF_LAST, AU_DBUF_LAST, AU_DBUF_COMPLETE};
d51e90740114c60620c0febffd4d3ce6e280a107ab/*
d51e90740114c60620c0febffd4d3ce6e280a107ab * Write to an audit descriptor.
d51e90740114c60620c0febffd4d3ce6e280a107ab * Add the au_membuf to the descriptor chain and free the chain passed in.
d51e90740114c60620c0febffd4d3ce6e280a107ab */
d51e90740114c60620c0febffd4d3ce6e280a107abvoid
d51e90740114c60620c0febffd4d3ce6e280a107abau_uwrite(m)
d51e90740114c60620c0febffd4d3ce6e280a107ab token_t *m;
d51e90740114c60620c0febffd4d3ce6e280a107ab{
d51e90740114c60620c0febffd4d3ce6e280a107ab au_write(&(u_ad), m);
d51e90740114c60620c0febffd4d3ce6e280a107ab}
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107abvoid
d51e90740114c60620c0febffd4d3ce6e280a107abau_write(caddr_t *d, token_t *m)
d51e90740114c60620c0febffd4d3ce6e280a107ab{
d51e90740114c60620c0febffd4d3ce6e280a107ab if (d == NULL) {
d51e90740114c60620c0febffd4d3ce6e280a107ab au_toss_token(m);
d51e90740114c60620c0febffd4d3ce6e280a107ab return;
d51e90740114c60620c0febffd4d3ce6e280a107ab }
d51e90740114c60620c0febffd4d3ce6e280a107ab if (m == (token_t *)0) {
d51e90740114c60620c0febffd4d3ce6e280a107ab printf("au_write: null token\n");
d51e90740114c60620c0febffd4d3ce6e280a107ab return;
d51e90740114c60620c0febffd4d3ce6e280a107ab }
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab if (*d == NULL)
d51e90740114c60620c0febffd4d3ce6e280a107ab *d = (caddr_t)m;
d51e90740114c60620c0febffd4d3ce6e280a107ab else
d51e90740114c60620c0febffd4d3ce6e280a107ab (void) au_append_rec((au_buff_t *)*d, m, AU_PACK);
d51e90740114c60620c0febffd4d3ce6e280a107ab}
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab/*
d51e90740114c60620c0febffd4d3ce6e280a107ab * Close an audit descriptor.
d51e90740114c60620c0febffd4d3ce6e280a107ab * Use the second parameter to indicate if it should be written or not.
d51e90740114c60620c0febffd4d3ce6e280a107ab */
d51e90740114c60620c0febffd4d3ce6e280a107abvoid
d51e90740114c60620c0febffd4d3ce6e280a107abau_close(au_kcontext_t *kctx, caddr_t *d, int flag, short e_type, short e_mod)
d51e90740114c60620c0febffd4d3ce6e280a107ab{
d51e90740114c60620c0febffd4d3ce6e280a107ab token_t *dchain; /* au_membuf chain which is the tokens */
d51e90740114c60620c0febffd4d3ce6e280a107ab t_audit_data_t *tad = U2A(u);
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab ASSERT(tad != NULL);
d51e90740114c60620c0febffd4d3ce6e280a107ab ASSERT(d != NULL);
d51e90740114c60620c0febffd4d3ce6e280a107ab ASSERT(kctx != NULL);
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab if ((dchain = (token_t *)*d) == (token_t *)NULL)
d51e90740114c60620c0febffd4d3ce6e280a107ab return;
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab *d = NULL;
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab /*
d51e90740114c60620c0febffd4d3ce6e280a107ab * If async then defer; or if requested, defer the closing/queueing to
d51e90740114c60620c0febffd4d3ce6e280a107ab * syscall end, unless no syscall is active or the syscall is _exit.
d51e90740114c60620c0febffd4d3ce6e280a107ab */
d51e90740114c60620c0febffd4d3ce6e280a107ab if ((flag & AU_DONTBLOCK) || ((flag & AU_DEFER) &&
d51e90740114c60620c0febffd4d3ce6e280a107ab (tad->tad_scid != 0) && (tad->tad_scid != SYS_exit))) {
d51e90740114c60620c0febffd4d3ce6e280a107ab au_close_defer(dchain, flag, e_type, e_mod);
d51e90740114c60620c0febffd4d3ce6e280a107ab return;
d51e90740114c60620c0febffd4d3ce6e280a107ab }
d51e90740114c60620c0febffd4d3ce6e280a107ab au_close_time(kctx, dchain, flag, e_type, e_mod, NULL);
d51e90740114c60620c0febffd4d3ce6e280a107ab}
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab/*
d51e90740114c60620c0febffd4d3ce6e280a107ab * Defer closing/queueing of an audit descriptor. For async events, queue
d51e90740114c60620c0febffd4d3ce6e280a107ab * via softcall. Otherwise, defer by queueing the record onto the tad; at
d51e90740114c60620c0febffd4d3ce6e280a107ab * syscall end time it will be pulled off.
d51e90740114c60620c0febffd4d3ce6e280a107ab */
d51e90740114c60620c0febffd4d3ce6e280a107abvoid
d51e90740114c60620c0febffd4d3ce6e280a107abau_close_defer(token_t *dchain, int flag, short e_type, short e_mod)
d51e90740114c60620c0febffd4d3ce6e280a107ab{
d51e90740114c60620c0febffd4d3ce6e280a107ab au_defer_info_t *attr;
d51e90740114c60620c0febffd4d3ce6e280a107ab t_audit_data_t *tad = U2A(u);
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab ASSERT(tad != NULL);
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab /* If not to be written, toss the record. */
d51e90740114c60620c0febffd4d3ce6e280a107ab if ((flag & AU_OK) == 0) {
d51e90740114c60620c0febffd4d3ce6e280a107ab au_toss_token(dchain);
d51e90740114c60620c0febffd4d3ce6e280a107ab return;
d51e90740114c60620c0febffd4d3ce6e280a107ab }
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab attr = kmem_alloc(sizeof (au_defer_info_t), KM_NOSLEEP);
d51e90740114c60620c0febffd4d3ce6e280a107ab /* If no mem available, failing silently is the best recourse */
d51e90740114c60620c0febffd4d3ce6e280a107ab if (attr == NULL) {
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz au_toss_token(dchain);
d51e90740114c60620c0febffd4d3ce6e280a107ab return;
d51e90740114c60620c0febffd4d3ce6e280a107ab }
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab attr->audi_next = NULL;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz attr->audi_ad = dchain;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz attr->audi_e_type = e_type;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz attr->audi_e_mod = e_mod;
d51e90740114c60620c0febffd4d3ce6e280a107ab attr->audi_flag = flag;
d51e90740114c60620c0febffd4d3ce6e280a107ab gethrestime(&attr->audi_atime);
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab /*
d51e90740114c60620c0febffd4d3ce6e280a107ab * All async events must be queued via softcall to avoid possible
d51e90740114c60620c0febffd4d3ce6e280a107ab * sleeping in high interrupt context. softcall will ensure it's
d51e90740114c60620c0febffd4d3ce6e280a107ab * done on a dedicated software-level interrupt thread.
d51e90740114c60620c0febffd4d3ce6e280a107ab */
d51e90740114c60620c0febffd4d3ce6e280a107ab if (flag & AU_DONTBLOCK) {
d51e90740114c60620c0febffd4d3ce6e280a107ab softcall(audit_async_finish_backend, attr);
d51e90740114c60620c0febffd4d3ce6e280a107ab audit_async_done(NULL, 0);
d51e90740114c60620c0febffd4d3ce6e280a107ab return;
d51e90740114c60620c0febffd4d3ce6e280a107ab }
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab /*
d51e90740114c60620c0febffd4d3ce6e280a107ab * If not an async event, defer by queuing onto the tad until
d51e90740114c60620c0febffd4d3ce6e280a107ab * syscall end. No locking is needed because the tad is per-thread.
d51e90740114c60620c0febffd4d3ce6e280a107ab */
d51e90740114c60620c0febffd4d3ce6e280a107ab if (tad->tad_defer_head)
d51e90740114c60620c0febffd4d3ce6e280a107ab tad->tad_defer_tail->audi_next = attr;
d51e90740114c60620c0febffd4d3ce6e280a107ab else
d51e90740114c60620c0febffd4d3ce6e280a107ab tad->tad_defer_head = attr;
d51e90740114c60620c0febffd4d3ce6e280a107ab tad->tad_defer_tail = attr;
d51e90740114c60620c0febffd4d3ce6e280a107ab}
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab/*
d51e90740114c60620c0febffd4d3ce6e280a107ab * Save the time in the event header. If time is not specified (i.e., pointer
d51e90740114c60620c0febffd4d3ce6e280a107ab * is NULL), use the current time. This code is fairly ugly since it needs
d51e90740114c60620c0febffd4d3ce6e280a107ab * to support both 32- and 64-bit environments and can be called indirectly
d51e90740114c60620c0febffd4d3ce6e280a107ab * from both au_close() (for kernel audit) and from audit() (userland audit).
d51e90740114c60620c0febffd4d3ce6e280a107ab */
b93b7f88faf1df7e4a0046bc3fa6f74516688d16jj/*ARGSUSED*/
b93b7f88faf1df7e4a0046bc3fa6f74516688d16jjstatic void
b93b7f88faf1df7e4a0046bc3fa6f74516688d16jjau_save_time(adr_t *hadrp, timestruc_t *time, int size)
b93b7f88faf1df7e4a0046bc3fa6f74516688d16jj{
b93b7f88faf1df7e4a0046bc3fa6f74516688d16jj struct {
b93b7f88faf1df7e4a0046bc3fa6f74516688d16jj uint32_t sec;
b93b7f88faf1df7e4a0046bc3fa6f74516688d16jj uint32_t usec;
b93b7f88faf1df7e4a0046bc3fa6f74516688d16jj } tv;
b93b7f88faf1df7e4a0046bc3fa6f74516688d16jj timestruc_t now;
b93b7f88faf1df7e4a0046bc3fa6f74516688d16jj
b93b7f88faf1df7e4a0046bc3fa6f74516688d16jj if (time == NULL) {
b93b7f88faf1df7e4a0046bc3fa6f74516688d16jj gethrestime(&now);
b93b7f88faf1df7e4a0046bc3fa6f74516688d16jj time = &now;
b93b7f88faf1df7e4a0046bc3fa6f74516688d16jj }
b93b7f88faf1df7e4a0046bc3fa6f74516688d16jj
b93b7f88faf1df7e4a0046bc3fa6f74516688d16jj#ifdef _LP64
b93b7f88faf1df7e4a0046bc3fa6f74516688d16jj if (size)
b93b7f88faf1df7e4a0046bc3fa6f74516688d16jj adr_int64(hadrp, (int64_t *)time, 2);
b93b7f88faf1df7e4a0046bc3fa6f74516688d16jj else
d51e90740114c60620c0febffd4d3ce6e280a107ab#endif
d51e90740114c60620c0febffd4d3ce6e280a107ab {
d51e90740114c60620c0febffd4d3ce6e280a107ab tv.sec = (uint32_t)time->tv_sec;
d51e90740114c60620c0febffd4d3ce6e280a107ab tv.usec = (uint32_t)time->tv_nsec;
d51e90740114c60620c0febffd4d3ce6e280a107ab adr_int32(hadrp, (int32_t *)&tv, 2);
d51e90740114c60620c0febffd4d3ce6e280a107ab }
d51e90740114c60620c0febffd4d3ce6e280a107ab}
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab/*
d51e90740114c60620c0febffd4d3ce6e280a107ab * Close an audit descriptor.
d51e90740114c60620c0febffd4d3ce6e280a107ab * If time of event is specified, use it in the record, otherwise use the
d51e90740114c60620c0febffd4d3ce6e280a107ab * current time.
d51e90740114c60620c0febffd4d3ce6e280a107ab */
d51e90740114c60620c0febffd4d3ce6e280a107abvoid
d51e90740114c60620c0febffd4d3ce6e280a107abau_close_time(au_kcontext_t *kctx, token_t *dchain, int flag, short e_type,
d51e90740114c60620c0febffd4d3ce6e280a107ab short e_mod, timestruc_t *etime)
d51e90740114c60620c0febffd4d3ce6e280a107ab{
d51e90740114c60620c0febffd4d3ce6e280a107ab token_t *record; /* au_membuf chain == the record */
d51e90740114c60620c0febffd4d3ce6e280a107ab int byte_count;
d51e90740114c60620c0febffd4d3ce6e280a107ab token_t *m; /* for potential sequence token */
d51e90740114c60620c0febffd4d3ce6e280a107ab adr_t hadr; /* handle for header token */
d51e90740114c60620c0febffd4d3ce6e280a107ab adr_t sadr; /* handle for sequence token */
d51e90740114c60620c0febffd4d3ce6e280a107ab size_t zone_length; /* length of zonename token */
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab ASSERT(dchain != NULL);
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab /* If not to be written, toss the record */
d51e90740114c60620c0febffd4d3ce6e280a107ab if ((flag & AU_OK) == 0) {
d51e90740114c60620c0febffd4d3ce6e280a107ab au_toss_token(dchain);
d51e90740114c60620c0febffd4d3ce6e280a107ab return;
d51e90740114c60620c0febffd4d3ce6e280a107ab }
d51e90740114c60620c0febffd4d3ce6e280a107ab /* if auditing not enabled, then don't generate an audit record */
d51e90740114c60620c0febffd4d3ce6e280a107ab ASSERT(kctx != NULL);
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab if ((kctx->auk_auditstate != AUC_AUDITING) &&
d51e90740114c60620c0febffd4d3ce6e280a107ab (kctx->auk_auditstate != AUC_INIT_AUDIT)) {
d51e90740114c60620c0febffd4d3ce6e280a107ab /*
d51e90740114c60620c0febffd4d3ce6e280a107ab * at system boot, neither is set yet we want to generate
d51e90740114c60620c0febffd4d3ce6e280a107ab * an audit record.
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz */
d51e90740114c60620c0febffd4d3ce6e280a107ab if (e_type != AUE_SYSTEMBOOT) {
d51e90740114c60620c0febffd4d3ce6e280a107ab au_toss_token(dchain);
d51e90740114c60620c0febffd4d3ce6e280a107ab return;
7199059354284218c1c31276b0a51935fb228cc2Richard Lowe }
d51e90740114c60620c0febffd4d3ce6e280a107ab }
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab /* Count up the bytes used in the record. */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz byte_count = au_token_size(dchain);
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz /*
d51e90740114c60620c0febffd4d3ce6e280a107ab * add in size of header token (always present).
d51e90740114c60620c0febffd4d3ce6e280a107ab */
d51e90740114c60620c0febffd4d3ce6e280a107ab byte_count += sizeof (char) + sizeof (int32_t) +
d51e90740114c60620c0febffd4d3ce6e280a107ab sizeof (char) + 2 * sizeof (short) + sizeof (timestruc_t);
22872efb9462b28180d11ea401344608e641a5aaedp
22872efb9462b28180d11ea401344608e641a5aaedp if (kctx->auk_hostaddr_valid)
22872efb9462b28180d11ea401344608e641a5aaedp byte_count += sizeof (int32_t) +
22872efb9462b28180d11ea401344608e641a5aaedp kctx->auk_info.ai_termid.at_type;
22872efb9462b28180d11ea401344608e641a5aaedp
22872efb9462b28180d11ea401344608e641a5aaedp /*
22872efb9462b28180d11ea401344608e641a5aaedp * add in size of zonename token (zero if !AUDIT_ZONENAME)
22872efb9462b28180d11ea401344608e641a5aaedp */
22872efb9462b28180d11ea401344608e641a5aaedp if (kctx->auk_policy & AUDIT_ZONENAME) {
d51e90740114c60620c0febffd4d3ce6e280a107ab zone_length = au_zonename_length(NULL);
d51e90740114c60620c0febffd4d3ce6e280a107ab byte_count += zone_length;
d51e90740114c60620c0febffd4d3ce6e280a107ab } else {
d51e90740114c60620c0febffd4d3ce6e280a107ab zone_length = 0;
d51e90740114c60620c0febffd4d3ce6e280a107ab }
d51e90740114c60620c0febffd4d3ce6e280a107ab /* add in size of (optional) trailer token */
d51e90740114c60620c0febffd4d3ce6e280a107ab if (kctx->auk_policy & AUDIT_TRAIL)
d51e90740114c60620c0febffd4d3ce6e280a107ab byte_count += 7;
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab /* add in size of (optional) sequence token */
d51e90740114c60620c0febffd4d3ce6e280a107ab if (kctx->auk_policy & AUDIT_SEQ)
d51e90740114c60620c0febffd4d3ce6e280a107ab byte_count += 5;
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab /* build the header */
d51e90740114c60620c0febffd4d3ce6e280a107ab if (kctx->auk_hostaddr_valid)
d51e90740114c60620c0febffd4d3ce6e280a107ab record = au_to_header_ex(byte_count, e_type, e_mod);
d51e90740114c60620c0febffd4d3ce6e280a107ab else
d51e90740114c60620c0febffd4d3ce6e280a107ab record = au_to_header(byte_count, e_type, e_mod);
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab /*
d51e90740114c60620c0febffd4d3ce6e280a107ab * If timestamp was specified, save it in header now. Otherwise,
d51e90740114c60620c0febffd4d3ce6e280a107ab * save reference to header so we can update time/data later
d51e90740114c60620c0febffd4d3ce6e280a107ab * and artificially adjust pointer to the time/date field of header.
d51e90740114c60620c0febffd4d3ce6e280a107ab */
d51e90740114c60620c0febffd4d3ce6e280a107ab adr_start(&hadr, memtod(record, char *));
d51e90740114c60620c0febffd4d3ce6e280a107ab hadr.adr_now += sizeof (char) + sizeof (int32_t) +
d51e90740114c60620c0febffd4d3ce6e280a107ab sizeof (char) + 2 * sizeof (short);
d51e90740114c60620c0febffd4d3ce6e280a107ab if (kctx->auk_hostaddr_valid)
d51e90740114c60620c0febffd4d3ce6e280a107ab hadr.adr_now += sizeof (int32_t) +
d51e90740114c60620c0febffd4d3ce6e280a107ab kctx->auk_info.ai_termid.at_type;
d51e90740114c60620c0febffd4d3ce6e280a107ab if (etime != NULL) {
d51e90740114c60620c0febffd4d3ce6e280a107ab au_save_time(&hadr, etime, 1);
d51e90740114c60620c0febffd4d3ce6e280a107ab hadr.adr_now = (char *)NULL;
d51e90740114c60620c0febffd4d3ce6e280a107ab }
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab /* append body of audit record */
d51e90740114c60620c0febffd4d3ce6e280a107ab (void) au_append_rec(record, dchain, AU_PACK);
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab /* add (optional) zonename token */
d51e90740114c60620c0febffd4d3ce6e280a107ab if (zone_length > 0) {
d51e90740114c60620c0febffd4d3ce6e280a107ab m = au_to_zonename(zone_length, NULL);
d51e90740114c60620c0febffd4d3ce6e280a107ab (void) au_append_rec(record, m, AU_PACK);
d51e90740114c60620c0febffd4d3ce6e280a107ab }
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab /* Add an (optional) sequence token. NULL offset if none */
d51e90740114c60620c0febffd4d3ce6e280a107ab if (kctx->auk_policy & AUDIT_SEQ) {
d51e90740114c60620c0febffd4d3ce6e280a107ab /* get the sequence token */
d51e90740114c60620c0febffd4d3ce6e280a107ab m = au_to_seq();
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab /* link to audit record (i.e. don't pack the data) */
d51e90740114c60620c0febffd4d3ce6e280a107ab (void) au_append_rec(record, m, AU_LINK);
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab /*
d51e90740114c60620c0febffd4d3ce6e280a107ab * advance to count field of sequence token by skipping
d51e90740114c60620c0febffd4d3ce6e280a107ab * the token type byte.
d51e90740114c60620c0febffd4d3ce6e280a107ab */
d51e90740114c60620c0febffd4d3ce6e280a107ab adr_start(&sadr, memtod(m, char *));
d51e90740114c60620c0febffd4d3ce6e280a107ab sadr.adr_now += 1;
d51e90740114c60620c0febffd4d3ce6e280a107ab } else {
d51e90740114c60620c0febffd4d3ce6e280a107ab sadr.adr_now = NULL;
d51e90740114c60620c0febffd4d3ce6e280a107ab }
d51e90740114c60620c0febffd4d3ce6e280a107ab /* add (optional) trailer token */
d51e90740114c60620c0febffd4d3ce6e280a107ab if (kctx->auk_policy & AUDIT_TRAIL) {
d51e90740114c60620c0febffd4d3ce6e280a107ab (void) au_append_rec(record, au_to_trailer(byte_count),
d51e90740114c60620c0febffd4d3ce6e280a107ab AU_PACK);
d51e90740114c60620c0febffd4d3ce6e280a107ab }
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab /*
d51e90740114c60620c0febffd4d3ce6e280a107ab * 1 - use 64 bit version of audit tokens for 64 bit kernels.
d51e90740114c60620c0febffd4d3ce6e280a107ab * 0 - use 32 bit version of audit tokens for 32 bit kernels.
d51e90740114c60620c0febffd4d3ce6e280a107ab */
d51e90740114c60620c0febffd4d3ce6e280a107ab#ifdef _LP64
d51e90740114c60620c0febffd4d3ce6e280a107ab au_enqueue(kctx, record, &hadr, &sadr, 1, flag & AU_DONTBLOCK);
d51e90740114c60620c0febffd4d3ce6e280a107ab#else
d51e90740114c60620c0febffd4d3ce6e280a107ab au_enqueue(kctx, record, &hadr, &sadr, 0, flag & AU_DONTBLOCK);
d51e90740114c60620c0febffd4d3ce6e280a107ab#endif
d51e90740114c60620c0febffd4d3ce6e280a107ab AS_INC(as_totalsize, byte_count, kctx);
d51e90740114c60620c0febffd4d3ce6e280a107ab}
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab/*ARGSUSED*/
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowiczvoid
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowiczau_enqueue(au_kcontext_t *kctx, au_buff_t *m, adr_t *hadrp, adr_t *sadrp,
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz int size, int dontblock)
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz{
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz if (kctx == NULL)
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz return;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz mutex_enter(&(kctx->auk_queue.lock));
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz if (!dontblock && (kctx->auk_queue.cnt >= kctx->auk_queue.hiwater) &&
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz audit_sync_block(kctx)) {
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz mutex_exit(&(kctx->auk_queue.lock));
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz au_free_rec(m);
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz return;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz }
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz /* Fill in date and time if needed */
de1f518f033a642fe7aa3c2b59429241a01e387fRichard Lowe if (hadrp->adr_now) {
de1f518f033a642fe7aa3c2b59429241a01e387fRichard Lowe au_save_time(hadrp, NULL, size);
de1f518f033a642fe7aa3c2b59429241a01e387fRichard Lowe }
de1f518f033a642fe7aa3c2b59429241a01e387fRichard Lowe
de1f518f033a642fe7aa3c2b59429241a01e387fRichard Lowe /* address will be non-zero only if AUDIT_SEQ set */
d51e90740114c60620c0febffd4d3ce6e280a107ab if (sadrp->adr_now) {
d51e90740114c60620c0febffd4d3ce6e280a107ab kctx->auk_sequence++;
d51e90740114c60620c0febffd4d3ce6e280a107ab adr_int32(sadrp, (int32_t *)&(kctx->auk_sequence), 1);
d51e90740114c60620c0febffd4d3ce6e280a107ab }
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab if (kctx->auk_queue.head)
d51e90740114c60620c0febffd4d3ce6e280a107ab kctx->auk_queue.tail->next_rec = m;
d51e90740114c60620c0febffd4d3ce6e280a107ab else
d51e90740114c60620c0febffd4d3ce6e280a107ab kctx->auk_queue.head = m;
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab kctx->auk_queue.tail = m;
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab if (++(kctx->auk_queue.cnt) >
d51e90740114c60620c0febffd4d3ce6e280a107ab kctx->auk_queue.lowater && kctx->auk_queue.rd_block)
d51e90740114c60620c0febffd4d3ce6e280a107ab cv_broadcast(&(kctx->auk_queue.read_cv));
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz
d51e90740114c60620c0febffd4d3ce6e280a107ab mutex_exit(&(kctx->auk_queue.lock));
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab /* count # audit records put onto kernel audit queue */
d51e90740114c60620c0febffd4d3ce6e280a107ab AS_INC(as_enqueue, 1, kctx);
d51e90740114c60620c0febffd4d3ce6e280a107ab}
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab/*
d51e90740114c60620c0febffd4d3ce6e280a107ab * Dequeue and free buffers upto and including "freeto"
d51e90740114c60620c0febffd4d3ce6e280a107ab * Keeps the queue lock long but acquires it only once when doing
d51e90740114c60620c0febffd4d3ce6e280a107ab * bulk dequeueing.
d51e90740114c60620c0febffd4d3ce6e280a107ab */
d51e90740114c60620c0febffd4d3ce6e280a107abstatic void
d51e90740114c60620c0febffd4d3ce6e280a107abau_dequeue(au_kcontext_t *kctx, au_buff_t *freeto)
d51e90740114c60620c0febffd4d3ce6e280a107ab{
d51e90740114c60620c0febffd4d3ce6e280a107ab au_buff_t *m, *l, *lastl;
d51e90740114c60620c0febffd4d3ce6e280a107ab int n = 0;
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab ASSERT(kctx != NULL);
d51e90740114c60620c0febffd4d3ce6e280a107ab
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz mutex_enter(&(kctx->auk_queue.lock));
d51e90740114c60620c0febffd4d3ce6e280a107ab
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz ASSERT(kctx->auk_queue.head != NULL);
d51e90740114c60620c0febffd4d3ce6e280a107ab ASSERT(freeto != NULL);
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz l = m = kctx->auk_queue.head;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz do {
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz n++;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz lastl = l;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz l = l->next_rec;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz } while (l != NULL && freeto != lastl);
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab kctx->auk_queue.cnt -= n;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz lastl->next_rec = NULL;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz kctx->auk_queue.head = l;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz /* Freeto must exist in the list */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz ASSERT(freeto == lastl);
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz if (kctx->auk_queue.cnt <= kctx->auk_queue.lowater &&
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz kctx->auk_queue.wt_block)
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz cv_broadcast(&(kctx->auk_queue.write_cv));
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz mutex_exit(&(kctx->auk_queue.lock));
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz while (m) {
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz l = m->next_rec;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz au_free_rec(m);
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz m = l;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz }
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz AS_INC(as_written, n, kctx);
d51e90740114c60620c0febffd4d3ce6e280a107ab}
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab/*
d51e90740114c60620c0febffd4d3ce6e280a107ab * audit_sync_block()
b93b7f88faf1df7e4a0046bc3fa6f74516688d16jj * If we've reached the high water mark, we look at the policy to see
d51e90740114c60620c0febffd4d3ce6e280a107ab * if we sleep or we should drop the audit record.
d51e90740114c60620c0febffd4d3ce6e280a107ab * This function is called with the auk_queue.lock held and the check
d51e90740114c60620c0febffd4d3ce6e280a107ab * performed one time already as an optimization. Caller should unlock.
d51e90740114c60620c0febffd4d3ce6e280a107ab * Returns 1 if the caller needs to free the record.
d51e90740114c60620c0febffd4d3ce6e280a107ab */
d51e90740114c60620c0febffd4d3ce6e280a107abstatic int
d51e90740114c60620c0febffd4d3ce6e280a107abaudit_sync_block(au_kcontext_t *kctx)
d51e90740114c60620c0febffd4d3ce6e280a107ab{
d51e90740114c60620c0febffd4d3ce6e280a107ab ASSERT(MUTEX_HELD(&(kctx->auk_queue.lock)));
d51e90740114c60620c0febffd4d3ce6e280a107ab /*
d51e90740114c60620c0febffd4d3ce6e280a107ab * Loop while we are at the high watermark.
d51e90740114c60620c0febffd4d3ce6e280a107ab */
d51e90740114c60620c0febffd4d3ce6e280a107ab do {
d51e90740114c60620c0febffd4d3ce6e280a107ab if ((kctx->auk_auditstate != AUC_AUDITING) ||
d51e90740114c60620c0febffd4d3ce6e280a107ab (kctx->auk_policy & AUDIT_CNT)) {
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab /* just count # of dropped audit records */
d51e90740114c60620c0febffd4d3ce6e280a107ab AS_INC(as_dropped, 1, kctx);
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab return (1);
d51e90740114c60620c0febffd4d3ce6e280a107ab }
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab /* kick reader awake if its asleep */
d51e90740114c60620c0febffd4d3ce6e280a107ab if (kctx->auk_queue.rd_block &&
d51e90740114c60620c0febffd4d3ce6e280a107ab kctx->auk_queue.cnt > kctx->auk_queue.lowater)
d51e90740114c60620c0febffd4d3ce6e280a107ab cv_broadcast(&(kctx->auk_queue.read_cv));
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab /* keep count of # times blocked */
d51e90740114c60620c0febffd4d3ce6e280a107ab AS_INC(as_wblocked, 1, kctx);
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab /* sleep now, until woken by reader */
d51e90740114c60620c0febffd4d3ce6e280a107ab kctx->auk_queue.wt_block++;
d51e90740114c60620c0febffd4d3ce6e280a107ab cv_wait(&(kctx->auk_queue.write_cv), &(kctx->auk_queue.lock));
d51e90740114c60620c0febffd4d3ce6e280a107ab kctx->auk_queue.wt_block--;
d51e90740114c60620c0febffd4d3ce6e280a107ab } while (kctx->auk_queue.cnt >= kctx->auk_queue.hiwater);
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab return (0);
d51e90740114c60620c0febffd4d3ce6e280a107ab}
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab/*
d51e90740114c60620c0febffd4d3ce6e280a107ab * audit_async_block()
d51e90740114c60620c0febffd4d3ce6e280a107ab * if we've reached the high water mark, we look at the ahlt policy to see
d51e90740114c60620c0febffd4d3ce6e280a107ab * if we reboot we should drop the audit record.
d51e90740114c60620c0febffd4d3ce6e280a107ab * Returns 1 if blocked.
d51e90740114c60620c0febffd4d3ce6e280a107ab */
d51e90740114c60620c0febffd4d3ce6e280a107abstatic int
d51e90740114c60620c0febffd4d3ce6e280a107abaudit_async_block(au_kcontext_t *kctx, caddr_t *rpp)
d51e90740114c60620c0febffd4d3ce6e280a107ab{
d51e90740114c60620c0febffd4d3ce6e280a107ab ASSERT(kctx != NULL);
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab mutex_enter(&(kctx->auk_queue.lock));
d51e90740114c60620c0febffd4d3ce6e280a107ab /* see if we've reached high water mark */
d51e90740114c60620c0febffd4d3ce6e280a107ab if (kctx->auk_queue.cnt >= kctx->auk_queue.hiwater) {
d51e90740114c60620c0febffd4d3ce6e280a107ab mutex_exit(&(kctx->auk_queue.lock));
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab audit_async_drop(rpp, AU_BACKEND);
d51e90740114c60620c0febffd4d3ce6e280a107ab return (1);
d51e90740114c60620c0febffd4d3ce6e280a107ab }
d51e90740114c60620c0febffd4d3ce6e280a107ab mutex_exit(&(kctx->auk_queue.lock));
d51e90740114c60620c0febffd4d3ce6e280a107ab return (0);
d51e90740114c60620c0febffd4d3ce6e280a107ab}
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab/*
d51e90740114c60620c0febffd4d3ce6e280a107ab * au_door_upcall. auditdoor() may change vp without notice, so
d51e90740114c60620c0febffd4d3ce6e280a107ab * some locking seems in order.
d51e90740114c60620c0febffd4d3ce6e280a107ab *
d51e90740114c60620c0febffd4d3ce6e280a107ab */
d51e90740114c60620c0febffd4d3ce6e280a107ab#define AGAIN_TICKS 10
d51e90740114c60620c0febffd4d3ce6e280a107ab
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowiczstatic int
d51e90740114c60620c0febffd4d3ce6e280a107abau_door_upcall(au_kcontext_t *kctx, au_dbuf_t *aubuf)
d51e90740114c60620c0febffd4d3ce6e280a107ab{
d51e90740114c60620c0febffd4d3ce6e280a107ab int rc;
d51e90740114c60620c0febffd4d3ce6e280a107ab door_arg_t darg;
d51e90740114c60620c0febffd4d3ce6e280a107ab int retry = 1;
d51e90740114c60620c0febffd4d3ce6e280a107ab int ticks_to_wait;
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab darg.data_ptr = (char *)aubuf;
d51e90740114c60620c0febffd4d3ce6e280a107ab darg.data_size = AU_DBUF_HEADER + aubuf->aub_size;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz
d51e90740114c60620c0febffd4d3ce6e280a107ab darg.desc_ptr = NULL;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz darg.desc_num = 0;
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab while (retry == 1) {
d51e90740114c60620c0febffd4d3ce6e280a107ab /* non-zero means return results expected */
d51e90740114c60620c0febffd4d3ce6e280a107ab darg.rbuf = (char *)aubuf;
d51e90740114c60620c0febffd4d3ce6e280a107ab darg.rsize = darg.data_size;
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab retry = 0;
d51e90740114c60620c0febffd4d3ce6e280a107ab mutex_enter(&(kctx->auk_svc_lock));
d51e90740114c60620c0febffd4d3ce6e280a107ab if ((rc = door_upcall(kctx->auk_current_vp, &darg)) != 0) {
d51e90740114c60620c0febffd4d3ce6e280a107ab mutex_exit(&(kctx->auk_svc_lock));
d51e90740114c60620c0febffd4d3ce6e280a107ab if (rc == EAGAIN)
d51e90740114c60620c0febffd4d3ce6e280a107ab ticks_to_wait = AGAIN_TICKS;
d51e90740114c60620c0febffd4d3ce6e280a107ab else
d51e90740114c60620c0febffd4d3ce6e280a107ab return (rc);
d51e90740114c60620c0febffd4d3ce6e280a107ab
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz mutex_enter(&(kctx->auk_eagain_mutex));
d51e90740114c60620c0febffd4d3ce6e280a107ab (void) cv_timedwait(&(kctx->auk_eagain_cv),
d51e90740114c60620c0febffd4d3ce6e280a107ab &(kctx->auk_eagain_mutex),
d51e90740114c60620c0febffd4d3ce6e280a107ab lbolt + ticks_to_wait);
d51e90740114c60620c0febffd4d3ce6e280a107ab mutex_exit(&(kctx->auk_eagain_mutex));
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab retry = 1;
d51e90740114c60620c0febffd4d3ce6e280a107ab } else
d51e90740114c60620c0febffd4d3ce6e280a107ab mutex_exit(&(kctx->auk_svc_lock)); /* no retry */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz } /* end while (retry == 1) */
d51e90740114c60620c0febffd4d3ce6e280a107ab if (darg.rbuf == NULL)
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz return (-1);
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab /* return code from door server */
d51e90740114c60620c0febffd4d3ce6e280a107ab return (*(int *)darg.rbuf);
d51e90740114c60620c0febffd4d3ce6e280a107ab}
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab/*
d51e90740114c60620c0febffd4d3ce6e280a107ab * Write an audit control message to the door handle. The message
d51e90740114c60620c0febffd4d3ce6e280a107ab * structure depends on message_code and at present the only control
d51e90740114c60620c0febffd4d3ce6e280a107ab * message defined is for a policy change. These are infrequent,
d51e90740114c60620c0febffd4d3ce6e280a107ab * so no memory is held for control messages.
d51e90740114c60620c0febffd4d3ce6e280a107ab */
d51e90740114c60620c0febffd4d3ce6e280a107abint
d51e90740114c60620c0febffd4d3ce6e280a107abau_doormsg(au_kcontext_t *kctx, uint32_t message_code, void *message)
d51e90740114c60620c0febffd4d3ce6e280a107ab{
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz int rc;
d51e90740114c60620c0febffd4d3ce6e280a107ab au_dbuf_t *buf;
d51e90740114c60620c0febffd4d3ce6e280a107ab size_t alloc_size;
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab switch (message_code) {
d51e90740114c60620c0febffd4d3ce6e280a107ab case AU_DBUF_POLICY:
d51e90740114c60620c0febffd4d3ce6e280a107ab alloc_size = AU_DBUF_HEADER + sizeof (uint32_t);
d51e90740114c60620c0febffd4d3ce6e280a107ab buf = kmem_alloc(alloc_size, KM_SLEEP);
d51e90740114c60620c0febffd4d3ce6e280a107ab buf->aub_size = sizeof (uint32_t);
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz *(uint32_t *)buf->aub_buf = *(uint32_t *)message;
d51e90740114c60620c0febffd4d3ce6e280a107ab break;
d51e90740114c60620c0febffd4d3ce6e280a107ab case AU_DBUF_SHUTDOWN:
d51e90740114c60620c0febffd4d3ce6e280a107ab alloc_size = AU_DBUF_HEADER;
d51e90740114c60620c0febffd4d3ce6e280a107ab buf = kmem_alloc(alloc_size, KM_SLEEP);
d51e90740114c60620c0febffd4d3ce6e280a107ab buf->aub_size = 0;
d51e90740114c60620c0febffd4d3ce6e280a107ab break;
d51e90740114c60620c0febffd4d3ce6e280a107ab default:
d51e90740114c60620c0febffd4d3ce6e280a107ab return (1);
d51e90740114c60620c0febffd4d3ce6e280a107ab }
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab buf->aub_type = AU_DBUF_NOTIFY | message_code;
d51e90740114c60620c0febffd4d3ce6e280a107ab rc = au_door_upcall(kctx, buf);
d51e90740114c60620c0febffd4d3ce6e280a107ab kmem_free(buf, alloc_size);
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab return (rc);
d51e90740114c60620c0febffd4d3ce6e280a107ab}
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab/*
d51e90740114c60620c0febffd4d3ce6e280a107ab * Write audit information to the door handle. au_doorio is called with
d51e90740114c60620c0febffd4d3ce6e280a107ab * one or more complete audit records on the queue and outputs those
d51e90740114c60620c0febffd4d3ce6e280a107ab * records in buffers of up to auk_queue.buflen in size.
d51e90740114c60620c0febffd4d3ce6e280a107ab */
d51e90740114c60620c0febffd4d3ce6e280a107abint
d51e90740114c60620c0febffd4d3ce6e280a107abau_doorio(au_kcontext_t *kctx) {
d51e90740114c60620c0febffd4d3ce6e280a107ab off_t off; /* space used in buffer */
d51e90740114c60620c0febffd4d3ce6e280a107ab ssize_t used; /* space used in au_membuf */
d51e90740114c60620c0febffd4d3ce6e280a107ab token_t *cAR; /* current AR being processed */
d51e90740114c60620c0febffd4d3ce6e280a107ab token_t *cMB; /* current au_membuf being processed */
d51e90740114c60620c0febffd4d3ce6e280a107ab token_t *sp; /* last AR processed */
d51e90740114c60620c0febffd4d3ce6e280a107ab char *bp; /* start of free space in staging buffer */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz unsigned char *cp; /* ptr to data to be moved */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz int error; /* return from door upcall */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz /*
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz * size (data left in au_membuf - space in buffer)
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz ssize_t sz;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz ssize_t len; /* len of data to move, size of AR */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz ssize_t curr_sz = 0; /* amount of data written during now */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz /*
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz * partial_state is AU_DBUF_COMPLETE...LAST; see audit_door_infc.h
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz int part = 0; /* partial audit record written */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz int partial_state = AU_DBUF_COMPLETE;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz /*
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz * Has the write buffer changed length due to a auditctl(2)?
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz * Initial allocation is from audit_start.c/audit_init()
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz if (kctx->auk_queue.bufsz != kctx->auk_queue.buflen) {
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz kmem_free(kctx->auk_dbuffer, AU_DBUF_HEADER +
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz kctx->auk_queue.buflen);
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz kctx->auk_dbuffer = kmem_alloc(AU_DBUF_HEADER +
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz kctx->auk_queue.bufsz, KM_SLEEP);
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz /* omit the 64 bit header */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz kctx->auk_queue.buflen = kctx->auk_queue.bufsz;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz }
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz if (!kctx->auk_queue.head)
beee6fc0eea41662170c4dea38a7e5605ab59507Bryan Cantrill goto nodata;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz sp = NULL; /* no record copied */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz off = 0; /* no space used in buffer */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz used = 0; /* no data processed in au_membuf */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz cAR = kctx->auk_queue.head; /* start at head of queue */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz cMB = cAR; /* start with first au_membuf of record */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz
beee6fc0eea41662170c4dea38a7e5605ab59507Bryan Cantrill /* start at beginning of buffer */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz bp = &(kctx->auk_dbuffer->aub_buf[0]);
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz while (cMB) {
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz part = 1; /* indicate audit record being processed */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz cp = memtod(cMB, unsigned char *); /* buffer ptr */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz
beee6fc0eea41662170c4dea38a7e5605ab59507Bryan Cantrill sz = (ssize_t)cMB->len - used; /* data left in au_membuf */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz /* len to move */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz len = (ssize_t)MIN(sz, kctx->auk_queue.buflen - off);
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz /* move the data */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz bcopy(cp + used, bp + off, len);
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz used += len; /* update used au_membuf */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz off += len; /* update offset into buffer */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz if (used >= (ssize_t)cMB->len) {
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz /* advance to next au_membuf */
beee6fc0eea41662170c4dea38a7e5605ab59507Bryan Cantrill used = 0;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz cMB = cMB->next_buf;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz }
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz if (cMB == NULL) {
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz /* advance to next audit record */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz sp = cAR;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz cAR = cAR->next_rec;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz cMB = cAR;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz part = 0; /* have a complete record */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz }
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz error = 0;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz if ((kctx->auk_queue.buflen == off) || (part == 0)) {
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz if (part)
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz partial_state = state_if_part[partial_state];
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz else
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz partial_state =
beee6fc0eea41662170c4dea38a7e5605ab59507Bryan Cantrill state_if_not_part[partial_state];
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz kctx->auk_dbuffer->aub_type = partial_state;
d51e90740114c60620c0febffd4d3ce6e280a107ab kctx->auk_dbuffer->aub_size = off;
d51e90740114c60620c0febffd4d3ce6e280a107ab error = au_door_upcall(kctx, kctx->auk_dbuffer);
d51e90740114c60620c0febffd4d3ce6e280a107ab if (error != 0)
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz goto nodata;
d51e90740114c60620c0febffd4d3ce6e280a107ab /*
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz * if we've successfully written an audit record,
d51e90740114c60620c0febffd4d3ce6e280a107ab * free records up to last full record copied
d51e90740114c60620c0febffd4d3ce6e280a107ab */
d51e90740114c60620c0febffd4d3ce6e280a107ab if (sp)
d51e90740114c60620c0febffd4d3ce6e280a107ab au_dequeue(kctx, sp);
d51e90740114c60620c0febffd4d3ce6e280a107ab
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz /* Update size */
d51e90740114c60620c0febffd4d3ce6e280a107ab curr_sz += off;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz /* reset auk_dbuffer pointers */
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz sp = NULL;
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz off = 0;
beee6fc0eea41662170c4dea38a7e5605ab59507Bryan Cantrill }
d51e90740114c60620c0febffd4d3ce6e280a107ab } /* while(cMB) */
d51e90740114c60620c0febffd4d3ce6e280a107abnodata:
d51e90740114c60620c0febffd4d3ce6e280a107ab return (error);
d51e90740114c60620c0febffd4d3ce6e280a107ab}
d51e90740114c60620c0febffd4d3ce6e280a107ab
beee6fc0eea41662170c4dea38a7e5605ab59507Bryan Cantrill/*
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz * Clean up thread audit state to clear out asynchronous audit record
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz * generation error recovery processing. Note that this is done on a
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz * per-thread basis and thus does not need any locking.
d9452f237f843c1321abb5810d2f9ee6cbeae43cEdward Pilatowicz */
d51e90740114c60620c0febffd4d3ce6e280a107abvoid
d51e90740114c60620c0febffd4d3ce6e280a107abaudit_async_done(caddr_t *rpp, int flags)
d51e90740114c60620c0febffd4d3ce6e280a107ab{
d51e90740114c60620c0febffd4d3ce6e280a107ab t_audit_data_t *tad = U2A(u);
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab /* clean up the tad unless called from softcall backend */
d51e90740114c60620c0febffd4d3ce6e280a107ab if (!(flags & AU_BACKEND)) {
d51e90740114c60620c0febffd4d3ce6e280a107ab ASSERT(tad != NULL);
d51e90740114c60620c0febffd4d3ce6e280a107ab ASSERT(tad->tad_ctrl & PAD_ERRJMP);
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab tad->tad_ctrl &= ~PAD_ERRJMP;
d51e90740114c60620c0febffd4d3ce6e280a107ab tad->tad_errjmp = NULL;
d51e90740114c60620c0febffd4d3ce6e280a107ab }
d51e90740114c60620c0febffd4d3ce6e280a107ab
d51e90740114c60620c0febffd4d3ce6e280a107ab /* clean out partial audit record */
d51e90740114c60620c0febffd4d3ce6e280a107ab if ((rpp != NULL) && (*rpp != NULL)) {
d51e90740114c60620c0febffd4d3ce6e280a107ab au_toss_token((au_buff_t *)*rpp);
*rpp = NULL;
}
}
/*
* implement the audit policy for asynchronous events generated within
* the kernel.
* XXX might need locks around audit_policy check.
*/
void
audit_async_drop(caddr_t *rpp, int flags)
{
au_kcontext_t *kctx;
/* could not generate audit record, clean up */
audit_async_done((caddr_t *)rpp, flags);
kctx = GET_KCTX_GZ;
/* just drop the record and return */
if (((audit_policy & AUDIT_AHLT) == 0) ||
(kctx->auk_auditstate == AUC_INIT_AUDIT)) {
/* just count # of dropped audit records */
AS_INC(as_dropped, 1, kctx);
return;
}
/*
* There can be a lot of data in the audit queue. We
* will first sync the file systems then attempt to
* shutdown the kernel so that a memory dump is
* performed.
*/
sync();
sync();
/*
* now shut down. What a cruel world it has been
*/
panic("non-attributable halt. should dump core");
/* No return */
}
int
audit_async_start(label_t *jb, int event, int sorf)
{
t_audit_data_t *tad = U2A(u);
au_state_t estate;
int success = 0, failure = 0;
au_kcontext_t *kctx = GET_KCTX_GZ;
/* if audit state off, then no audit record generation */
if ((kctx->auk_auditstate != AUC_AUDITING) &&
(kctx->auk_auditstate != AUC_INIT_AUDIT))
return (1);
/*
* preselect asynchronous event
* XXX should we check for out-of-range???
*/
estate = kctx->auk_ets[event];
if (sorf & AUM_SUCC)
success = kctx->auk_info.ai_mask.as_success & estate;
if (sorf & AUM_FAIL)
failure = kctx->auk_info.ai_mask.as_failure & estate;
if ((success | failure) == NULL)
return (1);
ASSERT(tad->tad_errjmp == NULL);
tad->tad_errjmp = (void *)jb;
tad->tad_ctrl |= PAD_ERRJMP;
return (0);
}
/*
* Complete auditing of an async event. The AU_DONTBLOCK flag to au_close will
* result in the backend routine being invoked from softcall, so all the real
* work can be done in a safe context.
*/
void
audit_async_finish(caddr_t *ad, int aid, int amod)
{
au_kcontext_t *kctx;
kctx = GET_KCTX_GZ;
au_close(kctx, ad, AU_DONTBLOCK | AU_OK, aid, PAD_NONATTR|amod);
}
/*
* Backend routine to complete an async audit. Invoked from softcall.
* (Note: the blocking and the queuing below both involve locking which can't
* be done safely in high interrupt context due to the chance of sleeping on
* the corresponding adaptive mutex. Hence the softcall.)
*/
static void
audit_async_finish_backend(void *addr)
{
au_kcontext_t *kctx;
au_defer_info_t *attr = (au_defer_info_t *)addr;
if (attr == NULL)
return; /* won't happen unless softcall is broken */
kctx = GET_KCTX_GZ;
if (audit_async_block(kctx, (caddr_t *)&attr->audi_ad)) {
kmem_free(attr, sizeof (au_defer_info_t));
return;
}
/*
* Call au_close_time to complete the audit with the saved values.
*
* For the exit-prom event, use the current time instead of the
* saved time as a better approximation. (Because the time saved via
* gethrestime during prom-exit handling would not yet be caught up
* after the system was idled in the debugger for a period of time.)
*/
if (attr->audi_e_type == AUE_EXITPROM) {
au_close_time(kctx, (token_t *)attr->audi_ad, attr->audi_flag,
attr->audi_e_type, attr->audi_e_mod, NULL);
} else {
au_close_time(kctx, (token_t *)attr->audi_ad, attr->audi_flag,
attr->audi_e_type, attr->audi_e_mod, &attr->audi_atime);
}
AS_INC(as_generated, 1, kctx);
AS_INC(as_nonattrib, 1, kctx);
kmem_free(attr, sizeof (au_defer_info_t));
}