auditfilter.c 34 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/* 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
 */

22 23
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

24 25 26
#include <linux/kernel.h>
#include <linux/audit.h>
#include <linux/kthread.h>
27 28 29
#include <linux/mutex.h>
#include <linux/fs.h>
#include <linux/namei.h>
30
#include <linux/netlink.h>
31
#include <linux/sched.h>
32
#include <linux/slab.h>
33
#include <linux/security.h>
34
#include <net/net_namespace.h>
35
#include <net/sock.h>
36 37
#include "audit.h"

38 39 40 41
/*
 * Locking model:
 *
 * audit_filter_mutex:
42 43 44 45 46 47 48
 *		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
 *		LSM 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.
49 50 51
 */

/* Audit filter lists, defined in <linux/audit.h> */
52 53 54 55 56 57 58 59 60 61 62
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
};
Al Viro's avatar
Al Viro committed
63 64 65 66 67 68 69 70
static struct list_head audit_rules_list[AUDIT_NR_FILTERS] = {
	LIST_HEAD_INIT(audit_rules_list[0]),
	LIST_HEAD_INIT(audit_rules_list[1]),
	LIST_HEAD_INIT(audit_rules_list[2]),
	LIST_HEAD_INIT(audit_rules_list[3]),
	LIST_HEAD_INIT(audit_rules_list[4]),
	LIST_HEAD_INIT(audit_rules_list[5]),
};
71

72
DEFINE_MUTEX(audit_filter_mutex);
73

74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
static void audit_free_lsm_field(struct audit_field *f)
{
	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:
		kfree(f->lsm_str);
		security_audit_rule_free(f->lsm_rule);
	}
}

92
static inline void audit_free_rule(struct audit_entry *e)
93
{
94
	int i;
95
	struct audit_krule *erule = &e->rule;
96

97
	/* some rules don't have associated watches */
98 99 100
	if (erule->watch)
		audit_put_watch(erule->watch);
	if (erule->fields)
101 102
		for (i = 0; i < erule->field_count; i++)
			audit_free_lsm_field(&erule->fields[i]);
103 104
	kfree(erule->fields);
	kfree(erule->filterkey);
105 106 107
	kfree(e);
}

108
void audit_free_rule_rcu(struct rcu_head *head)
109 110 111 112 113
{
	struct audit_entry *e = container_of(head, struct audit_entry, rcu);
	audit_free_rule(e);
}

114 115 116 117 118 119 120 121 122 123
/* 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;

124
	fields = kcalloc(field_count, sizeof(*fields), GFP_KERNEL);
125 126 127 128 129 130 131 132 133
	if (unlikely(!fields)) {
		kfree(entry);
		return NULL;
	}
	entry->rule.fields = fields;

	return entry;
}

134 135
/* Unpack a filter field's string representation from user-space
 * buffer. */
136
char *audit_unpack_string(void **bufp, size_t *remain, size_t len)
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
{
	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;
}

Wei Yuan's avatar
Wei Yuan committed
161
/* Translate an inode field to kernel representation. */
162 163 164 165
static inline int audit_to_inode(struct audit_krule *krule,
				 struct audit_field *f)
{
	if (krule->listnr != AUDIT_FILTER_EXIT ||
166
	    krule->inode_f || krule->watch || krule->tree ||
167
	    (f->op != Audit_equal && f->op != Audit_not_equal))
168 169 170 171 172 173
		return -EINVAL;

	krule->inode_f = f;
	return 0;
}

Al Viro's avatar
Al Viro committed
174 175 176 177
static __u32 *classes[AUDIT_SYSCALL_CLASSES];

int __init audit_register_class(int class, unsigned *list)
{
178
	__u32 *p = kcalloc(AUDIT_BITMASK_SIZE, sizeof(__u32), GFP_KERNEL);
Al Viro's avatar
Al Viro committed
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
	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;
}

197 198
int audit_match_class(int class, unsigned syscall)
{
199
	if (unlikely(syscall >= AUDIT_BITMASK_SIZE * 32))
200 201 202 203 204 205
		return 0;
	if (unlikely(class >= AUDIT_SYSCALL_CLASSES || !classes[class]))
		return 0;
	return classes[class][AUDIT_WORD(syscall)] & AUDIT_BIT(syscall);
}

206
#ifdef CONFIG_AUDITSYSCALL
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
static inline int audit_match_class_bits(int class, u32 *mask)
{
	int i;

	if (classes[class]) {
		for (i = 0; i < AUDIT_BITMASK_SIZE; i++)
			if (mask[i] & classes[class][i])
				return 0;
	}
	return 1;
}

static int audit_match_signal(struct audit_entry *entry)
{
	struct audit_field *arch = entry->rule.arch_f;

	if (!arch) {
		/* When arch is unspecified, we must check both masks on biarch
		 * as syscall number alone is ambiguous. */
		return (audit_match_class_bits(AUDIT_CLASS_SIGNAL,
					       entry->rule.mask) &&
			audit_match_class_bits(AUDIT_CLASS_SIGNAL_32,
					       entry->rule.mask));
	}

	switch(audit_classify_arch(arch->val)) {
	case 0: /* native */
		return (audit_match_class_bits(AUDIT_CLASS_SIGNAL,
					       entry->rule.mask));
	case 1: /* 32bit on biarch */
		return (audit_match_class_bits(AUDIT_CLASS_SIGNAL_32,
					       entry->rule.mask));
	default:
		return 1;
	}
}
243
#endif
244

