/* auditfilter.c -- filtering of audit events
 *
 * Copyright 2003-2004 Red Hat, Inc.
 * Copyright 2005 Hewlett-Packard Development Company, L.P.
 * Copyright 2005 IBM Corporation
 *
 * 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
 */

#include <linux/kernel.h>
#include <linux/audit.h>
#include <linux/kthread.h>
#include <linux/mutex.h>
#include <linux/fs.h>
#include <linux/namei.h>
#include <linux/netlink.h>
#include <linux/sched.h>
#include <linux/inotify.h>
#include <linux/selinux.h>
#include "audit.h"

/*
 * Locking model:
 *
 * audit_filter_mutex:
 * 		Synchronizes writes and blocking reads of audit's filterlist
 * 		data.  Rcu is used to traverse the filterlist and access
 * 		contents of structs audit_entry, audit_watch and opaque
 * 		selinux rules during filtering.  If modified, these structures
 * 		must be copied and replace their counterparts in the filterlist.
 * 		An audit_parent struct is not accessed during filtering, so may
 * 		be written directly provided audit_filter_mutex is held.
 */

/*
 * Reference counting:
 *
 * audit_parent: lifetime is from audit_init_parent() to receipt of an IN_IGNORED
 * 	event.  Each audit_watch holds a reference to its associated parent.
 *
 * audit_watch: if added to lists, lifetime is from audit_init_watch() to
 * 	audit_remove_watch().  Additionally, an audit_watch may exist
 * 	temporarily to assist in searching existing filter data.  Each
 * 	audit_krule holds a reference to its associated watch.
 */

struct audit_parent {
	struct list_head	ilist;	/* entry in inotify registration list */
	struct list_head	watches; /* associated watches */
	struct inotify_watch	wdata;	/* inotify watch data */
	unsigned		flags;	/* status flags */
};

/*
 * audit_parent status flags:
 *
 * AUDIT_PARENT_INVALID - set anytime rules/watches are auto-removed due to
 * a filesystem event to ensure we're adding audit watches to a valid parent.
 * Technically not needed for IN_DELETE_SELF or IN_UNMOUNT events, as we cannot
 * receive them while we have nameidata, but must be used for IN_MOVE_SELF which
 * we can receive while holding nameidata.
 */
#define AUDIT_PARENT_INVALID	0x001

/* Audit filter lists, defined in <linux/audit.h> */
struct list_head audit_filter_list[AUDIT_NR_FILTERS] = {
	LIST_HEAD_INIT(audit_filter_list[0]),
	LIST_HEAD_INIT(audit_filter_list[1]),
	LIST_HEAD_INIT(audit_filter_list[2]),
	LIST_HEAD_INIT(audit_filter_list[3]),
	LIST_HEAD_INIT(audit_filter_list[4]),
	LIST_HEAD_INIT(audit_filter_list[5]),
#if AUDIT_NR_FILTERS != 6
#error Fix audit_filter_list initialiser
#endif
};

static DEFINE_MUTEX(audit_filter_mutex);

/* Inotify handle */
extern struct inotify_handle *audit_ih;

/* Inotify events we care about. */
#define AUDIT_IN_WATCH IN_MOVE|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MOVE_SELF

void audit_free_parent(struct inotify_watch *i_watch)
{
	struct audit_parent *parent;

	parent = container_of(i_watch, struct audit_parent, wdata);
	WARN_ON(!list_empty(&parent->watches));
	kfree(parent);
}

static inline void audit_get_watch(struct audit_watch *watch)
{
	atomic_inc(&watch->count);
}

static void audit_put_watch(struct audit_watch *watch)
{
	if (atomic_dec_and_test(&watch->count)) {
		WARN_ON(watch->parent);
		WARN_ON(!list_empty(&watch->rules));
		kfree(watch->path);
		kfree(watch);
	}
}

static void audit_remove_watch(struct audit_watch *watch)
{
	list_del(&watch->wlist);
	put_inotify_watch(&watch->parent->wdata);
	watch->parent = NULL;
	audit_put_watch(watch); /* match initial get */
}

static inline void audit_free_rule(struct audit_entry *e)
{
	int i;

	/* some rules don't have associated watches */
	if (e->rule.watch)
		audit_put_watch(e->rule.watch);
	if (e->rule.fields)
		for (i = 0; i < e->rule.field_count; i++) {
			struct audit_field *f = &e->rule.fields[i];
			kfree(f->se_str);
			selinux_audit_rule_free(f->se_rule);
		}
	kfree(e->rule.fields);
	kfree(e->rule.filterkey);
	kfree(e);
}

static inline void audit_free_rule_rcu(struct rcu_head *head)
{
	struct audit_entry *e = container_of(head, struct audit_entry, rcu);
	audit_free_rule(e);
}

/* Initialize a parent watch entry. */
static struct audit_parent *audit_init_parent(struct nameidata *ndp)
{
	struct audit_parent *parent;
	s32 wd;

	parent = kzalloc(sizeof(*parent), GFP_KERNEL);
	if (unlikely(!parent))
		return ERR_PTR(-ENOMEM);

	INIT_LIST_HEAD(&parent->watches);
	parent->flags = 0;

	inotify_init_watch(&parent->wdata);
	/* grab a ref so inotify watch hangs around until we take audit_filter_mutex */
	get_inotify_watch(&parent->wdata);
	wd = inotify_add_watch(audit_ih, &parent->wdata, ndp->dentry->d_inode,
			       AUDIT_IN_WATCH);
	if (wd < 0) {
		audit_free_parent(&parent->wdata);
		return ERR_PTR(wd);
	}

	return parent;
}

/* Initialize a watch entry. */
static struct audit_watch *audit_init_watch(char *path)
{
	struct audit_watch *watch;

	watch = kzalloc(sizeof(*watch), GFP_KERNEL);
	if (unlikely(!watch))
		return ERR_PTR(-ENOMEM);

	INIT_LIST_HEAD(&watch->rules);
	atomic_set(&watch->count, 1);
	watch->path = path;
	watch->dev = (dev_t)-1;
	watch->ino = (unsigned long)-1;

	return watch;
}

/* Initialize an audit filterlist entry. */
static inline struct audit_entry *audit_init_entry(u32 field_count)
{
	struct audit_entry *entry;
	struct audit_field *fields;

	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
	if (unlikely(!entry))
		return NULL;

	fields = kzalloc(sizeof(*fields) * field_count, GFP_KERNEL);
	if (unlikely(!fields)) {
		kfree(entry);
		return NULL;
	}
	entry->rule.fields = fields;

	return entry;
}

