/* audit.c -- Auditing support
 * Gateway between the kernel (e.g., selinux) and the user-space audit daemon.
 * System-call specific features have moved to auditsc.c
 *
 * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
 * All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Written by Rickard E. (Rik) Faith <faith@redhat.com>
 *
 * Goals: 1) Integrate fully with SELinux.
 *	  2) Minimal run-time overhead:
 *	     a) Minimal when syscall auditing is disabled (audit_enable=0).
 *	     b) Small when syscall auditing is enabled and no audit record
 *		is generated (defer as much work as possible to record
 *		generation time):
 *		i) context is allocated,
 *		ii) names from getname are stored without a copy, and
 *		iii) inode information stored from path_lookup.
 *	  3) Ability to disable syscall auditing at boot time (audit=0).
 *	  4) Usable by other parts of the kernel (if audit_log* is called,
 *	     then a syscall record will be generated automatically for the
 *	     current syscall).
 *	  5) Netlink interface to user-space.
 *	  6) Support low-overhead kernel-based filtering to minimize the
 *	     information that must be passed to user-space.
 *
 * Example user-space utilities: http://people.redhat.com/sgrubb/audit/
 */

#include <linux/init.h>
#include <asm/atomic.h>
#include <asm/types.h>
#include <linux/mm.h>
#include <linux/module.h>

#include <linux/audit.h>

#include <net/sock.h>
#include <linux/skbuff.h>
#include <linux/netlink.h>

/* No auditing will take place until audit_initialized != 0.
 * (Initialization happens after skb_init is called.) */
static int	audit_initialized;

/* No syscall auditing will take place unless audit_enabled != 0. */
int		audit_enabled;

/* Default state when kernel boots without any parameters. */
static int	audit_default;

/* If auditing cannot proceed, audit_failure selects what happens. */
static int	audit_failure = AUDIT_FAIL_PRINTK;

/* If audit records are to be written to the netlink socket, audit_pid
 * contains the (non-zero) pid. */
int		audit_pid;

/* If audit_limit is non-zero, limit the rate of sending audit records
 * to that number per second.  This prevents DoS attacks, but results in
 * audit records being dropped. */
static int	audit_rate_limit;

/* Number of outstanding audit_buffers allowed. */
static int	audit_backlog_limit = 64;
static atomic_t	audit_backlog	    = ATOMIC_INIT(0);

/* The identity of the user shutting down the audit system. */
uid_t		audit_sig_uid = -1;
pid_t		audit_sig_pid = -1;

/* Records can be lost in several ways:
   0) [suppressed in audit_alloc]
   1) out of memory in audit_log_start [kmalloc of struct audit_buffer]
   2) out of memory in audit_log_move [alloc_skb]
   3) suppressed due to audit_rate_limit
   4) suppressed due to audit_backlog_limit
*/
static atomic_t    audit_lost = ATOMIC_INIT(0);

/* The netlink socket. */
static struct sock *audit_sock;

/* There are two lists of audit buffers.  The txlist contains audit
 * buffers that cannot be sent immediately to the netlink device because
 * we are in an irq context (these are sent later in a tasklet).
 *
 * The second list is a list of pre-allocated audit buffers (if more
 * than AUDIT_MAXFREE are in use, the audit buffer is freed instead of
 * being placed on the freelist). */
static DEFINE_SPINLOCK(audit_txlist_lock);
static DEFINE_SPINLOCK(audit_freelist_lock);
static int	   audit_freelist_count = 0;
static LIST_HEAD(audit_txlist);
static LIST_HEAD(audit_freelist);

/* There are three lists of rules -- one to search at task creation
 * time, one to search at syscall entry time, and another to search at
 * syscall exit time. */
static LIST_HEAD(audit_tsklist);
static LIST_HEAD(audit_entlist);
static LIST_HEAD(audit_extlist);

/* The netlink socket is only to be read by 1 CPU, which lets us assume
 * that list additions and deletions never happen simultaneously in
 * auditsc.c */
static DECLARE_MUTEX(audit_netlink_sem);

/* AUDIT_BUFSIZ is the size of the temporary buffer used for formatting
 * audit records.  Since printk uses a 1024 byte buffer, this buffer
 * should be at least that large. */
#define AUDIT_BUFSIZ 1024

/* AUDIT_MAXFREE is the number of empty audit_buffers we keep on the
 * audit_freelist.  Doing so eliminates many kmalloc/kfree calls. */
#define AUDIT_MAXFREE  (2*NR_CPUS)