245
/* Common user-space to kernel rule translation. */
246
static inline struct audit_entry *audit_to_entry_common(struct audit_rule_data *rule)
247 248 249 250 251 252 253 254 255 256 257 258
{
	unsigned listnr;
	struct audit_entry *entry;
	int i, err;

	err = -EINVAL;
	listnr = rule->flags & ~AUDIT_FILTER_PREPEND;
	switch(listnr) {
	default:
		goto exit_err;
#ifdef CONFIG_AUDITSYSCALL
	case AUDIT_FILTER_ENTRY:
259 260
		if (rule->action == AUDIT_ALWAYS)
			goto exit_err;
261 262 263
	case AUDIT_FILTER_EXIT:
	case AUDIT_FILTER_TASK:
#endif
264 265
	case AUDIT_FILTER_USER:
	case AUDIT_FILTER_TYPE:
266 267
		;
	}
268
	if (unlikely(rule->action == AUDIT_POSSIBLE)) {
269
		pr_err("AUDIT_POSSIBLE is deprecated\n");
270 271 272
		goto exit_err;
	}
	if (rule->action != AUDIT_NEVER && rule->action != AUDIT_ALWAYS)
273 274 275 276 277
		goto exit_err;
	if (rule->field_count > AUDIT_MAX_FIELDS)
		goto exit_err;

	err = -ENOMEM;
278 279
	entry = audit_init_entry(rule->field_count);
	if (!entry)
280 281 282 283 284 285 286 287 288 289
		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];

Al Viro's avatar
Al Viro committed
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305
	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];
		}
	}

306 307 308 309 310 311
	return entry;

exit_err:
	return ERR_PTR(err);
}

312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331
static u32 audit_ops[] =
{
	[Audit_equal] = AUDIT_EQUAL,
	[Audit_not_equal] = AUDIT_NOT_EQUAL,
	[Audit_bitmask] = AUDIT_BIT_MASK,
	[Audit_bittest] = AUDIT_BIT_TEST,
	[Audit_lt] = AUDIT_LESS_THAN,
	[Audit_gt] = AUDIT_GREATER_THAN,
	[Audit_le] = AUDIT_LESS_THAN_OR_EQUAL,
	[Audit_ge] = AUDIT_GREATER_THAN_OR_EQUAL,
};

static u32 audit_to_op(u32 op)
{
	u32 n;
	for (n = Audit_equal; n < Audit_bad && audit_ops[n] != op; n++)
		;
	return n;
}

332
/* check if an audit field is valid */
333
static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
334
{
335 336 337 338 339 340 341
	switch(f->type) {
	case AUDIT_MSGTYPE:
		if (entry->rule.listnr != AUDIT_FILTER_TYPE &&
		    entry->rule.listnr != AUDIT_FILTER_USER)
			return -EINVAL;
		break;
	};
342

343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364
	switch(f->type) {
	default:
		return -EINVAL;
	case AUDIT_UID:
	case AUDIT_EUID:
	case AUDIT_SUID:
	case AUDIT_FSUID:
	case AUDIT_LOGINUID:
	case AUDIT_OBJ_UID:
	case AUDIT_GID:
	case AUDIT_EGID:
	case AUDIT_SGID:
	case AUDIT_FSGID:
	case AUDIT_OBJ_GID:
	case AUDIT_PID:
	case AUDIT_PERS:
	case AUDIT_MSGTYPE:
	case AUDIT_PPID:
	case AUDIT_DEVMAJOR:
	case AUDIT_DEVMINOR:
	case AUDIT_EXIT:
	case AUDIT_SUCCESS:
365
	case AUDIT_INODE:
366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387
		/* bit ops are only useful on syscall args */
		if (f->op == Audit_bitmask || f->op == Audit_bittest)
			return -EINVAL;
		break;
	case AUDIT_ARG0:
	case AUDIT_ARG1:
	case AUDIT_ARG2:
	case AUDIT_ARG3:
	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:
	case AUDIT_WATCH:
	case AUDIT_DIR:
	case AUDIT_FILTERKEY:
		break;
388 389 390 391
	case AUDIT_LOGINUID_SET:
		if ((f->val != 0) && (f->val != 1))
			return -EINVAL;
	/* FALL THROUGH */
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407
	case AUDIT_ARCH:
		if (f->op != Audit_not_equal && f->op != Audit_equal)
			return -EINVAL;
		break;
	case AUDIT_PERM:
		if (f->val & ~15)
			return -EINVAL;
		break;
	case AUDIT_FILETYPE:
		if (f->val & ~S_IFMT)
			return -EINVAL;
		break;
	case AUDIT_FIELD_COMPARE:
		if (f->val > AUDIT_MAX_FIELD_COMPARE)
			return -EINVAL;
		break;
408 409 410 411 412 413
	case AUDIT_EXE:
		if (f->op != Audit_equal)
			return -EINVAL;
		if (entry->rule.listnr != AUDIT_FILTER_EXIT)
			return -EINVAL;
		break;
414
	};
415
	return 0;
416 417
}

Wei Yuan's avatar
Wei Yuan committed
418
/* Translate struct audit_rule_data to kernel's rule representation. */
419 420
static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
					       size_t datasz)