/* Unpack a filter field's string representation from user-space
 * buffer. */
static char *audit_unpack_string(void **bufp, size_t *remain, size_t len)
{
	char *str;

	if (!*bufp || (len == 0) || (len > *remain))
		return ERR_PTR(-EINVAL);

	/* Of the currently implemented string fields, PATH_MAX
	 * defines the longest valid length.
	 */
	if (len > PATH_MAX)
		return ERR_PTR(-ENAMETOOLONG);

	str = kmalloc(len + 1, GFP_KERNEL);
	if (unlikely(!str))
		return ERR_PTR(-ENOMEM);

	memcpy(str, *bufp, len);
	str[len] = 0;
	*bufp += len;
	*remain -= len;

	return str;
}

/* Translate an inode field to kernel respresentation. */
static inline int audit_to_inode(struct audit_krule *krule,
				 struct audit_field *f)
{
	if (krule->listnr != AUDIT_FILTER_EXIT ||
	    krule->watch || krule->inode_f)
		return -EINVAL;

	krule->inode_f = f;
	return 0;
}

/* Translate a watch string to kernel respresentation. */
static int audit_to_watch(struct audit_krule *krule, char *path, int len,
			  u32 op)
{
	struct audit_watch *watch;

	if (!audit_ih)
		return -EOPNOTSUPP;

	if (path[0] != '/' || path[len-1] == '/' ||
	    krule->listnr != AUDIT_FILTER_EXIT ||
	    op & ~AUDIT_EQUAL ||
	    krule->inode_f || krule->watch) /* 1 inode # per rule, for hash */
		return -EINVAL;

	watch = audit_init_watch(path);
	if (unlikely(IS_ERR(watch)))
		return PTR_ERR(watch);

	audit_get_watch(watch);
	krule->watch = watch;

	return 0;
}

static __u32 *classes[AUDIT_SYSCALL_CLASSES];

int __init audit_register_class(int class, unsigned *list)
{
	__u32 *p = kzalloc(AUDIT_BITMASK_SIZE * sizeof(__u32), GFP_KERNEL);
	if (!p)
		return -ENOMEM;
	while (*list != ~0U) {
		unsigned n = *list++;
		if (n >= AUDIT_BITMASK_SIZE * 32 - AUDIT_SYSCALL_CLASSES) {
			kfree(p);
			return -EINVAL;
		}
		p[AUDIT_WORD(n)] |= AUDIT_BIT(n);
	}
	if (class >= AUDIT_SYSCALL_CLASSES || classes[class]) {
		kfree(p);
		return -EINVAL;
	}
	classes[class] = p;
	return 0;
}

/* Common user-space to kernel rule translation. */
static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule)
{
	unsigned listnr;
	struct audit_entry *entry;
	int i, err;

	err = -EINVAL;
	listnr = rule->flags & ~AUDIT_FILTER_PREPEND;
	switch(listnr) {
	default:
		goto exit_err;
	case AUDIT_FILTER_USER:
	case AUDIT_FILTER_TYPE:
#ifdef CONFIG_AUDITSYSCALL
	case AUDIT_FILTER_ENTRY:
	case AUDIT_FILTER_EXIT:
	case AUDIT_FILTER_TASK:
#endif
		;
	}
	if (unlikely(rule->action == AUDIT_POSSIBLE)) {
		printk(KERN_ERR "AUDIT_POSSIBLE is deprecated\n");
		goto exit_err;
	}
	if (rule->action != AUDIT_NEVER && rule->action != AUDIT_ALWAYS)
		goto exit_err;
	if (rule->field_count > AUDIT_MAX_FIELDS)
		goto exit_err;

	err = -ENOMEM;
	entry = audit_init_entry(rule->field_count);
	if (!entry)
		goto exit_err;

	entry->rule.flags = rule->flags & AUDIT_FILTER_PREPEND;
	entry->rule.listnr = listnr;
	entry->rule.action = rule->action;
	entry->rule.field_count = rule->field_count;

	for (i = 0; i < AUDIT_BITMASK_SIZE; i++)
		entry->rule.mask[i] = rule->mask[i];

	for (i = 0; i < AUDIT_SYSCALL_CLASSES; i++) {
		int bit = AUDIT_BITMASK_SIZE * 32 - i - 1;
		__u32 *p = &entry->rule.mask[AUDIT_WORD(bit)];
		__u32 *class;

		if (!(*p & AUDIT_BIT(bit)))
			continue;
		*p &= ~AUDIT_BIT(bit);
		class = classes[i];
		if (class) {
			int j;
			for (j = 0; j < AUDIT_BITMASK_SIZE; j++)
				entry->rule.mask[j] |= class[j];
		}
	}

	return entry;

exit_err:
	return ERR_PTR(err);
}

/* Translate struct audit_rule to kernel's rule respresentation.
 * Exists for backward compatibility with userspace. */
static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
{
	struct audit_entry *entry;
	struct audit_field *f;
	int err = 0;
	int i;

	entry = audit_to_entry_common(rule);
	if (IS_ERR(entry))
		goto exit_nofree;

	for (i = 0; i < rule->field_count; i++) {
		struct audit_field *f = &entry->rule.fields[i];

		f->op = rule->fields[i] & (AUDIT_NEGATE|AUDIT_OPERATORS);
		f->type = rule->fields[i] & ~(AUDIT_NEGATE|AUDIT_OPERATORS);
		f->val = rule->values[i];

		err = -EINVAL;
		switch(f->type) {
		default:
			goto exit_free;
		case AUDIT_PID:
		case AUDIT_UID:
		case AUDIT_EUID:
		case AUDIT_SUID:
		case AUDIT_FSUID:
		case AUDIT_GID:
		case AUDIT_EGID:
		case AUDIT_SGID:
		case AUDIT_FSGID:
		case AUDIT_LOGINUID:
		case AUDIT_PERS:
		case AUDIT_ARCH:
		case AUDIT_MSGTYPE:
		case AUDIT_DEVMAJOR:
		case AUDIT_DEVMINOR:
		case AUDIT_EXIT:
		case AUDIT_SUCCESS:
		case AUDIT_ARG0:
		case AUDIT_ARG1:
		case AUDIT_ARG2:
		case AUDIT_ARG3:
			break;
		case AUDIT_INODE:
			err = audit_to_inode(&entry->rule, f);
			if (err)
				goto exit_free;
			break;
		}

		entry->rule.vers_ops = (f->op & AUDIT_OPERATORS) ? 2 : 1;

		/* Support for legacy operators where
		 * AUDIT_NEGATE bit signifies != and otherwise assumes == */
		if (f->op & AUDIT_NEGATE)
			f->op = AUDIT_NOT_EQUAL;
		else if (!f->op)
			f->op = AUDIT_EQUAL;
		else if (f->op == AUDIT_OPERATORS) {
			err = -EINVAL;
			goto exit_free;
		}
	}

	f = entry->rule.inode_f;
	if (f) {
		switch(f->op) {
		case AUDIT_NOT_EQUAL:
			entry->rule.inode_f = NULL;
		case AUDIT_EQUAL:
			break;
		default:
			goto exit_free;
		}
	}

exit_nofree:
	return entry;

exit_free:
	audit_free_rule(entry);
	return ERR_PTR(err);
}