/* The audit_buffer is used when formatting an audit record.  The caller
 * locks briefly to get the record off the freelist or to allocate the
 * buffer, and locks briefly to send the buffer to the netlink layer or
 * to place it on a transmit queue.  Multiple audit_buffers can be in
 * use simultaneously. */
struct audit_buffer {
	struct list_head     list;
	struct sk_buff       *skb;	/* formatted skb ready to send */
	struct audit_context *ctx;	/* NULL or associated context */
};

static void audit_set_pid(struct audit_buffer *ab, pid_t pid)
{
	struct nlmsghdr *nlh = (struct nlmsghdr *)ab->skb->data;
	nlh->nlmsg_pid = pid;
}

struct audit_entry {
	struct list_head  list;
	struct audit_rule rule;
};

static void audit_log_end_irq(struct audit_buffer *ab);
static void audit_log_end_fast(struct audit_buffer *ab);

static void audit_panic(const char *message)
{
	switch (audit_failure)
	{
	case AUDIT_FAIL_SILENT:
		break;
	case AUDIT_FAIL_PRINTK:
		printk(KERN_ERR "audit: %s\n", message);
		break;
	case AUDIT_FAIL_PANIC:
		panic("audit: %s\n", message);
		break;
	}
}

static inline int audit_rate_check(void)
{
	static unsigned long	last_check = 0;
	static int		messages   = 0;
	static DEFINE_SPINLOCK(lock);
	unsigned long		flags;
	unsigned long		now;
	unsigned long		elapsed;
	int			retval	   = 0;

	if (!audit_rate_limit) return 1;

	spin_lock_irqsave(&lock, flags);
	if (++messages < audit_rate_limit) {
		retval = 1;
	} else {
		now     = jiffies;
		elapsed = now - last_check;
		if (elapsed > HZ) {
			last_check = now;
			messages   = 0;
			retval     = 1;
		}
	}
	spin_unlock_irqrestore(&lock, flags);

	return retval;
}

/* Emit at least 1 message per second, even if audit_rate_check is
 * throttling. */
void audit_log_lost(const char *message)
{
	static unsigned long	last_msg = 0;
	static DEFINE_SPINLOCK(lock);
	unsigned long		flags;
	unsigned long		now;
	int			print;

	atomic_inc(&audit_lost);

	print = (audit_failure == AUDIT_FAIL_PANIC || !audit_rate_limit);

	if (!print) {
		spin_lock_irqsave(&lock, flags);
		now = jiffies;
		if (now - last_msg > HZ) {
			print = 1;
			last_msg = now;
		}
		spin_unlock_irqrestore(&lock, flags);
	}

	if (print) {
		printk(KERN_WARNING
		       "audit: audit_lost=%d audit_backlog=%d"
		       " audit_rate_limit=%d audit_backlog_limit=%d\n",
		       atomic_read(&audit_lost),
		       atomic_read(&audit_backlog),
		       audit_rate_limit,
		       audit_backlog_limit);
		audit_panic(message);
	}

}

static int audit_set_rate_limit(int limit, uid_t loginuid)
{
	int old		 = audit_rate_limit;
	audit_rate_limit = limit;
	audit_log(NULL, AUDIT_CONFIG_CHANGE, 
			"audit_rate_limit=%d old=%d by auid %u",
			audit_rate_limit, old, loginuid);
	return old;
}

static int audit_set_backlog_limit(int limit, uid_t loginuid)
{
	int old		 = audit_backlog_limit;
	audit_backlog_limit = limit;
	audit_log(NULL, AUDIT_CONFIG_CHANGE,
			"audit_backlog_limit=%d old=%d by auid %u",
			audit_backlog_limit, old, loginuid);
	return old;
}

static int audit_set_enabled(int state, uid_t loginuid)
{
	int old		 = audit_enabled;
	if (state != 0 && state != 1)
		return -EINVAL;
	audit_enabled = state;
	audit_log(NULL, AUDIT_CONFIG_CHANGE,
			"audit_enabled=%d old=%d by auid %u",
			audit_enabled, old, loginuid);
	return old;
}

static int audit_set_failure(int state, uid_t loginuid)
{
	int old		 = audit_failure;
	if (state != AUDIT_FAIL_SILENT
	    && state != AUDIT_FAIL_PRINTK
	    && state != AUDIT_FAIL_PANIC)
		return -EINVAL;
	audit_failure = state;
	audit_log(NULL, AUDIT_CONFIG_CHANGE,
			"audit_failure=%d old=%d by auid %u",
			audit_failure, old, loginuid);
	return old;
}