421
{
422 423 424
	int err = 0;
	struct audit_entry *entry;
	void *bufp;
425
	size_t remain = datasz - sizeof(struct audit_rule_data);
426
	int i;
427
	char *str;
428
	struct audit_fsnotify_mark *audit_mark;
429

430
	entry = audit_to_entry_common(data);
431 432
	if (IS_ERR(entry))
		goto exit_nofree;
433

434 435 436 437 438
	bufp = data->buf;
	for (i = 0; i < data->field_count; i++) {
		struct audit_field *f = &entry->rule.fields[i];

		err = -EINVAL;
439 440 441

		f->op = audit_to_op(data->fieldflags[i]);
		if (f->op == Audit_bad)
442 443 444
			goto exit_free;

		f->type = data->fields[i];
445
		f->val = data->values[i];
446

447
		/* Support legacy tests for a valid loginuid */
448
		if ((f->type == AUDIT_LOGINUID) && (f->val == AUDIT_UID_UNSET)) {
449 450
			f->type = AUDIT_LOGINUID_SET;
			f->val = 0;
451
			entry->rule.pflags |= AUDIT_LOGINUID_LEGACY;
452 453
		}

454 455 456 457 458
		err = audit_field_valid(entry, f);
		if (err)
			goto exit_free;

		err = -EINVAL;
459
		switch (f->type) {
460
		case AUDIT_LOGINUID:
461 462 463 464
		case AUDIT_UID:
		case AUDIT_EUID:
		case AUDIT_SUID:
		case AUDIT_FSUID:
465 466 467 468 469
		case AUDIT_OBJ_UID:
			f->uid = make_kuid(current_user_ns(), f->val);
			if (!uid_valid(f->uid))
				goto exit_free;
			break;
470 471 472 473
		case AUDIT_GID:
		case AUDIT_EGID:
		case AUDIT_SGID:
		case AUDIT_FSGID:
474 475 476 477 478
		case AUDIT_OBJ_GID:
			f->gid = make_kgid(current_user_ns(), f->val);
			if (!gid_valid(f->gid))
				goto exit_free;
			break;
479 480 481
		case AUDIT_ARCH:
			entry->rule.arch_f = f;
			break;
482 483 484 485 486
		case AUDIT_SUBJ_USER:
		case AUDIT_SUBJ_ROLE:
		case AUDIT_SUBJ_TYPE:
		case AUDIT_SUBJ_SEN:
		case AUDIT_SUBJ_CLR:
487 488 489 490 491
		case AUDIT_OBJ_USER:
		case AUDIT_OBJ_ROLE:
		case AUDIT_OBJ_TYPE:
		case AUDIT_OBJ_LEV_LOW:
		case AUDIT_OBJ_LEV_HIGH:
492 493 494 495 496
			str = audit_unpack_string(&bufp, &remain, f->val);
			if (IS_ERR(str))
				goto exit_free;
			entry->rule.buflen += f->val;

497
			err = security_audit_rule_init(f->type, f->op, str,
498
						       (void **)&f->lsm_rule);
499 500 501
			/* Keep currently invalid fields around in case they
			 * become valid after a policy reload. */
			if (err == -EINVAL) {
502 503
				pr_warn("audit rule for LSM \'%s\' is invalid\n",
					str);
504 505 506 507 508 509
				err = 0;
			}
			if (err) {
				kfree(str);
				goto exit_free;
			} else
510
				f->lsm_str = str;
511
			break;
512 513 514 515 516 517 518 519 520 521 522 523
		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;
524 525 526 527 528 529 530 531 532 533 534
		case AUDIT_DIR:
			str = audit_unpack_string(&bufp, &remain, f->val);
			if (IS_ERR(str))
				goto exit_free;
			entry->rule.buflen += f->val;

			err = audit_make_tree(&entry->rule, str, f->op);
			kfree(str);
			if (err)
				goto exit_free;
			break;
535 536 537 538 539
		case AUDIT_INODE:
			err = audit_to_inode(&entry->rule, f);
			if (err)
				goto exit_free;
			break;
Amy Griffis's avatar
Amy Griffis committed
540 541 542 543 544 545 546 547 548
		case AUDIT_FILTERKEY:
			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;
549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566
		case AUDIT_EXE:
			if (entry->rule.exe || f->val > PATH_MAX)
				goto exit_free;
			str = audit_unpack_string(&bufp, &remain, f->val);
			if (IS_ERR(str)) {
				err = PTR_ERR(str);
				goto exit_free;
			}
			entry->rule.buflen += f->val;

			audit_mark = audit_alloc_mark(&entry->rule, str, f->val);
			if (IS_ERR(audit_mark)) {
				kfree(str);
				err = PTR_ERR(audit_mark);
				goto exit_free;
			}
			entry->rule.exe = audit_mark;
			break;
567 568 569
		}
	}

570 571
	if (entry->rule.inode_f && entry->rule.inode_f->op == Audit_not_equal)
		entry->rule.inode_f = NULL;
572 573 574 575 576

exit_nofree:
	return entry;

exit_free:
577 578
	if (entry->rule.tree)
		audit_put_tree(entry->rule.tree); /* that's the temporary one */
579 580
	if (entry->rule.exe)
		audit_remove_mark(entry->rule.exe); /* that's the template one */
581 582 583 584 585
	audit_free_rule(entry);
	return ERR_PTR(err);
}

/* Pack a filter field's string representation into data block. */
586
static inline size_t audit_pack_string(void **bufp, const char *str)
587 588 589 590 591 592 593 594 595
{
	size_t len = strlen(str);

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

	return len;
}

Wei Yuan's avatar
Wei Yuan committed
596
/* Translate kernel rule representation to struct audit_rule_data. */
597 598 599 600 601 602 603 604
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))
605
		return NULL;