/* Translate struct audit_rule_data to kernel's rule respresentation. */
static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
					       size_t datasz)
{
	int err = 0;
	struct audit_entry *entry;
	struct audit_field *f;
	void *bufp;
	size_t remain = datasz - sizeof(struct audit_rule_data);
	int i;
	char *str;

	entry = audit_to_entry_common((struct audit_rule *)data);
	if (IS_ERR(entry))
		goto exit_nofree;

	bufp = data->buf;
	entry->rule.vers_ops = 2;
	for (i = 0; i < data->field_count; i++) {
		struct audit_field *f = &entry->rule.fields[i];

		err = -EINVAL;
		if (!(data->fieldflags[i] & AUDIT_OPERATORS) ||
		    data->fieldflags[i] & ~AUDIT_OPERATORS)
			goto exit_free;

		f->op = data->fieldflags[i] & AUDIT_OPERATORS;
		f->type = data->fields[i];
		f->val = data->values[i];
		f->se_str = NULL;
		f->se_rule = NULL;
		switch(f->type) {
		case AUDIT_PID:
		case AUDIT_UID:
		case AUDIT_EUID:
		case AUDIT_SUID:
		case AUDIT_FSUID:
		case AUDIT_GID:
		case AUDIT_EGID:
		case AUDIT_SGID:
		case AUDIT_FSGID:
		case AUDIT_LOGINUID:
		case AUDIT_PERS:
		case AUDIT_ARCH:
		case AUDIT_MSGTYPE:
		case AUDIT_PPID:
		case AUDIT_DEVMAJOR:
		case AUDIT_DEVMINOR:
		case AUDIT_EXIT:
		case AUDIT_SUCCESS:
		case AUDIT_ARG0:
		case AUDIT_ARG1:
		case AUDIT_ARG2:
		case AUDIT_ARG3:
			break;
		case AUDIT_SUBJ_USER:
		case AUDIT_SUBJ_ROLE:
		case AUDIT_SUBJ_TYPE:
		case AUDIT_SUBJ_SEN:
		case AUDIT_SUBJ_CLR:
		case AUDIT_OBJ_USER:
		case AUDIT_OBJ_ROLE:
		case AUDIT_OBJ_TYPE:
		case AUDIT_OBJ_LEV_LOW:
		case AUDIT_OBJ_LEV_HIGH:
			str = audit_unpack_string(&bufp, &remain, f->val);
			if (IS_ERR(str))
				goto exit_free;
			entry->rule.buflen += f->val;

			err = selinux_audit_rule_init(f->type, f->op, str,
						      &f->se_rule);
			/* Keep currently invalid fields around in case they
			 * become valid after a policy reload. */
			if (err == -EINVAL) {
				printk(KERN_WARNING "audit rule for selinux "
				       "\'%s\' is invalid\n",  str);
				err = 0;
			}
			if (err) {
				kfree(str);
				goto exit_free;
			} else
				f->se_str = str;
			break;
		case AUDIT_WATCH:
			str = audit_unpack_string(&bufp, &remain, f->val);
			if (IS_ERR(str))
				goto exit_free;
			entry->rule.buflen += f->val;

			err = audit_to_watch(&entry->rule, str, f->val, f->op);
			if (err) {
				kfree(str);
				goto exit_free;
			}
			break;
		case AUDIT_INODE:
			err = audit_to_inode(&entry->rule, f);
			if (err)
				goto exit_free;
			break;
		case AUDIT_FILTERKEY:
			err = -EINVAL;
			if (entry->rule.filterkey || f->val > AUDIT_MAX_KEY_LEN)
				goto exit_free;
			str = audit_unpack_string(&bufp, &remain, f->val);
			if (IS_ERR(str))
				goto exit_free;
			entry->rule.buflen += f->val;
			entry->rule.filterkey = str;
			break;
		default:
			goto exit_free;
		}
	}

	f = entry->rule.inode_f;
	if (f) {
		switch(f->op) {
		case AUDIT_NOT_EQUAL:
			entry->rule.inode_f = NULL;
		case AUDIT_EQUAL:
			break;
		default:
			goto exit_free;
		}
	}

exit_nofree:
	return entry;

exit_free:
	audit_free_rule(entry);
	return ERR_PTR(err);
}

/* Pack a filter field's string representation into data block. */
static inline size_t audit_pack_string(void **bufp, char *str)
{
	size_t len = strlen(str);

	memcpy(*bufp, str, len);
	*bufp += len;

	return len;
}

/* Translate kernel rule respresentation to struct audit_rule.
 * Exists for backward compatibility with userspace. */
static struct audit_rule *audit_krule_to_rule(struct audit_krule *krule)
{
	struct audit_rule *rule;
	int i;

	rule = kmalloc(sizeof(*rule), GFP_KERNEL);
	if (unlikely(!rule))
		return NULL;
	memset(rule, 0, sizeof(*rule));

	rule->flags = krule->flags | krule->listnr;
	rule->action = krule->action;
	rule->field_count = krule->field_count;
	for (i = 0; i < rule->field_count; i++) {
		rule->values[i] = krule->fields[i].val;
		rule->fields[i] = krule->fields[i].type;

		if (krule->vers_ops == 1) {
			if (krule->fields[i].op & AUDIT_NOT_EQUAL)
				rule->fields[i] |= AUDIT_NEGATE;
		} else {
			rule->fields[i] |= krule->fields[i].op;
		}
	}
	for (i = 0; i < AUDIT_BITMASK_SIZE; i++) rule->mask[i] = krule->mask[i];

	return rule;
}