void audit_send_reply(int pid, int seq, int type, int done, int multi,
		      void *payload, int size)
{
	struct sk_buff	*skb;
	struct nlmsghdr	*nlh;
	int		len = NLMSG_SPACE(size);
	void		*data;
	int		flags = multi ? NLM_F_MULTI : 0;
	int		t     = done  ? NLMSG_DONE  : type;

	skb = alloc_skb(len, GFP_KERNEL);
	if (!skb)
		goto nlmsg_failure;

	nlh		 = NLMSG_PUT(skb, pid, seq, t, len - sizeof(*nlh));
	nlh->nlmsg_flags = flags;
	data		 = NLMSG_DATA(nlh);
	memcpy(data, payload, size);
	netlink_unicast(audit_sock, skb, pid, MSG_DONTWAIT);
	return;

nlmsg_failure:			/* Used by NLMSG_PUT */
	if (skb)
		kfree_skb(skb);
}

/*
 * Check for appropriate CAP_AUDIT_ capabilities on incoming audit
 * control messages.
 */
static int audit_netlink_ok(kernel_cap_t eff_cap, u16 msg_type)
{
	int err = 0;

	switch (msg_type) {
	case AUDIT_GET:
	case AUDIT_LIST:
	case AUDIT_SET:
	case AUDIT_ADD:
	case AUDIT_DEL:
	case AUDIT_SIGNAL_INFO:
		if (!cap_raised(eff_cap, CAP_AUDIT_CONTROL))
			err = -EPERM;
		break;
	case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG:
		if (!cap_raised(eff_cap, CAP_AUDIT_WRITE))
			err = -EPERM;
		break;
	default:  /* bad msg */
		err = -EINVAL;
	}

	return err;
}

static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
{
	u32			uid, pid, seq;
	void			*data;
	struct audit_status	*status_get, status_set;
	int			err;
	struct audit_buffer	*ab;
	u16			msg_type = nlh->nlmsg_type;
	uid_t			loginuid; /* loginuid of sender */
	struct audit_sig_info   sig_data;

	err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type);
	if (err)
		return err;

	pid  = NETLINK_CREDS(skb)->pid;
	uid  = NETLINK_CREDS(skb)->uid;
	loginuid = NETLINK_CB(skb).loginuid;
	seq  = nlh->nlmsg_seq;
	data = NLMSG_DATA(nlh);

	switch (msg_type) {
	case AUDIT_GET:
		status_set.enabled	 = audit_enabled;
		status_set.failure	 = audit_failure;
		status_set.pid		 = audit_pid;
		status_set.rate_limit	 = audit_rate_limit;
		status_set.backlog_limit = audit_backlog_limit;
		status_set.lost		 = atomic_read(&audit_lost);
		status_set.backlog	 = atomic_read(&audit_backlog);
		audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_GET, 0, 0,
				 &status_set, sizeof(status_set));
		break;
	case AUDIT_SET:
		if (nlh->nlmsg_len < sizeof(struct audit_status))
			return -EINVAL;
		status_get   = (struct audit_status *)data;
		if (status_get->mask & AUDIT_STATUS_ENABLED) {
			err = audit_set_enabled(status_get->enabled, loginuid);
			if (err < 0) return err;
		}
		if (status_get->mask & AUDIT_STATUS_FAILURE) {
			err = audit_set_failure(status_get->failure, loginuid);
			if (err < 0) return err;
		}
		if (status_get->mask & AUDIT_STATUS_PID) {
			int old   = audit_pid;
			audit_pid = status_get->pid;
			audit_log(NULL, AUDIT_CONFIG_CHANGE,
				"audit_pid=%d old=%d by auid %u",
				  audit_pid, old, loginuid);
		}
		if (status_get->mask & AUDIT_STATUS_RATE_LIMIT)
			audit_set_rate_limit(status_get->rate_limit, loginuid);
		if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT)
			audit_set_backlog_limit(status_get->backlog_limit,
							loginuid);
		break;
	case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG:
		ab = audit_log_start(NULL, msg_type);
		if (!ab)
			break;	/* audit_panic has been called */
		audit_log_format(ab,
				 "user pid=%d uid=%d length=%d loginuid=%u"
				 " msg='%.1024s'",
				 pid, uid,
				 (int)(nlh->nlmsg_len
				       - ((char *)data - (char *)nlh)),
				 loginuid, (char *)data);
		audit_set_pid(ab, pid);
		audit_log_end(ab);
		break;
	case AUDIT_ADD:
	case AUDIT_DEL:
		if (nlh->nlmsg_len < sizeof(struct audit_rule))
			return -EINVAL;
		/* fallthrough */
	case AUDIT_LIST:
		err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid,
					   uid, seq, data, loginuid);
		break;
	case AUDIT_SIGNAL_INFO:
		sig_data.uid = audit_sig_uid;
		sig_data.pid = audit_sig_pid;
		audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO, 
				0, 0, &sig_data, sizeof(sig_data));
		break;
	default:
		err = -EINVAL;
		break;
	}

	return err < 0 ? err : 0;
}