606 607 608 609 610 611 612 613 614 615
	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;
616
		data->fieldflags[i] = audit_ops[f->op];
617
		switch(f->type) {
618 619 620 621 622
		case AUDIT_SUBJ_USER:
		case AUDIT_SUBJ_ROLE:
		case AUDIT_SUBJ_TYPE:
		case AUDIT_SUBJ_SEN:
		case AUDIT_SUBJ_CLR:
623 624 625 626 627
		case AUDIT_OBJ_USER:
		case AUDIT_OBJ_ROLE:
		case AUDIT_OBJ_TYPE:
		case AUDIT_OBJ_LEV_LOW:
		case AUDIT_OBJ_LEV_HIGH:
628
			data->buflen += data->values[i] =
629
				audit_pack_string(&bufp, f->lsm_str);
630
			break;
631 632
		case AUDIT_WATCH:
			data->buflen += data->values[i] =
633 634
				audit_pack_string(&bufp,
						  audit_watch_path(krule->watch));
635
			break;
636 637 638 639 640
		case AUDIT_DIR:
			data->buflen += data->values[i] =
				audit_pack_string(&bufp,
						  audit_tree_path(krule->tree));
			break;
Amy Griffis's avatar
Amy Griffis committed
641 642 643 644
		case AUDIT_FILTERKEY:
			data->buflen += data->values[i] =
				audit_pack_string(&bufp, krule->filterkey);
			break;
645 646 647 648
		case AUDIT_EXE:
			data->buflen += data->values[i] =
				audit_pack_string(&bufp, audit_mark_path(krule->exe));
			break;
649 650 651 652 653 654 655
		case AUDIT_LOGINUID_SET:
			if (krule->pflags & AUDIT_LOGINUID_LEGACY && !f->val) {
				data->fields[i] = AUDIT_LOGINUID;
				data->values[i] = AUDIT_UID_UNSET;
				break;
			}
			/* fallthrough if set */
656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671
		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 ||
672
	    a->pflags != b->pflags ||
673 674 675
	    a->listnr != b->listnr ||
	    a->action != b->action ||
	    a->field_count != b->field_count)
676 677 678
		return 1;

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

		switch(a->fields[i].type) {
684 685 686 687 688
		case AUDIT_SUBJ_USER:
		case AUDIT_SUBJ_ROLE:
		case AUDIT_SUBJ_TYPE:
		case AUDIT_SUBJ_SEN:
		case AUDIT_SUBJ_CLR:
689 690 691 692 693
		case AUDIT_OBJ_USER:
		case AUDIT_OBJ_ROLE:
		case AUDIT_OBJ_TYPE:
		case AUDIT_OBJ_LEV_LOW:
		case AUDIT_OBJ_LEV_HIGH:
694
			if (strcmp(a->fields[i].lsm_str, b->fields[i].lsm_str))
695 696
				return 1;
			break;
697
		case AUDIT_WATCH:
698 699
			if (strcmp(audit_watch_path(a->watch),
				   audit_watch_path(b->watch)))
700 701
				return 1;
			break;
702 703 704 705 706
		case AUDIT_DIR:
			if (strcmp(audit_tree_path(a->tree),
				   audit_tree_path(b->tree)))
				return 1;
			break;
Amy Griffis's avatar
Amy Griffis committed
707 708 709 710 711
		case AUDIT_FILTERKEY:
			/* both filterkeys exist based on above type compare */
			if (strcmp(a->filterkey, b->filterkey))
				return 1;
			break;
712 713 714 715 716 717
		case AUDIT_EXE:
			/* both paths exist based on above type compare */
			if (strcmp(audit_mark_path(a->exe),
				   audit_mark_path(b->exe)))
				return 1;
			break;
718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734
		case AUDIT_UID:
		case AUDIT_EUID:
		case AUDIT_SUID:
		case AUDIT_FSUID:
		case AUDIT_LOGINUID:
		case AUDIT_OBJ_UID:
			if (!uid_eq(a->fields[i].uid, b->fields[i].uid))
				return 1;
			break;
		case AUDIT_GID:
		case AUDIT_EGID:
		case AUDIT_SGID:
		case AUDIT_FSGID:
		case AUDIT_OBJ_GID:
			if (!gid_eq(a->fields[i].gid, b->fields[i].gid))
				return 1;
			break;
735 736 737 738
		default:
			if (a->fields[i].val != b->fields[i].val)
				return 1;
		}
739 740 741 742 743 744 745 746 747
	}

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

	return 0;
}

748
/* Duplicate LSM field information.  The lsm_rule is opaque, so must be
749
 * re-initialized. */
750
static inline int audit_dupe_lsm_field(struct audit_field *df,
751 752 753
					   struct audit_field *sf)
{
	int ret = 0;
754
	char *lsm_str;
755

756 757 758
	/* our own copy of lsm_str */
	lsm_str = kstrdup(sf->lsm_str, GFP_KERNEL);
	if (unlikely(!lsm_str))
759
		return -ENOMEM;
760
	df->lsm_str = lsm_str;
761

762 763 764
	/* our own (refreshed) copy of lsm_rule */
	ret = security_audit_rule_init(df->type, df->op, df->lsm_str,
				       (void **)&df->lsm_rule);
765 766 767
	/* Keep currently invalid fields around in case they
	 * become valid after a policy reload. */
	if (ret == -EINVAL) {
768 769
		pr_warn("audit rule for LSM \'%s\' is invalid\n",
			df->lsm_str);
770 771 772 773 774 775 776
		ret = 0;
	}