/* Translate kernel rule respresentation to struct audit_rule_data. */
static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule)
{
	struct audit_rule_data *data;
	void *bufp;
	int i;

	data = kmalloc(sizeof(*data) + krule->buflen, GFP_KERNEL);
	if (unlikely(!data))
		return NULL;
	memset(data, 0, sizeof(*data));

	data->flags = krule->flags | krule->listnr;
	data->action = krule->action;
	data->field_count = krule->field_count;
	bufp = data->buf;
	for (i = 0; i < data->field_count; i++) {
		struct audit_field *f = &krule->fields[i];

		data->fields[i] = f->type;
		data->fieldflags[i] = f->op;
		switch(f->type) {
		case AUDIT_SUBJ_USER:
		case AUDIT_SUBJ_ROLE:
		case AUDIT_SUBJ_TYPE:
		case AUDIT_SUBJ_SEN:
		case AUDIT_SUBJ_CLR:
		case AUDIT_OBJ_USER:
		case AUDIT_OBJ_ROLE:
		case AUDIT_OBJ_TYPE:
		case AUDIT_OBJ_LEV_LOW:
		case AUDIT_OBJ_LEV_HIGH:
			data->buflen += data->values[i] =
				audit_pack_string(&bufp, f->se_str);
			break;
		case AUDIT_WATCH:
			data->buflen += data->values[i] =
				audit_pack_string(&bufp, krule->watch->path);
			break;
		case AUDIT_FILTERKEY:
			data->buflen += data->values[i] =
				audit_pack_string(&bufp, krule->filterkey);
			break;
		default:
			data->values[i] = f->val;
		}
	}
	for (i = 0; i < AUDIT_BITMASK_SIZE; i++) data->mask[i] = krule->mask[i];

	return data;
}

/* Compare two rules in kernel format.  Considered success if rules
 * don't match. */
static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b)
{
	int i;

	if (a->flags != b->flags ||
	    a->listnr != b->listnr ||
	    a->action != b->action ||
	    a->field_count != b->field_count)
		return 1;

	for (i = 0; i < a->field_count; i++) {
		if (a->fields[i].type != b->fields[i].type ||
		    a->fields[i].op != b->fields[i].op)
			return 1;

		switch(a->fields[i].type) {
		case AUDIT_SUBJ_USER:
		case AUDIT_SUBJ_ROLE:
		case AUDIT_SUBJ_TYPE:
		case AUDIT_SUBJ_SEN:
		case AUDIT_SUBJ_CLR:
		case AUDIT_OBJ_USER:
		case AUDIT_OBJ_ROLE:
		case AUDIT_OBJ_TYPE:
		case AUDIT_OBJ_LEV_LOW:
		case AUDIT_OBJ_LEV_HIGH:
			if (strcmp(a->fields[i].se_str, b->fields[i].se_str))
				return 1;
			break;
		case AUDIT_WATCH:
			if (strcmp(a->watch->path, b->watch->path))
				return 1;
			break;
		case AUDIT_FILTERKEY:
			/* both filterkeys exist based on above type compare */
			if (strcmp(a->filterkey, b->filterkey))
				return 1;
			break;
		default:
			if (a->fields[i].val != b->fields[i].val)
				return 1;
		}
	}

	for (i = 0; i < AUDIT_BITMASK_SIZE; i++)
		if (a->mask[i] != b->mask[i])
			return 1;

	return 0;
}

/* Duplicate the given audit watch.  The new watch's rules list is initialized
 * to an empty list and wlist is undefined. */
static struct audit_watch *audit_dupe_watch(struct audit_watch *old)
{
	char *path;
	struct audit_watch *new;

	path = kstrdup(old->path, GFP_KERNEL);
	if (unlikely(!path))
		return ERR_PTR(-ENOMEM);

	new = audit_init_watch(path);
	if (unlikely(IS_ERR(new))) {
		kfree(path);
		goto out;
	}

	new->dev = old->dev;
	new->ino = old->ino;
	get_inotify_watch(&old->parent->wdata);
	new->parent = old->parent;

out:
	return new;
}

/* Duplicate selinux field information.  The se_rule is opaque, so must be
 * re-initialized. */
static inline int audit_dupe_selinux_field(struct audit_field *df,
					   struct audit_field *sf)
{
	int ret = 0;
	char *se_str;

	/* our own copy of se_str */
	se_str = kstrdup(sf->se_str, GFP_KERNEL);
	if (unlikely(IS_ERR(se_str)))
	    return -ENOMEM;
	df->se_str = se_str;

	/* our own (refreshed) copy of se_rule */
	ret = selinux_audit_rule_init(df->type, df->op, df->se_str,
				      &df->se_rule);
	/* Keep currently invalid fields around in case they
	 * become valid after a policy reload. */
	if (ret == -EINVAL) {
		printk(KERN_WARNING "audit rule for selinux \'%s\' is "
		       "invalid\n", df->se_str);
		ret = 0;
	}

	return ret;
}

/* Duplicate an audit rule.  This will be a deep copy with the exception
 * of the watch - that pointer is carried over.  The selinux specific fields
 * will be updated in the copy.  The point is to be able to replace the old
 * rule with the new rule in the filterlist, then free the old rule.
 * The rlist element is undefined; list manipulations are handled apart from
 * the initial copy. */
static struct audit_entry *audit_dupe_rule(struct audit_krule *old,
					   struct audit_watch *watch)
{
	u32 fcount = old->field_count;
	struct audit_entry *entry;
	struct audit_krule *new;
	char *fk;
	int i, err = 0;

	entry = audit_init_entry(fcount);
	if (unlikely(!entry))
		return ERR_PTR(-ENOMEM);

	new = &entry->rule;
	new->vers_ops = old->vers_ops;
	new->flags = old->flags;
	new->listnr = old->listnr;
	new->action = old->action;
	for (i = 0; i < AUDIT_BITMASK_SIZE; i++)
		new->mask[i] = old->mask[i];
	new->buflen = old->buflen;
	new->inode_f = old->inode_f;
	new->watch = NULL;
	new->field_count = old->field_count;
	memcpy(new->fields, old->fields, sizeof(struct audit_field) * fcount);