/* Get message from skb (based on rtnetlink_rcv_skb).  Each message is
 * processed by audit_receive_msg.  Malformed skbs with wrong length are
 * discarded silently.  */
static void audit_receive_skb(struct sk_buff *skb)
{
	int		err;
	struct nlmsghdr	*nlh;
	u32		rlen;

	while (skb->len >= NLMSG_SPACE(0)) {
		nlh = (struct nlmsghdr *)skb->data;
		if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
			return;
		rlen = NLMSG_ALIGN(nlh->nlmsg_len);
		if (rlen > skb->len)
			rlen = skb->len;
		if ((err = audit_receive_msg(skb, nlh))) {
			netlink_ack(skb, nlh, err);
		} else if (nlh->nlmsg_flags & NLM_F_ACK)
			netlink_ack(skb, nlh, 0);
		skb_pull(skb, rlen);
	}
}

/* Receive messages from netlink socket. */
static void audit_receive(struct sock *sk, int length)
{
	struct sk_buff  *skb;
	unsigned int qlen;

	down(&audit_netlink_sem);

	for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) {
		skb = skb_dequeue(&sk->sk_receive_queue);
		audit_receive_skb(skb);
		kfree_skb(skb);
	}
	up(&audit_netlink_sem);
}

/* Grab skbuff from the audit_buffer and send to user space. */
static inline int audit_log_drain(struct audit_buffer *ab)
{
	struct sk_buff *skb = ab->skb;

	if (skb) {
		int retval = 0;

		if (audit_pid) {
			struct nlmsghdr *nlh = (struct nlmsghdr *)skb->data;
			nlh->nlmsg_len = skb->len - NLMSG_SPACE(0);
			skb_get(skb); /* because netlink_* frees */
			retval = netlink_unicast(audit_sock, skb, audit_pid,
						 MSG_DONTWAIT);
		}
		if (retval == -EAGAIN &&
		    (atomic_read(&audit_backlog)) < audit_backlog_limit) {
			audit_log_end_irq(ab);
			return 1;
		}
		if (retval < 0) {
			if (retval == -ECONNREFUSED) {
				printk(KERN_ERR
				       "audit: *NO* daemon at audit_pid=%d\n",
				       audit_pid);
				audit_pid = 0;
			} else
				audit_log_lost("netlink socket too busy");
		}
		if (!audit_pid) { /* No daemon */
			int offset = NLMSG_SPACE(0);
			int len    = skb->len - offset;
			skb->data[offset + len] = '\0';
			printk(KERN_ERR "%s\n", skb->data + offset);
		}
	}
	return 0;
}

/* Initialize audit support at boot time. */
static int __init audit_init(void)
{
	printk(KERN_INFO "audit: initializing netlink socket (%s)\n",
	       audit_default ? "enabled" : "disabled");
	audit_sock = netlink_kernel_create(NETLINK_AUDIT, audit_receive);
	if (!audit_sock)
		audit_panic("cannot initialize netlink socket");

	audit_initialized = 1;
	audit_enabled = audit_default;
	audit_log(NULL, AUDIT_KERNEL, "initialized");
	return 0;
}
__initcall(audit_init);

/* Process kernel command-line parameter at boot time.  audit=0 or audit=1. */
static int __init audit_enable(char *str)
{
	audit_default = !!simple_strtol(str, NULL, 0);
	printk(KERN_INFO "audit: %s%s\n",
	       audit_default ? "enabled" : "disabled",
	       audit_initialized ? "" : " (after initialization)");
	if (audit_initialized)
		audit_enabled = audit_default;
	return 0;
}

__setup("audit=", audit_enable);