	return ret;
}

/* Duplicate an audit rule.  This will be a deep copy with the exception
777
 * of the watch - that pointer is carried over.  The LSM specific fields
778
 * will be updated in the copy.  The point is to be able to replace the old
779 780 781
 * 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. */
782
struct audit_entry *audit_dupe_rule(struct audit_krule *old)
783 784 785 786
{
	u32 fcount = old->field_count;
	struct audit_entry *entry;
	struct audit_krule *new;
Amy Griffis's avatar
Amy Griffis committed
787
	char *fk;
788 789 790 791 792 793 794 795
	int i, err = 0;

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

	new = &entry->rule;
	new->flags = old->flags;
796
	new->pflags = old->pflags;
797 798 799 800
	new->listnr = old->listnr;
	new->action = old->action;
	for (i = 0; i < AUDIT_BITMASK_SIZE; i++)
		new->mask[i] = old->mask[i];
801
	new->prio = old->prio;
802
	new->buflen = old->buflen;
803
	new->inode_f = old->inode_f;
804
	new->field_count = old->field_count;
805

806 807 808 809 810 811 812 813
	/*
	 * note that we are OK with not refcounting here; audit_match_tree()
	 * never dereferences tree and we can't get false positives there
	 * since we'd have to have rule gone from the list *and* removed
	 * before the chunks found by lookup had been allocated, i.e. before
	 * the beginning of list scan.
	 */
	new->tree = old->tree;
814 815
	memcpy(new->fields, old->fields, sizeof(struct audit_field) * fcount);

816
	/* deep copy this information, updating the lsm_rule fields, because
817 818 819
	 * the originals will all be freed when the old rule is freed. */
	for (i = 0; i < fcount; i++) {
		switch (new->fields[i].type) {
820 821 822 823 824
		case AUDIT_SUBJ_USER:
		case AUDIT_SUBJ_ROLE:
		case AUDIT_SUBJ_TYPE:
		case AUDIT_SUBJ_SEN:
		case AUDIT_SUBJ_CLR:
825 826 827 828 829
		case AUDIT_OBJ_USER:
		case AUDIT_OBJ_ROLE:
		case AUDIT_OBJ_TYPE:
		case AUDIT_OBJ_LEV_LOW:
		case AUDIT_OBJ_LEV_HIGH:
830
			err = audit_dupe_lsm_field(&new->fields[i],
831
						       &old->fields[i]);
Amy Griffis's avatar
Amy Griffis committed
832 833 834 835 836 837 838
			break;
		case AUDIT_FILTERKEY:
			fk = kstrdup(old->filterkey, GFP_KERNEL);
			if (unlikely(!fk))
				err = -ENOMEM;
			else
				new->filterkey = fk;
839 840 841 842
			break;
		case AUDIT_EXE:
			err = audit_dupe_exe(new, old);
			break;
843 844
		}
		if (err) {
845 846
			if (new->exe)
				audit_remove_mark(new->exe);
847 848 849 850 851
			audit_free_rule(entry);
			return ERR_PTR(err);
		}
	}

852 853 854
	if (old->watch) {
		audit_get_watch(old->watch);
		new->watch = old->watch;
855 856
	}

857 858 859
	return entry;
}

860 861 862
/* 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,
863
					   struct list_head **p)
864 865
{
	struct audit_entry *e, *found = NULL;
866
	struct list_head *list;
867 868
	int h;

869 870 871 872
	if (entry->rule.inode_f) {
		h = audit_hash_ino(entry->rule.inode_f->val);
		*p = list = &audit_inode_hash[h];
	} else if (entry->rule.watch) {
873 874 875 876 877 878 879 880 881 882
		/* 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;
883 884
	} else {
		*p = list = &audit_filter_list[entry->rule.listnr];
885 886 887 888 889 890 891 892 893 894 895 896
	}

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

out:
	return found;
}

897 898 899
static u64 prio_low = ~0ULL/2;
static u64 prio_high = ~0ULL/2 - 1;

900
/* Add rule to given filterlist if not a duplicate. */
901
static inline int audit_add_rule(struct audit_entry *entry)
902
{
903
	struct audit_entry *e;
904
	struct audit_watch *watch = entry->rule.watch;
905
	struct audit_tree *tree = entry->rule.tree;
906
	struct list_head *list;
907
	int err = 0;
908 909 910 911 912 913 914 915
#ifdef CONFIG_AUDITSYSCALL
	int dont_count = 0;

	/* If either of these, don't count towards total */
	if (entry->rule.listnr == AUDIT_FILTER_USER ||
		entry->rule.listnr == AUDIT_FILTER_TYPE)
		dont_count = 1;
#endif
916 917

	mutex_lock(&audit_filter_mutex);
918
	e = audit_find_rule(entry, &list);
919
	if (e) {
920
		mutex_unlock(&audit_filter_mutex);
921
		err = -EEXIST;
922 923 924
		/* normally audit_add_tree_rule() will free it on failure */
		if (tree)
			audit_put_tree(tree);
925
		return err;
926
	}
927

928 929
	if (watch) {
		/* audit_filter_mutex is dropped and re-taken during this call */
930
		err = audit_add_watch(&entry->rule, &list);
931 932
		if (err) {
			mutex_unlock(&audit_filter_mutex);
933 934 935 936 937 938
			/*
			 * normally audit_add_tree_rule() will free it
			 * on failure
			 */
			if (tree)
				audit_put_tree(tree);
939
			return err;
940
		}
941
	}
942 943 944 945
	if (tree) {
		err = audit_add_tree_rule(&entry->rule);
		if (err) {
			mutex_unlock(&audit_filter_mutex);
946
			return err;
947 948
		}
	}
949

950 951 952 953 954 955 956 957
	entry->rule.prio = ~0ULL;
	if (entry->rule.listnr == AUDIT_FILTER_EXIT) {
		if (entry->rule.flags & AUDIT_FILTER_PREPEND)
			entry->rule.prio = ++prio_high;
		else
			entry->rule.prio = --prio_low;
	}

958
	if (entry->rule.flags & AUDIT_FILTER_PREPEND) {
Al Viro's avatar
Al Viro committed
959 960
		list_add(&entry->rule.list,
			 &audit_rules_list[entry->rule.listnr]);
961
		list_add_rcu(&entry->list, list);
962
		entry->rule.flags &= ~AUDIT_FILTER_PREPEND;
963
	} else {
Al Viro's avatar
Al Viro committed
964 965
		list_add_tail(&entry->rule.list,
			      &audit_rules_list[entry->rule.listnr]);
966 967
		list_add_tail_rcu(&entry->list, list);
	}
968 969 970
#ifdef CONFIG_AUDITSYSCALL
	if (!dont_count)
		audit_n_rules++;
971 972 973

	if (!audit_match_signal(entry))
		audit_signals++;
974
#endif
975
	mutex_unlock(&audit_filter_mutex);
976

977
	return err;
978 979
}