	/* deep copy this information, updating the se_rule fields, because
	 * the originals will all be freed when the old rule is freed. */
	for (i = 0; i < fcount; i++) {
		switch (new->fields[i].type) {
		case AUDIT_SUBJ_USER:
		case AUDIT_SUBJ_ROLE:
		case AUDIT_SUBJ_TYPE:
		case AUDIT_SUBJ_SEN:
		case AUDIT_SUBJ_CLR:
		case AUDIT_OBJ_USER:
		case AUDIT_OBJ_ROLE:
		case AUDIT_OBJ_TYPE:
		case AUDIT_OBJ_LEV_LOW:
		case AUDIT_OBJ_LEV_HIGH:
			err = audit_dupe_selinux_field(&new->fields[i],
						       &old->fields[i]);
			break;
		case AUDIT_FILTERKEY:
			fk = kstrdup(old->filterkey, GFP_KERNEL);
			if (unlikely(!fk))
				err = -ENOMEM;
			else
				new->filterkey = fk;
		}
		if (err) {
			audit_free_rule(entry);
			return ERR_PTR(err);
		}
	}

	if (watch) {
		audit_get_watch(watch);
		new->watch = watch;
	}

	return entry;
}

/* Update inode info in audit rules based on filesystem event. */
static void audit_update_watch(struct audit_parent *parent,
			       const char *dname, dev_t dev,
			       unsigned long ino, unsigned invalidating)
{
	struct audit_watch *owatch, *nwatch, *nextw;
	struct audit_krule *r, *nextr;
	struct audit_entry *oentry, *nentry;
	struct audit_buffer *ab;

	mutex_lock(&audit_filter_mutex);
	list_for_each_entry_safe(owatch, nextw, &parent->watches, wlist) {
		if (audit_compare_dname_path(dname, owatch->path, NULL))
			continue;

		/* If the update involves invalidating rules, do the inode-based
		 * filtering now, so we don't omit records. */
		if (invalidating &&
		    audit_filter_inodes(current, current->audit_context) == AUDIT_RECORD_CONTEXT)
			audit_set_auditable(current->audit_context);

		nwatch = audit_dupe_watch(owatch);
		if (unlikely(IS_ERR(nwatch))) {
			mutex_unlock(&audit_filter_mutex);
			audit_panic("error updating watch, skipping");
			return;
		}
		nwatch->dev = dev;
		nwatch->ino = ino;

		list_for_each_entry_safe(r, nextr, &owatch->rules, rlist) {

			oentry = container_of(r, struct audit_entry, rule);
			list_del(&oentry->rule.rlist);
			list_del_rcu(&oentry->list);

			nentry = audit_dupe_rule(&oentry->rule, nwatch);
			if (unlikely(IS_ERR(nentry)))
				audit_panic("error updating watch, removing");
			else {
				int h = audit_hash_ino((u32)ino);
				list_add(&nentry->rule.rlist, &nwatch->rules);
				list_add_rcu(&nentry->list, &audit_inode_hash[h]);
			}

			call_rcu(&oentry->rcu, audit_free_rule_rcu);
		}

		ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
		audit_log_format(ab, "audit updated rules specifying watch=");
		audit_log_untrustedstring(ab, owatch->path);
		audit_log_format(ab, " with dev=%u ino=%lu\n", dev, ino);
		audit_log_end(ab);

		audit_remove_watch(owatch);
		goto add_watch_to_parent; /* event applies to a single watch */
	}
	mutex_unlock(&audit_filter_mutex);
	return;

add_watch_to_parent:
	list_add(&nwatch->wlist, &parent->watches);
	mutex_unlock(&audit_filter_mutex);
	return;
}

/* Remove all watches & rules associated with a parent that is going away. */
static void audit_remove_parent_watches(struct audit_parent *parent)
{
	struct audit_watch *w, *nextw;
	struct audit_krule *r, *nextr;
	struct audit_entry *e;

	mutex_lock(&audit_filter_mutex);
	parent->flags |= AUDIT_PARENT_INVALID;
	list_for_each_entry_safe(w, nextw, &parent->watches, wlist) {
		list_for_each_entry_safe(r, nextr, &w->rules, rlist) {
			e = container_of(r, struct audit_entry, rule);
			list_del(&r->rlist);
			list_del_rcu(&e->list);
			call_rcu(&e->rcu, audit_free_rule_rcu);

			audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
				 "audit implicitly removed rule from list=%d\n",
				  AUDIT_FILTER_EXIT);
		}
		audit_remove_watch(w);
	}
	mutex_unlock(&audit_filter_mutex);
}

/* Unregister inotify watches for parents on in_list.
 * Generates an IN_IGNORED event. */
static void audit_inotify_unregister(struct list_head *in_list)
{
	struct audit_parent *p, *n;

	list_for_each_entry_safe(p, n, in_list, ilist) {
		list_del(&p->ilist);
		inotify_rm_watch(audit_ih, &p->wdata);
		/* the put matching the get in audit_do_del_rule() */
		put_inotify_watch(&p->wdata);
	}
}

/* Find an existing audit rule.
 * Caller must hold audit_filter_mutex to prevent stale rule data. */
static struct audit_entry *audit_find_rule(struct audit_entry *entry,
					   struct list_head *list)
{
	struct audit_entry *e, *found = NULL;
	int h;

	if (entry->rule.watch) {
		/* we don't know the inode number, so must walk entire hash */
		for (h = 0; h < AUDIT_INODE_BUCKETS; h++) {
			list = &audit_inode_hash[h];
			list_for_each_entry(e, list, list)
				if (!audit_compare_rule(&entry->rule, &e->rule)) {
					found = e;
					goto out;
				}
		}
		goto out;
	}

	list_for_each_entry(e, list, list)
		if (!audit_compare_rule(&entry->rule, &e->rule)) {
			found = e;
			goto out;
		}

out:
	return found;
}

/* Get path information necessary for adding watches. */
static int audit_get_nd(char *path, struct nameidata **ndp,
			struct nameidata **ndw)
{
	struct nameidata *ndparent, *ndwatch;
	int err;

	ndparent = kmalloc(sizeof(*ndparent), GFP_KERNEL);
	if (unlikely(!ndparent))
		return -ENOMEM;

	ndwatch = kmalloc(sizeof(*ndwatch), GFP_KERNEL);
	if (unlikely(!ndwatch)) {
		kfree(ndparent);
		return -ENOMEM;
	}

	err = path_lookup(path, LOOKUP_PARENT, ndparent);
	if (err) {
		kfree(ndparent);
		kfree(ndwatch);
		return err;
	}

	err = path_lookup(path, 0, ndwatch);
	if (err) {
		kfree(ndwatch);
		ndwatch = NULL;
	}

	*ndp = ndparent;
	*ndw = ndwatch;

	return 0;
}

/* Release resources used for watch path information. */
static void audit_put_nd(struct nameidata *ndp, struct nameidata *ndw)
{
	if (ndp) {
		path_release(ndp);
		kfree(ndp);
	}
	if (ndw) {
		path_release(ndw);
		kfree(ndw);
	}
}

