Home | History | Annotate | Download | only in c2
      1  0  stevel /*
      2  0  stevel  * CDDL HEADER START
      3  0  stevel  *
      4  0  stevel  * The contents of this file are subject to the terms of the
      5  0  stevel  * Common Development and Distribution License, Version 1.0 only
      6  0  stevel  * (the "License").  You may not use this file except in compliance
      7  0  stevel  * with the License.
      8  0  stevel  *
      9  0  stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10  0  stevel  * or http://www.opensolaris.org/os/licensing.
     11  0  stevel  * See the License for the specific language governing permissions
     12  0  stevel  * and limitations under the License.
     13  0  stevel  *
     14  0  stevel  * When distributing Covered Code, include this CDDL HEADER in each
     15  0  stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16  0  stevel  * If applicable, add the following below this CDDL HEADER, with the
     17  0  stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     18  0  stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     19  0  stevel  *
     20  0  stevel  * CDDL HEADER END
     21  0  stevel  */
     22  0  stevel /*
     23  0  stevel  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
     24  0  stevel  * Use is subject to license terms.
     25  0  stevel  */
     26  0  stevel 
     27  0  stevel #pragma ident	"%Z%%M%	%I%	%E% SMI"
     28  0  stevel 
     29  0  stevel #include <sys/param.h>
     30  0  stevel #include <sys/types.h>
     31  0  stevel #include <sys/kmem.h>
     32  0  stevel #include <sys/t_lock.h>
     33  0  stevel #include <sys/thread.h>
     34  0  stevel #include <sys/systm.h>
     35  0  stevel #include <c2/audit.h>
     36  0  stevel #include <c2/audit_kernel.h>
     37  0  stevel #include <c2/audit_record.h>
     38  0  stevel 
     39  0  stevel kmem_cache_t *au_pad_cache;
     40  0  stevel 
     41  0  stevel static kmem_cache_t *au_buf_cache;
     42  0  stevel 
     43  0  stevel /*
     44  0  stevel  * au_buff_t and token_t are equivalent (see audit_record.h).  Don't
     45  0  stevel  * confuse this token_t with the one that is defined for userspace
     46  0  stevel  * in the same header file.
     47  0  stevel  */
     48  0  stevel 
     49  0  stevel /*
     50  0  stevel  * Function: au_get_buff
     51  0  stevel  * args:
     52  0  stevel  */
     53  0  stevel struct au_buff *
     54  0  stevel au_get_buff(void)
     55  0  stevel {
     56  0  stevel 	au_buff_t *buffer;
     57  0  stevel 	t_audit_data_t *tad = U2A(u);
     58  0  stevel 
     59  0  stevel 	ASSERT(tad);
     60  0  stevel 
     61  0  stevel 	/*
     62  0  stevel 	 * If asynchronous (interrupt) thread, then we can't sleep
     63  0  stevel 	 * (the tad ERRJMP flag is set at the start of async processing).
     64  0  stevel 	 */
     65  0  stevel 	if (tad->tad_ctrl & PAD_ERRJMP) {
     66  0  stevel 		buffer = kmem_cache_alloc(au_buf_cache, KM_NOSLEEP);
     67  0  stevel 		if (buffer == NULL) {
     68  0  stevel 			/* return to top of stack & report an error */
     69  0  stevel 			ASSERT(tad->tad_errjmp);
     70  0  stevel 			longjmp(tad->tad_errjmp);
     71  0  stevel 		}
     72  0  stevel 	} else {
     73  0  stevel 		buffer = kmem_cache_alloc(au_buf_cache, KM_SLEEP);
     74  0  stevel 	}
     75  0  stevel 	/* Never gets here when buffer == NULL */
     76  0  stevel 	bzero(buffer, sizeof (*buffer));
     77  0  stevel 	return (buffer);
     78  0  stevel }
     79  0  stevel 
     80  0  stevel /*
     81  0  stevel  * Function: au_free_rec
     82  0  stevel  * args:
     83  0  stevel  *	au_buff_t *buf;		start of the record chain
     84  0  stevel  */
     85  0  stevel void
     86  0  stevel au_free_rec(au_buff_t *buf)
     87  0  stevel {
     88  0  stevel 	au_buff_t *next;
     89  0  stevel 	t_audit_data_t *tad = U2A(u);
     90  0  stevel 
     91  0  stevel 	ASSERT(tad);
     92  0  stevel 
     93  0  stevel 	/*
     94  0  stevel 	 * If asynchronous (interrupt) thread, schedule the release
     95  0  stevel 	 * (the tad ERRJMP flag is set at the start of async processing).
     96  0  stevel 	 */
     97  0  stevel 	if (tad->tad_ctrl & PAD_ERRJMP) {
     98  0  stevel 		/* Discard async events via softcall. */
     99  0  stevel 		softcall(audit_async_discard_backend, buf);
    100  0  stevel 	}
    101  0  stevel 
    102  0  stevel 	while (buf != NULL) {
    103  0  stevel 		next = buf->next_buf;
    104  0  stevel 		kmem_cache_free(au_buf_cache, buf);
    105  0  stevel 		buf = next;
    106  0  stevel 	}
    107  0  stevel }
    108  0  stevel 
    109  0  stevel /*
    110  0  stevel  * Backend routine to discard an async event. Invoked from softcall.
    111  0  stevel  * (Note: the freeing of memory for the event can't be done safely in high
    112  0  stevel  * interrupt context due to the chance of sleeping on an adaptive mutex.
    113  0  stevel  * Hence the softcall.)
    114  0  stevel  */
    115  0  stevel void
    116  0  stevel audit_async_discard_backend(void *addr)
    117  0  stevel {
    118  0  stevel 	au_toss_token(addr);
    119  0  stevel }
    120  0  stevel 
    121  0  stevel /*
    122  0  stevel  * Function: au_append_rec
    123  0  stevel  * args:
    124  0  stevel  *	au_buff_t *rec;		start of the record chain
    125  0  stevel  *	au_buff_t *buf;		buffer to append
    126  0  stevel  *	int        pack;	AU_PACK/1 - pack data, AU_LINK/0 - link buffer
    127  0  stevel  */
    128  0  stevel int
    129  0  stevel au_append_rec(au_buff_t *rec, au_buff_t *buf, int pack)
    130  0  stevel {
    131  0  stevel 	if (!rec)
    132  0  stevel 		return (-1);
    133  0  stevel 
    134  0  stevel 	while (rec->next_buf)
    135  0  stevel 		rec = rec->next_buf;
    136  0  stevel 	if (((int)(rec->len + buf->len) <= AU_BUFSIZE) && pack) {
    137  0  stevel 		bcopy(buf->buf, (char *)(rec->buf + rec->len),
    138  0  stevel 		    (uint_t)buf->len);
    139  0  stevel 		rec->len += buf->len;
    140  0  stevel 		rec->next_buf = buf->next_buf;
    141  0  stevel 		kmem_cache_free(au_buf_cache, buf);
    142  0  stevel 	} else {
    143  0  stevel 		rec->next_buf = buf;
    144  0  stevel 	}
    145  0  stevel 	return (0);
    146  0  stevel }
    147  0  stevel 
    148  0  stevel /*
    149  0  stevel  * Function: au_append_buf
    150  0  stevel  * args:
    151  0  stevel  *	char *data;		data buffer to append
    152  0  stevel  *	int len;		size of data to append
    153  0  stevel  *	au_buff_t *buf;		buffer to append to
    154  0  stevel  */
    155  0  stevel int
    156  0  stevel au_append_buf(const char *data, int len, au_buff_t *buf)
    157  0  stevel {
    158  0  stevel 	au_buff_t *new_buf;
    159  0  stevel 	int	new_len;
    160  0  stevel 
    161  0  stevel 	while (buf->next_buf != NULL)
    162  0  stevel 		buf = buf->next_buf;
    163  0  stevel 
    164  0  stevel 	new_len = (uint_t)(buf->len + len) > AU_BUFSIZE ?
    165  0  stevel 		AU_BUFSIZE - buf->len : len;
    166  0  stevel 	bcopy(data, (buf->buf + buf->len), (uint_t)new_len);
    167  0  stevel 	buf->len += (uchar_t)new_len;
    168  0  stevel 	len -= new_len;
    169  0  stevel 
    170  0  stevel 	while (len > 0) {
    171  0  stevel 		data += new_len;
    172  0  stevel 		if ((new_buf = au_get_buff()) == NULL) {
    173  0  stevel 			return (-1);
    174  0  stevel 		}
    175  0  stevel 		buf->next_buf = new_buf;
    176  0  stevel 		buf = new_buf;
    177  0  stevel 		new_len = len > AU_BUFSIZE ? AU_BUFSIZE : len;
    178  0  stevel 		bcopy(data, buf->buf, (uint_t)new_len);
    179  0  stevel 		buf->len = (uchar_t)new_len;
    180  0  stevel 		len -= new_len;
    181  0  stevel 	}
    182  0  stevel 	return (0);
    183  0  stevel }
    184  0  stevel 
    185  0  stevel /*ARGSUSED1*/
    186  0  stevel static int
    187  0  stevel au_pad_const(void *vpad, void *priv, int flags)
    188  0  stevel {
    189  0  stevel 	p_audit_data_t *pad = vpad;
    190  0  stevel 
    191  0  stevel 	mutex_init(&pad->pad_lock, NULL, MUTEX_DEFAULT, NULL);
    192  0  stevel 
    193  0  stevel 	return (0);
    194  0  stevel }
    195  0  stevel 
    196  0  stevel /*ARGSUSED1*/
    197  0  stevel static void
    198  0  stevel au_pad_destr(void *vpad, void *priv)
    199  0  stevel {
    200  0  stevel 	p_audit_data_t *pad = vpad;
    201  0  stevel 
    202  0  stevel 	mutex_destroy(&pad->pad_lock);
    203  0  stevel }
    204  0  stevel 
    205  0  stevel void
    206  0  stevel au_mem_init()
    207  0  stevel {
    208  0  stevel 	au_buf_cache = kmem_cache_create("audit_buffer",
    209  0  stevel 		sizeof (au_buff_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
    210  0  stevel 
    211  0  stevel 	au_pad_cache = kmem_cache_create("audit_proc",
    212  0  stevel 		sizeof (p_audit_data_t), 0, au_pad_const, au_pad_destr,
    213  0  stevel 		NULL, NULL, NULL, 0);
    214  0  stevel }
    215