980
/* Remove an existing rule from filterlist. */
981
int audit_del_rule(struct audit_entry *entry)
982 983
{
	struct audit_entry  *e;
984
	struct audit_tree *tree = entry->rule.tree;
985 986
	struct list_head *list;
	int ret = 0;
987 988 989 990 991 992 993 994
#ifdef CONFIG_AUDITSYSCALL
	int dont_count = 0;

	/* If either of these, don't count towards total */
	if (entry->rule.listnr == AUDIT_FILTER_USER ||
		entry->rule.listnr == AUDIT_FILTER_TYPE)
		dont_count = 1;
#endif
995 996

	mutex_lock(&audit_filter_mutex);
997
	e = audit_find_rule(entry, &list);
998 999 1000 1001 1002
	if (!e) {
		ret = -ENOENT;
		goto out;
	}

1003
	if (e->rule.watch)
1004
		audit_remove_watch_rule(&e->rule);
1005

1006 1007 1008
	if (e->rule.tree)
		audit_remove_tree_rule(&e->rule);

1009 1010 1011
	if (e->rule.exe)
		audit_remove_mark_rule(&e->rule);

1012 1013 1014
#ifdef CONFIG_AUDITSYSCALL
	if (!dont_count)
		audit_n_rules--;
1015 1016 1017

	if (!audit_match_signal(entry))
		audit_signals--;
1018
#endif
1019 1020 1021 1022

	list_del_rcu(&e->list);
	list_del(&e->rule.list);
	call_rcu(&e->rcu, audit_free_rule_rcu);
1023 1024

out:
1025 1026
	mutex_unlock(&audit_filter_mutex);

1027 1028
	if (tree)
		audit_put_tree(tree);	/* that's the temporary one */
1029 1030

	return ret;
1031 1032
}

1033
/* List rules using struct audit_rule_data. */
1034
static void audit_list_rules(__u32 portid, int seq, struct sk_buff_head *q)
1035
{
1036
	struct sk_buff *skb;
Al Viro's avatar
Al Viro committed
1037
	struct audit_krule *r;
1038 1039
	int i;

1040 1041
	/* This is a blocking read, so use audit_filter_mutex instead of rcu
	 * iterator to sync with list writers. */
1042
	for (i=0; i<AUDIT_NR_FILTERS; i++) {
Al Viro's avatar
Al Viro committed
1043
		list_for_each_entry(r, &audit_rules_list[i], list) {
1044 1045
			struct audit_rule_data *data;

Al Viro's avatar
Al Viro committed
1046
			data = audit_krule_to_data(r);
1047 1048
			if (unlikely(!data))
				break;
1049 1050 1051
			skb = audit_make_reply(portid, seq, AUDIT_LIST_RULES,
					       0, 1, data,
					       sizeof(*data) + data->buflen);
1052 1053
			if (skb)
				skb_queue_tail(q, skb);
1054 1055 1056
			kfree(data);
		}
	}
1057
	skb = audit_make_reply(portid, seq, AUDIT_LIST_RULES, 1, 1, NULL, 0);
1058 1059
	if (skb)
		skb_queue_tail(q, skb);
1060 1061
}

Amy Griffis's avatar
Amy Griffis committed
1062
/* Log rule additions and removals */
1063
static void audit_log_rule_change(char *action, struct audit_krule *rule, int res)
Amy Griffis's avatar
Amy Griffis committed
1064 1065
{
	struct audit_buffer *ab;
1066
	uid_t loginuid = from_kuid(&init_user_ns, audit_get_loginuid(current));
1067
	unsigned int sessionid = audit_get_sessionid(current);
Amy Griffis's avatar
Amy Griffis committed
1068

1069 1070 1071
	if (!audit_enabled)
		return;

Amy Griffis's avatar
Amy Griffis committed
1072 1073 1074
	ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
	if (!ab)
		return;
1075
	audit_log_format(ab, "auid=%u ses=%u" ,loginuid, sessionid);
1076
	audit_log_task_context(ab);
1077 1078 1079
	audit_log_format(ab, " op=");
	audit_log_string(ab, action);
	audit_log_key(ab, rule->filterkey);
Amy Griffis's avatar
Amy Griffis committed
1080 1081 1082 1083
	audit_log_format(ab, " list=%d res=%d", rule->listnr, res);
	audit_log_end(ab);
}