/* Associate the given rule with an existing parent inotify_watch.
 * Caller must hold audit_filter_mutex. */
static void audit_add_to_parent(struct audit_krule *krule,
				struct audit_parent *parent)
{
	struct audit_watch *w, *watch = krule->watch;
	int watch_found = 0;

	list_for_each_entry(w, &parent->watches, wlist) {
		if (strcmp(watch->path, w->path))
			continue;

		watch_found = 1;

		/* put krule's and initial refs to temporary watch */
		audit_put_watch(watch);
		audit_put_watch(watch);

		audit_get_watch(w);
		krule->watch = watch = w;
		break;
	}

	if (!watch_found) {
		get_inotify_watch(&parent->wdata);
		watch->parent = parent;

		list_add(&watch->wlist, &parent->watches);
	}
	list_add(&krule->rlist, &watch->rules);
}

/* Find a matching watch entry, or add this one.
 * Caller must hold audit_filter_mutex. */
static int audit_add_watch(struct audit_krule *krule, struct nameidata *ndp,
			   struct nameidata *ndw)
{
	struct audit_watch *watch = krule->watch;
	struct inotify_watch *i_watch;
	struct audit_parent *parent;
	int ret = 0;

	/* update watch filter fields */
	if (ndw) {
		watch->dev = ndw->dentry->d_inode->i_sb->s_dev;
		watch->ino = ndw->dentry->d_inode->i_ino;
	}

	/* The audit_filter_mutex must not be held during inotify calls because
	 * we hold it during inotify event callback processing.  If an existing
	 * inotify watch is found, inotify_find_watch() grabs a reference before
	 * returning.
	 */
	mutex_unlock(&audit_filter_mutex);

	if (inotify_find_watch(audit_ih, ndp->dentry->d_inode, &i_watch) < 0) {
		parent = audit_init_parent(ndp);
		if (IS_ERR(parent)) {
			/* caller expects mutex locked */
			mutex_lock(&audit_filter_mutex);
			return PTR_ERR(parent);
		}
	} else
		parent = container_of(i_watch, struct audit_parent, wdata);

	mutex_lock(&audit_filter_mutex);

	/* parent was moved before we took audit_filter_mutex */
	if (parent->flags & AUDIT_PARENT_INVALID)
		ret = -ENOENT;
	else
		audit_add_to_parent(krule, parent);

	/* match get in audit_init_parent or inotify_find_watch */
	put_inotify_watch(&parent->wdata);
	return ret;
}

/* Add rule to given filterlist if not a duplicate. */
static inline int audit_add_rule(struct audit_entry *entry,
				 struct list_head *list)
{
	struct audit_entry *e;
	struct audit_field *inode_f = entry->rule.inode_f;
	struct audit_watch *watch = entry->rule.watch;
	struct nameidata *ndp, *ndw;
	int h, err, putnd_needed = 0;

	if (inode_f) {
		h = audit_hash_ino(inode_f->val);
		list = &audit_inode_hash[h];
	}

	mutex_lock(&audit_filter_mutex);
	e = audit_find_rule(entry, list);
	mutex_unlock(&audit_filter_mutex);
	if (e) {
		err = -EEXIST;
		goto error;
	}

	/* Avoid calling path_lookup under audit_filter_mutex. */
	if (watch) {
		err = audit_get_nd(watch->path, &ndp, &ndw);
		if (err)
			goto error;
		putnd_needed = 1;
	}

	mutex_lock(&audit_filter_mutex);
	if (watch) {
		/* audit_filter_mutex is dropped and re-taken during this call */
		err = audit_add_watch(&entry->rule, ndp, ndw);
		if (err) {
			mutex_unlock(&audit_filter_mutex);
			goto error;
		}
		h = audit_hash_ino((u32)watch->ino);
		list = &audit_inode_hash[h];
	}

	if (entry->rule.flags & AUDIT_FILTER_PREPEND) {
		list_add_rcu(&entry->list, list);
		entry->rule.flags &= ~AUDIT_FILTER_PREPEND;
	} else {
		list_add_tail_rcu(&entry->list, list);
	}
	mutex_unlock(&audit_filter_mutex);

	if (putnd_needed)
		audit_put_nd(ndp, ndw);

 	return 0;

error:
	if (putnd_needed)
		audit_put_nd(ndp, ndw);
	if (watch)
		audit_put_watch(watch); /* tmp watch, matches initial get */
	return err;
}

/* Remove an existing rule from filterlist. */
static inline int audit_del_rule(struct audit_entry *entry,
				 struct list_head *list)
{
	struct audit_entry  *e;
	struct audit_field *inode_f = entry->rule.inode_f;
	struct audit_watch *watch, *tmp_watch = entry->rule.watch;
	LIST_HEAD(inotify_list);
	int h, ret = 0;

	if (inode_f) {
		h = audit_hash_ino(inode_f->val);
		list = &audit_inode_hash[h];
	}

	mutex_lock(&audit_filter_mutex);
	e = audit_find_rule(entry, list);
	if (!e) {
		mutex_unlock(&audit_filter_mutex);
		ret = -ENOENT;
		goto out;
	}

	watch = e->rule.watch;
	if (watch) {
		struct audit_parent *parent = watch->parent;

		list_del(&e->rule.rlist);

		if (list_empty(&watch->rules)) {
			audit_remove_watch(watch);

			if (list_empty(&parent->watches)) {
				/* Put parent on the inotify un-registration
				 * list.  Grab a reference before releasing
				 * audit_filter_mutex, to be released in
				 * audit_inotify_unregister(). */
				list_add(&parent->ilist, &inotify_list);
				get_inotify_watch(&parent->wdata);
			}
		}
	}

	list_del_rcu(&e->list);
	call_rcu(&e->rcu, audit_free_rule_rcu);

	mutex_unlock(&audit_filter_mutex);

	if (!list_empty(&inotify_list))
		audit_inotify_unregister(&inotify_list);

out:
	if (tmp_watch)
		audit_put_watch(tmp_watch); /* match initial get */

	return ret;
}

/* List rules using struct audit_rule.  Exists for backward
 * compatibility with userspace. */