static void audit_buffer_free(struct audit_buffer *ab)
{
	unsigned long flags;

	if (!ab)
		return;

	if (ab->skb)
		kfree_skb(ab->skb);
	atomic_dec(&audit_backlog);
	spin_lock_irqsave(&audit_freelist_lock, flags);
	if (++audit_freelist_count > AUDIT_MAXFREE)
		kfree(ab);
	else
		list_add(&ab->list, &audit_freelist);
	spin_unlock_irqrestore(&audit_freelist_lock, flags);
}

static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx,
						int gfp_mask, int type)
{
	unsigned long flags;
	struct audit_buffer *ab = NULL;
	struct nlmsghdr *nlh;

	spin_lock_irqsave(&audit_freelist_lock, flags);
	if (!list_empty(&audit_freelist)) {
		ab = list_entry(audit_freelist.next,
				struct audit_buffer, list);
		list_del(&ab->list);
		--audit_freelist_count;
	}
	spin_unlock_irqrestore(&audit_freelist_lock, flags);

	if (!ab) {
		ab = kmalloc(sizeof(*ab), gfp_mask);
		if (!ab)
			goto err;
	}
	atomic_inc(&audit_backlog);

	ab->skb = alloc_skb(AUDIT_BUFSIZ, gfp_mask);
	if (!ab->skb)
		goto err;

	ab->ctx   = ctx;
	nlh = (struct nlmsghdr *)skb_put(ab->skb, NLMSG_SPACE(0));
	nlh->nlmsg_type = type;
	nlh->nlmsg_flags = 0;
	nlh->nlmsg_pid = 0;
	nlh->nlmsg_seq = 0;
	return ab;
err:
	audit_buffer_free(ab);
	return NULL;
}

/* Obtain an audit buffer.  This routine does locking to obtain the
 * audit buffer, but then no locking is required for calls to
 * audit_log_*format.  If the tsk is a task that is currently in a
 * syscall, then the syscall is marked as auditable and an audit record
 * will be written at syscall exit.  If there is no associated task, tsk
 * should be NULL. */
struct audit_buffer *audit_log_start(struct audit_context *ctx, int type)
{
	struct audit_buffer	*ab	= NULL;
	struct timespec		t;
	unsigned int		serial;

	if (!audit_initialized)
		return NULL;

	if (audit_backlog_limit
	    && atomic_read(&audit_backlog) > audit_backlog_limit) {
		if (audit_rate_check())
			printk(KERN_WARNING
			       "audit: audit_backlog=%d > "
			       "audit_backlog_limit=%d\n",
			       atomic_read(&audit_backlog),
			       audit_backlog_limit);
		audit_log_lost("backlog limit exceeded");
		return NULL;
	}

	ab = audit_buffer_alloc(ctx, GFP_ATOMIC, type);
	if (!ab) {
		audit_log_lost("out of memory in audit_log_start");
		return NULL;
	}

	if (!audit_get_stamp(ab->ctx, &t, &serial)) {
		t = CURRENT_TIME;
		serial = 0;
	}

	audit_log_format(ab, "audit(%lu.%03lu:%u): ",
			 t.tv_sec, t.tv_nsec/1000000, serial);
	return ab;
}

/**
 * audit_expand - expand skb in the audit buffer
 * @ab: audit_buffer
 *
 * Returns 0 (no space) on failed expansion, or available space if
 * successful.
 */
static inline int audit_expand(struct audit_buffer *ab, int extra)
{
	struct sk_buff *skb = ab->skb;
	int ret = pskb_expand_head(skb, skb_headroom(skb), extra,
				   GFP_ATOMIC);
	if (ret < 0) {
		audit_log_lost("out of memory in audit_expand");
		return 0;
	}
	return skb_tailroom(skb);
}

/* Format an audit message into the audit buffer.  If there isn't enough
 * room in the audit buffer, more room will be allocated and vsnprint
 * will be called a second time.  Currently, we assume that a printk
 * can't format message larger than 1024 bytes, so we don't either. */
static void audit_log_vformat(struct audit_buffer *ab, const char *fmt,
			      va_list args)
{
	int len, avail;
	struct sk_buff *skb;
	va_list args2;

	if (!ab)
		return;

	BUG_ON(!ab->skb);
	skb = ab->skb;
	avail = skb_tailroom(skb);
	if (avail == 0) {
		avail = audit_expand(ab, AUDIT_BUFSIZ);
		if (!avail)
			goto out;
	}
	va_copy(args2, args);
	len = vsnprintf(skb->tail, avail, fmt, args);
	if (len >= avail) {
		/* The printk buffer is 1024 bytes long, so if we get
		 * here and AUDIT_BUFSIZ is at least 1024, then we can
		 * log everything that printk could have logged. */
		avail = audit_expand(ab, max_t(unsigned, AUDIT_BUFSIZ, 1+len-avail));
		if (!avail)
			goto out;
		len = vsnprintf(skb->tail, avail, fmt, args2);
	}
	skb_put(skb, (len < avail) ? len : avail);
out:
	return;
}