1084
/**
1085
 * audit_rule_change - apply all rules to the specified message type
1086
 * @type: audit message type
1087
 * @portid: target port id for netlink audit messages
1088 1089
 * @seq: netlink audit message sequence (serial) number
 * @data: payload data
1090
 * @datasz: size of payload data
1091
 */
1092 1093
int audit_rule_change(int type, __u32 portid, int seq, void *data,
			size_t datasz)
1094
{
1095 1096
	int err = 0;
	struct audit_entry *entry;
1097

1098 1099 1100 1101
	entry = audit_data_to_entry(data, datasz);
	if (IS_ERR(entry))
		return PTR_ERR(entry);

1102
	switch (type) {
1103
	case AUDIT_ADD_RULE:
1104
		err = audit_add_rule(entry);
1105
		audit_log_rule_change("add_rule", &entry->rule, !err);
1106
		break;
1107
	case AUDIT_DEL_RULE:
1108
		err = audit_del_rule(entry);
1109
		audit_log_rule_change("remove_rule", &entry->rule, !err);
1110 1111
		break;
	default:
1112 1113
		err = -EINVAL;
		WARN_ON(1);
1114 1115
	}

1116 1117 1118
	if (err || type == AUDIT_DEL_RULE) {
		if (entry->rule.exe)
			audit_remove_mark(entry->rule.exe);
1119
		audit_free_rule(entry);
1120
	}
1121

1122 1123 1124
	return err;
}

1125 1126
/**
 * audit_list_rules_send - list the audit rules
1127
 * @request_skb: skb of request we are replying to (used to target the reply)
1128 1129
 * @seq: netlink audit message sequence (serial) number
 */