static void audit_list(int pid, int seq, struct sk_buff_head *q)
{
	struct sk_buff *skb;
	struct audit_entry *entry;
	int i;

	/* This is a blocking read, so use audit_filter_mutex instead of rcu
	 * iterator to sync with list writers. */
	for (i=0; i<AUDIT_NR_FILTERS; i++) {
		list_for_each_entry(entry, &audit_filter_list[i], list) {
			struct audit_rule *rule;

			rule = audit_krule_to_rule(&entry->rule);
			if (unlikely(!rule))
				break;
			skb = audit_make_reply(pid, seq, AUDIT_LIST, 0, 1,
					 rule, sizeof(*rule));
			if (skb)
				skb_queue_tail(q, skb);
			kfree(rule);
		}
	}
	for (i = 0; i < AUDIT_INODE_BUCKETS; i++) {
		list_for_each_entry(entry, &audit_inode_hash[i], list) {
			struct audit_rule *rule;

			rule = audit_krule_to_rule(&entry->rule);
			if (unlikely(!rule))
				break;
			skb = audit_make_reply(pid, seq, AUDIT_LIST, 0, 1,
					 rule, sizeof(*rule));
			if (skb)
				skb_queue_tail(q, skb);
			kfree(rule);
		}
	}
	skb = audit_make_reply(pid, seq, AUDIT_LIST, 1, 1, NULL, 0);
	if (skb)
		skb_queue_tail(q, skb);
}

/* List rules using struct audit_rule_data. */
static void audit_list_rules(int pid, int seq, struct sk_buff_head *q)
{
	struct sk_buff *skb;
	struct audit_entry *e;
	int i;

	/* This is a blocking read, so use audit_filter_mutex instead of rcu
	 * iterator to sync with list writers. */
	for (i=0; i<AUDIT_NR_FILTERS; i++) {
		list_for_each_entry(e, &audit_filter_list[i], list) {
			struct audit_rule_data *data;

			data = audit_krule_to_data(&e->rule);
			if (unlikely(!data))
				break;
			skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 0, 1,
					 data, sizeof(*data) + data->buflen);
			if (skb)
				skb_queue_tail(q, skb);
			kfree(data);
		}
	}
	for (i=0; i< AUDIT_INODE_BUCKETS; i++) {
		list_for_each_entry(e, &audit_inode_hash[i], list) {
			struct audit_rule_data *data;

			data = audit_krule_to_data(&e->rule);
			if (unlikely(!data))
				break;
			skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 0, 1,
					 data, sizeof(*data) + data->buflen);
			if (skb)
				skb_queue_tail(q, skb);
			kfree(data);
		}
	}
	skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 1, 1, NULL, 0);
	if (skb)
		skb_queue_tail(q, skb);
}

/* Log rule additions and removals */
static void audit_log_rule_change(uid_t loginuid, u32 sid, char *action,
				  struct audit_krule *rule, int res)
{
	struct audit_buffer *ab;

	ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
	if (!ab)
		return;
	audit_log_format(ab, "auid=%u", loginuid);
	if (sid) {
		char *ctx = NULL;
		u32 len;
		if (selinux_ctxid_to_string(sid, &ctx, &len))
			audit_log_format(ab, " ssid=%u", sid);
		else
			audit_log_format(ab, " subj=%s", ctx);
		kfree(ctx);
	}
	audit_log_format(ab, " %s rule key=", action);
	if (rule->filterkey)
		audit_log_untrustedstring(ab, rule->filterkey);
	else
		audit_log_format(ab, "(null)");
	audit_log_format(ab, " list=%d res=%d", rule->listnr, res);
	audit_log_end(ab);
}

/**
 * audit_receive_filter - apply all rules to the specified message type
 * @type: audit message type
 * @pid: target pid for netlink audit messages
 * @uid: target uid for netlink audit messages
 * @seq: netlink audit message sequence (serial) number
 * @data: payload data
 * @datasz: size of payload data
 * @loginuid: loginuid of sender
 * @sid: SE Linux Security ID of sender
 */
int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
			 size_t datasz, uid_t loginuid, u32 sid)
{
	struct task_struct *tsk;
	struct audit_netlink_list *dest;
	int err = 0;
	struct audit_entry *entry;

	switch (type) {
	case AUDIT_LIST:
	case AUDIT_LIST_RULES:
		/* We can't just spew out the rules here because we might fill
		 * the available socket buffer space and deadlock waiting for
		 * auditctl to read from it... which isn't ever going to
		 * happen if we're actually running in the context of auditctl
		 * trying to _send_ the stuff */
		 
		dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL);
		if (!dest)
			return -ENOMEM;
		dest->pid = pid;
		skb_queue_head_init(&dest->q);

		mutex_lock(&audit_filter_mutex);
		if (type == AUDIT_LIST)
			audit_list(pid, seq, &dest->q);
		else
			audit_list_rules(pid, seq, &dest->q);
		mutex_unlock(&audit_filter_mutex);

		tsk = kthread_run(audit_send_list, dest, "audit_send_list");
		if (IS_ERR(tsk)) {
			skb_queue_purge(&dest->q);
			kfree(dest);
			err = PTR_ERR(tsk);
		}
		break;
	case AUDIT_ADD:
	case AUDIT_ADD_RULE:
		if (type == AUDIT_ADD)
			entry = audit_rule_to_entry(data);
		else
			entry = audit_data_to_entry(data, datasz);
		if (IS_ERR(entry))
			return PTR_ERR(entry);

		err = audit_add_rule(entry,
				     &audit_filter_list[entry->rule.listnr]);
		audit_log_rule_change(loginuid, sid, "add", &entry->rule, !err);

		if (err)
			audit_free_rule(entry);
		break;
	case AUDIT_DEL:
	case AUDIT_DEL_RULE:
		if (type == AUDIT_DEL)
			entry = audit_rule_to_entry(data);
		else
			entry = audit_data_to_entry(data, datasz);
		if (IS_ERR(entry))
			return PTR_ERR(entry);

		err = audit_del_rule(entry,
				     &audit_filter_list[entry->rule.listnr]);
		audit_log_rule_change(loginuid, sid, "remove", &entry->rule,
				      !err);

		audit_free_rule(entry);
		break;
	default:
		return -EINVAL;
	}

	return err;
}

int audit_comparator(const u32 left, const u32 op, const u32 right)
{
	switch (op) {
	case AUDIT_EQUAL:
		return (left == right);
	case AUDIT_NOT_EQUAL:
		return (left != right);
	case AUDIT_LESS_THAN:
		return (left < right);
	case AUDIT_LESS_THAN_OR_EQUAL:
		return (left <= right);
	case AUDIT_GREATER_THAN:
		return (left > right);
	case AUDIT_GREATER_THAN_OR_EQUAL:
		return (left >= right);
	}
	BUG();
	return 0;
}