/* Format a message into the audit buffer.  All the work is done in
 * audit_log_vformat. */
void audit_log_format(struct audit_buffer *ab, const char *fmt, ...)
{
	va_list args;

	if (!ab)
		return;
	va_start(args, fmt);
	audit_log_vformat(ab, fmt, args);
	va_end(args);
}

void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf, size_t len)
{
	int i;

	for (i=0; i<len; i++)
		audit_log_format(ab, "%02x", buf[i]);
}

void audit_log_untrustedstring(struct audit_buffer *ab, const char *string)
{
	const unsigned char *p = string;

	while (*p) {
		if (*p == '"' || *p == ' ' || *p < 0x20 || *p > 0x7f) {
			audit_log_hex(ab, string, strlen(string));
			return;
		}
		p++;
	}
	audit_log_format(ab, "\"%s\"", string);
}


/* This is a helper-function to print the d_path without using a static
 * buffer or allocating another buffer in addition to the one in
 * audit_buffer. */
void audit_log_d_path(struct audit_buffer *ab, const char *prefix,
		      struct dentry *dentry, struct vfsmount *vfsmnt)
{
	char *p;
	struct sk_buff *skb = ab->skb;
	int  len, avail;

	if (prefix)
		audit_log_format(ab, " %s", prefix);

	avail = skb_tailroom(skb);
	p = d_path(dentry, vfsmnt, skb->tail, avail);
	if (IS_ERR(p)) {
		/* FIXME: can we save some information here? */
		audit_log_format(ab, "<toolong>");
	} else {
		/* path isn't at start of buffer */
		len = ((char *)skb->tail + avail - 1) - p;
		memmove(skb->tail, p, len);
		skb_put(skb, len);
	}
}

/* Remove queued messages from the audit_txlist and send them to user space. */
static void audit_tasklet_handler(unsigned long arg)
{
	LIST_HEAD(list);
	struct audit_buffer *ab;
	unsigned long	    flags;

	spin_lock_irqsave(&audit_txlist_lock, flags);
	list_splice_init(&audit_txlist, &list);
	spin_unlock_irqrestore(&audit_txlist_lock, flags);

	while (!list_empty(&list)) {
		ab = list_entry(list.next, struct audit_buffer, list);
		list_del(&ab->list);
		audit_log_end_fast(ab);
	}
}

static DECLARE_TASKLET(audit_tasklet, audit_tasklet_handler, 0);

/* The netlink_* functions cannot be called inside an irq context, so
 * the audit buffer is places on a queue and a tasklet is scheduled to
 * remove them from the queue outside the irq context.  May be called in
 * any context. */
static void audit_log_end_irq(struct audit_buffer *ab)
{
	unsigned long flags;

	if (!ab)
		return;
	spin_lock_irqsave(&audit_txlist_lock, flags);
	list_add_tail(&ab->list, &audit_txlist);
	spin_unlock_irqrestore(&audit_txlist_lock, flags);

	tasklet_schedule(&audit_tasklet);
}

/* Send the message in the audit buffer directly to user space.  May not
 * be called in an irq context. */
static void audit_log_end_fast(struct audit_buffer *ab)
{
	BUG_ON(in_irq());
	if (!ab)
		return;
	if (!audit_rate_check()) {
		audit_log_lost("rate limit exceeded");
	} else {
		if (audit_log_drain(ab))
			return;
	}
	audit_buffer_free(ab);
}

/* Send or queue the message in the audit buffer, depending on the
 * current context.  (A convenience function that may be called in any
 * context.) */
void audit_log_end(struct audit_buffer *ab)
{
	if (in_irq())
		audit_log_end_irq(ab);
	else
		audit_log_end_fast(ab);
}

/* Log an audit record.  This is a convenience function that calls
 * audit_log_start, audit_log_vformat, and audit_log_end.  It may be
 * called in any context. */
void audit_log(struct audit_context *ctx, int type, const char *fmt, ...)
{
	struct audit_buffer *ab;
	va_list args;

	ab = audit_log_start(ctx, type);
	if (ab) {
		va_start(args, fmt);
		audit_log_vformat(ab, fmt, args);
		va_end(args);
		audit_log_end(ab);
	}
}