1130
int audit_list_rules_send(struct sk_buff *request_skb, int seq)
1131
{
1132 1133
	u32 portid = NETLINK_CB(request_skb).portid;
	struct net *net = sock_net(NETLINK_CB(request_skb).sk);
1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146
	struct task_struct *tsk;
	struct audit_netlink_list *dest;
	int err = 0;

	/* 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;
1147
	dest->net = get_net(net);
1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164
	dest->portid = portid;
	skb_queue_head_init(&dest->q);

	mutex_lock(&audit_filter_mutex);
	audit_list_rules(portid, 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);
	}

	return err;
}

1165
int audit_comparator(u32 left, u32 op, u32 right)
1166 1167
{
	switch (op) {
1168
	case Audit_equal:
1169
		return (left == right);
1170
	case Audit_not_equal:
1171
		return (left != right);
1172
	case Audit_lt:
1173
		return (left < right);
1174
	case Audit_le:
1175
		return (left <= right);
1176
	case Audit_gt:
1177
		return (left > right);
1178
	case Audit_ge:
1179
		return (left >= right);
1180
	case Audit_bitmask:
1181
		return (left & right);
1182
	case Audit_bittest:
1183
		return ((left & right) == right);
1184 1185 1186
	default:
		BUG();
		return 0;
1187 1188 1189
	}
}

1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235
int audit_uid_comparator(kuid_t left, u32 op, kuid_t right)
{
	switch (op) {
	case Audit_equal:
		return uid_eq(left, right);
	case Audit_not_equal:
		return !uid_eq(left, right);
	case Audit_lt:
		return uid_lt(left, right);
	case Audit_le:
		return uid_lte(left, right);
	case Audit_gt:
		return uid_gt(left, right);
	case Audit_ge:
		return uid_gte(left, right);
	case Audit_bitmask:
	case Audit_bittest:
	default:
		BUG();
		return 0;
	}
}

int audit_gid_comparator(kgid_t left, u32 op, kgid_t right)
{
	switch (op) {
	case Audit_equal:
		return gid_eq(left, right);
	case Audit_not_equal:
		return !gid_eq(left, right);
	case Audit_lt:
		return gid_lt(left, right);
	case Audit_le:
		return gid_lte(left, right);
	case Audit_gt:
		return gid_gt(left, right);
	case Audit_ge:
		return gid_gte(left, right);
	case Audit_bitmask:
	case Audit_bittest:
	default:
		BUG();
		return 0;
	}
}

1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265
/**
 * parent_len - find the length of the parent portion of a pathname
 * @path: pathname of which to determine length
 */
int parent_len(const char *path)
{
	int plen;
	const char *p;

	plen = strlen(path);

	if (plen == 0)
		return plen;

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

	/* walk backward until we find the next slash or hit beginning */
	while ((*p != '/') && (p > path))
		p--;

	/* did we find a slash? Then increment to include it in path */
	if (*p == '/')
		p++;

	return p - path;
}

1266 1267 1268 1269 1270 1271 1272 1273 1274
/**
 * audit_compare_dname_path - compare given dentry name with last component in
 * 			      given path. Return of 0 indicates a match.
 * @dname:	dentry name that we're comparing
 * @path:	full pathname that we're comparing
 * @parentlen:	length of the parent if known. Passing in AUDIT_NAME_FULL
 * 		here indicates that we must compute this value.
 */
int audit_compare_dname_path(const char *dname, const char *path, int parentlen)
1275
{
1276
	int dlen, pathlen;
1277 1278 1279
	const char *p;

	dlen = strlen(dname);
1280 1281
	pathlen = strlen(path);
	if (pathlen < dlen)
1282 1283
		return 1;

1284
	parentlen = parentlen == AUDIT_NAME_FULL ? parent_len(path) : parentlen;
1285
	if (pathlen - parentlen != dlen)
1286
		return 1;
1287 1288

	p = path + parentlen;
1289

1290 1291
	return strncmp(p, dname, dlen);
}
1292

1293
int audit_filter(int msgtype, unsigned int listtype)
1294 1295
{
	struct audit_entry *e;
1296
	int ret = 1; /* Audit by default */
1297

1298
	rcu_read_lock();
1299
	if (list_empty(&audit_filter_list[listtype]))
1300
		goto unlock_and_return;
1301 1302
	list_for_each_entry_rcu(e, &audit_filter_list[listtype], list) {
		int i, result = 0;
1303

1304 1305
		for (i = 0; i < e->rule.field_count; i++) {
			struct audit_field *f = &e->rule.fields[i];
1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343
			pid_t pid;
			u32 sid;

			switch (f->type) {
			case AUDIT_PID:
				pid = task_pid_nr(current);
				result = audit_comparator(pid, f->op, f->val);
				break;
			case AUDIT_UID:
				result = audit_uid_comparator(current_uid(), f->op, f->uid);
				break;
			case AUDIT_GID:
				result = audit_gid_comparator(current_gid(), f->op, f->gid);
				break;
			case AUDIT_LOGINUID:
				result = audit_uid_comparator(audit_get_loginuid(current),
							      f->op, f->uid);
				break;
			case AUDIT_LOGINUID_SET:
				result = audit_comparator(audit_loginuid_set(current),
							  f->op, f->val);
				break;
			case AUDIT_MSGTYPE:
				result = audit_comparator(msgtype, f->op, f->val);
				break;
			case AUDIT_SUBJ_USER:
			case AUDIT_SUBJ_ROLE:
			case AUDIT_SUBJ_TYPE:
			case AUDIT_SUBJ_SEN:
			case AUDIT_SUBJ_CLR:
				if (f->lsm_rule) {
					security_task_getsecid(current, &sid);
					result = security_audit_rule_match(sid,
							f->type, f->op, f->lsm_rule, NULL);
				}
				break;
			default:
				goto unlock_and_return;
1344
			}
1345 1346 1347 1348 1349 1350 1351 1352 1353
			if (result < 0) /* error */
				goto unlock_and_return;
			if (!result)
				break;
		}
		if (result > 0) {
			if (e->rule.action == AUDIT_NEVER || listtype == AUDIT_FILTER_TYPE)
				ret = 0;
			break;
1354 1355 1356 1357
		}
	}
unlock_and_return:
	rcu_read_unlock();
1358
	return ret;
1359
}
1360

Al Viro's avatar
Al Viro committed
1361
static int update_lsm_rule(struct audit_krule *r)
1362
{
Al Viro's avatar
Al Viro committed
1363
	struct audit_entry *entry = container_of(r, struct audit_entry, rule);
1364 1365 1366
	struct audit_entry *nentry;
	int err = 0;

Al Viro's avatar
Al Viro committed
1367
	if (!security_audit_rule_known(r))
1368 1369
		return 0;

1370
	nentry = audit_dupe_rule(r);
1371 1372
	if (entry->rule.exe)
		audit_remove_mark(entry->rule.exe);
1373 1374 1375 1376 1377
	if (IS_ERR(nentry)) {
		/* save the first error encountered for the
		 * return value */
		err = PTR_ERR(nentry);
		audit_panic("error updating LSM filters");
1378
		if (r->watch)
Al Viro's avatar
Al Viro committed
1379
			list_del(&r->rlist);
1380
		list_del_rcu(&entry->list);
Al Viro's avatar
Al Viro committed
1381
		list_del(&r->list);
1382
	} else {
1383
		if (r->watch || r->tree)
Al Viro's avatar
Al Viro committed
1384
			list_replace_init(&r->rlist, &nentry->rule.rlist);
1385
		list_replace_rcu(&entry->list, &nentry->list);
Al Viro's avatar
Al Viro committed
1386
		list_replace(&r->list, &nentry->rule.list);
1387 1388 1389 1390 1391 1392
	}
	call_rcu(&entry->rcu, audit_free_rule_rcu);

	return err;
}

1393
/* This function will re-initialize the lsm_rule field of all applicable rules.
1394
 * It will traverse the filter lists serarching for rules that contain LSM
1395
 * specific filter fields.  When such a rule is found, it is copied, the
1396
 * LSM field is re-initialized, and the old rule is replaced with the
1397
 * updated rule. */
1398
int audit_update_lsm_rules(void)
1399
{
Al Viro's avatar
Al Viro committed
1400
	struct audit_krule *r, *n;
1401 1402
	int i, err = 0;

1403 1404
	/* audit_filter_mutex synchronizes the writers */
	mutex_lock(&audit_filter_mutex);
1405 1406

	for (i = 0; i < AUDIT_NR_FILTERS; i++) {
Al Viro's avatar
Al Viro committed
1407 1408
		list_for_each_entry_safe(r, n, &audit_rules_list[i], list) {
			int res = update_lsm_rule(r);
1409 1410
			if (!err)
				err = res;
1411 1412
		}
	}
1413
	mutex_unlock(&audit_filter_mutex);
1414 1415 1416

	return err;
}