/* Compare given dentry name with last component in given path,
 * return of 0 indicates a match. */
int audit_compare_dname_path(const char *dname, const char *path,
			     int *dirlen)
{
	int dlen, plen;
	const char *p;

	if (!dname || !path)
		return 1;

	dlen = strlen(dname);
	plen = strlen(path);
	if (plen < dlen)
		return 1;

	/* disregard trailing slashes */
	p = path + plen - 1;
	while ((*p == '/') && (p > path))
		p--;

	/* find last path component */
	p = p - dlen + 1;
	if (p < path)
		return 1;
	else if (p > path) {
		if (*--p != '/')
			return 1;
		else
			p++;
	}

	/* return length of path's directory component */
	if (dirlen)
		*dirlen = p - path;
	return strncmp(p, dname, dlen);
}

static int audit_filter_user_rules(struct netlink_skb_parms *cb,
				   struct audit_krule *rule,
				   enum audit_state *state)
{
	int i;

	for (i = 0; i < rule->field_count; i++) {
		struct audit_field *f = &rule->fields[i];
		int result = 0;

		switch (f->type) {
		case AUDIT_PID:
			result = audit_comparator(cb->creds.pid, f->op, f->val);
			break;
		case AUDIT_UID:
			result = audit_comparator(cb->creds.uid, f->op, f->val);
			break;
		case AUDIT_GID:
			result = audit_comparator(cb->creds.gid, f->op, f->val);
			break;
		case AUDIT_LOGINUID:
			result = audit_comparator(cb->loginuid, f->op, f->val);
			break;
		}

		if (!result)
			return 0;
	}
	switch (rule->action) {
	case AUDIT_NEVER:    *state = AUDIT_DISABLED;	    break;
	case AUDIT_ALWAYS:   *state = AUDIT_RECORD_CONTEXT; break;
	}
	return 1;
}

int audit_filter_user(struct netlink_skb_parms *cb, int type)
{
	struct audit_entry *e;
	enum audit_state   state;
	int ret = 1;

	rcu_read_lock();
	list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) {
		if (audit_filter_user_rules(cb, &e->rule, &state)) {
			if (state == AUDIT_DISABLED)
				ret = 0;
			break;
		}
	}
	rcu_read_unlock();

	return ret; /* Audit by default */
}

int audit_filter_type(int type)
{
	struct audit_entry *e;
	int result = 0;
	
	rcu_read_lock();
	if (list_empty(&audit_filter_list[AUDIT_FILTER_TYPE]))
		goto unlock_and_return;

	list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TYPE],
				list) {
		int i;
		for (i = 0; i < e->rule.field_count; i++) {
			struct audit_field *f = &e->rule.fields[i];
			if (f->type == AUDIT_MSGTYPE) {
				result = audit_comparator(type, f->op, f->val);
				if (!result)
					break;
			}
		}
		if (result)
			goto unlock_and_return;
	}
unlock_and_return:
	rcu_read_unlock();
	return result;
}

/* Check to see if the rule contains any selinux fields.  Returns 1 if there
   are selinux fields specified in the rule, 0 otherwise. */
static inline int audit_rule_has_selinux(struct audit_krule *rule)
{
	int i;

	for (i = 0; i < rule->field_count; i++) {
		struct audit_field *f = &rule->fields[i];
		switch (f->type) {
		case AUDIT_SUBJ_USER:
		case AUDIT_SUBJ_ROLE:
		case AUDIT_SUBJ_TYPE:
		case AUDIT_SUBJ_SEN:
		case AUDIT_SUBJ_CLR:
		case AUDIT_OBJ_USER:
		case AUDIT_OBJ_ROLE:
		case AUDIT_OBJ_TYPE:
		case AUDIT_OBJ_LEV_LOW:
		case AUDIT_OBJ_LEV_HIGH:
			return 1;
		}
	}

	return 0;
}

/* This function will re-initialize the se_rule field of all applicable rules.
 * It will traverse the filter lists serarching for rules that contain selinux
 * specific filter fields.  When such a rule is found, it is copied, the
 * selinux field is re-initialized, and the old rule is replaced with the
 * updated rule. */
int selinux_audit_rule_update(void)
{
	struct audit_entry *entry, *n, *nentry;
	struct audit_watch *watch;
	int i, err = 0;

	/* audit_filter_mutex synchronizes the writers */
	mutex_lock(&audit_filter_mutex);

	for (i = 0; i < AUDIT_NR_FILTERS; i++) {
		list_for_each_entry_safe(entry, n, &audit_filter_list[i], list) {
			if (!audit_rule_has_selinux(&entry->rule))
				continue;

			watch = entry->rule.watch;
			nentry = audit_dupe_rule(&entry->rule, watch);
			if (unlikely(IS_ERR(nentry))) {
				/* save the first error encountered for the
				 * return value */
				if (!err)
					err = PTR_ERR(nentry);
				audit_panic("error updating selinux filters");
				if (watch)
					list_del(&entry->rule.rlist);
				list_del_rcu(&entry->list);
			} else {
				if (watch) {
					list_add(&nentry->rule.rlist,
						 &watch->rules);
					list_del(&entry->rule.rlist);
				}
				list_replace_rcu(&entry->list, &nentry->list);
			}
			call_rcu(&entry->rcu, audit_free_rule_rcu);
		}
	}

	mutex_unlock(&audit_filter_mutex);

	return err;
}

/* Update watch data in audit rules based on inotify events. */
void audit_handle_ievent(struct inotify_watch *i_watch, u32 wd, u32 mask,
			 u32 cookie, const char *dname, struct inode *inode)
{
	struct audit_parent *parent;

	parent = container_of(i_watch, struct audit_parent, wdata);

	if (mask & (IN_CREATE|IN_MOVED_TO) && inode)
		audit_update_watch(parent, dname, inode->i_sb->s_dev,
				   inode->i_ino, 0);
	else if (mask & (IN_DELETE|IN_MOVED_FROM))
		audit_update_watch(parent, dname, (dev_t)-1, (unsigned long)-1, 1);
	/* inotify automatically removes the watch and sends IN_IGNORED */
	else if (mask & (IN_DELETE_SELF|IN_UNMOUNT))
		audit_remove_parent_watches(parent);
	/* inotify does not remove the watch, so remove it manually */
	else if(mask & IN_MOVE_SELF) {
		audit_remove_parent_watches(parent);
		inotify_remove_watch_locked(audit_ih, i_watch);
	} else if (mask & IN_IGNORED)
		put_inotify_watch(i_watch);
}
