auditfilter.c 35.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/* 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>
Amy Griffis's avatar
Amy Griffis committed
25 26 27
#include <linux/mutex.h>
#include <linux/fs.h>
#include <linux/namei.h>
28
#include <linux/netlink.h>
Amy Griffis's avatar
Amy Griffis committed
29
#include <linux/sched.h>
30
#include <linux/slab.h>
31
#include <linux/security.h>
32 33
#include "audit.h"

Amy Griffis's avatar
Amy Griffis committed
34 35 36 37 38 39 40
/*
 * 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
41
 * 		LSM rules during filtering.  If modified, these structures
Amy Griffis's avatar
Amy Griffis committed
42 43 44 45 46 47
 * 		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.
 */

/* Audit filter lists, defined in <linux/audit.h> */
48 49 50 51 52 53 54 55 56 57 58
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
59 60 61 62 63 64 65 66
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]),
};
67

Al Viro's avatar
Al Viro committed
68
DEFINE_MUTEX(audit_filter_mutex);
Amy Griffis's avatar
Amy Griffis committed
69

70
static inline void audit_free_rule(struct audit_entry *e)
71
{
72
	int i;
73
	struct audit_krule *erule = &e->rule;
74

Amy Griffis's avatar
Amy Griffis committed
75
	/* some rules don't have associated watches */
76 77 78 79 80
	if (erule->watch)
		audit_put_watch(erule->watch);
	if (erule->fields)
		for (i = 0; i < erule->field_count; i++) {
			struct audit_field *f = &erule->fields[i];
81 82
			kfree(f->lsm_str);
			security_audit_rule_free(f->lsm_rule);
83
		}
84 85
	kfree(erule->fields);
	kfree(erule->filterkey);
86 87 88
	kfree(e);
}

Al Viro's avatar
Al Viro committed
89
void audit_free_rule_rcu(struct rcu_head *head)
90 91 92 93 94
{
	struct audit_entry *e = container_of(head, struct audit_entry, rcu);
	audit_free_rule(e);
}

95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
/* 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;
}

115 116
/* Unpack a filter field's string representation from user-space
 * buffer. */
Al Viro's avatar
Al Viro committed
117
char *audit_unpack_string(void **bufp, size_t *remain, size_t len)
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
{
	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;
}

Amy Griffis's avatar
Amy Griffis committed
142 143 144 145 146
/* 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 ||
147 148
	    krule->watch || krule->inode_f || krule->tree ||
	    (f->op != Audit_equal && f->op != Audit_not_equal))
Amy Griffis's avatar
Amy Griffis committed
149 150 151 152 153 154
		return -EINVAL;

	krule->inode_f = f;
	return 0;
}

Al Viro's avatar
Al Viro committed
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
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;
}

Al Viro's avatar
Al Viro committed
178 179
int audit_match_class(int class, unsigned syscall)
{
180
	if (unlikely(syscall >= AUDIT_BITMASK_SIZE * 32))
Al Viro's avatar
Al Viro committed
181 182 183 184 185 186
		return 0;
	if (unlikely(class >= AUDIT_SYSCALL_CLASSES || !classes[class]))
		return 0;
	return classes[class][AUDIT_WORD(syscall)] & AUDIT_BIT(syscall);
}

187
#ifdef CONFIG_AUDITSYSCALL
Amy Griffis's avatar
Amy Griffis committed
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
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;
	}
}
224
#endif
Amy Griffis's avatar
Amy Griffis committed
225

226 227 228 229 230 231 232 233 234 235 236 237 238 239
/* 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;
#ifdef CONFIG_AUDITSYSCALL
	case AUDIT_FILTER_ENTRY:
Eric Paris's avatar
Eric Paris committed
240 241
		if (rule->action == AUDIT_ALWAYS)
			goto exit_err;
242 243 244
	case AUDIT_FILTER_EXIT:
	case AUDIT_FILTER_TASK:
#endif
Eric Paris's avatar
Eric Paris committed
245 246
	case AUDIT_FILTER_USER:
	case AUDIT_FILTER_TYPE:
247 248
		;
	}
Al Viro's avatar
Al Viro committed
249 250 251 252 253
	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)
254 255 256 257 258
		goto exit_err;
	if (rule->field_count > AUDIT_MAX_FIELDS)
		goto exit_err;

	err = -ENOMEM;
259 260
	entry = audit_init_entry(rule->field_count);
	if (!entry)
261 262 263 264 265 266 267 268 269 270
		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
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
	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];
		}
	}

287 288 289 290 291 292
	return entry;

exit_err:
	return ERR_PTR(err);
}

293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313
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;
}


314 315 316 317 318 319
/* 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;
	int err = 0;
320 321
	int i;

322 323 324 325 326 327
	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];
328 329 330 331 332 333 334 335 336 337 338 339 340 341
		u32 n;

		n = rule->fields[i] & (AUDIT_NEGATE|AUDIT_OPERATORS);

		/* Support for legacy operators where
		 * AUDIT_NEGATE bit signifies != and otherwise assumes == */
		if (n & AUDIT_NEGATE)
			f->op = Audit_not_equal;
		else if (!n)
			f->op = Audit_equal;
		else
			f->op = audit_to_op(n);

		entry->rule.vers_ops = (n & AUDIT_OPERATORS) ? 2 : 1;
342 343 344

		f->type = rule->fields[i] & ~(AUDIT_NEGATE|AUDIT_OPERATORS);
		f->val = rule->values[i];
345 346
		f->uid = INVALID_UID;
		f->gid = INVALID_GID;
347

Amy Griffis's avatar
Amy Griffis committed
348
		err = -EINVAL;
349 350 351
		if (f->op == Audit_bad)
			goto exit_free;

Amy Griffis's avatar
Amy Griffis committed
352
		switch(f->type) {
Al Viro's avatar
Al Viro committed
353
		default:
354
			goto exit_free;
Al Viro's avatar
Al Viro committed
355 356 357 358
		case AUDIT_UID:
		case AUDIT_EUID:
		case AUDIT_SUID:
		case AUDIT_FSUID:
359 360 361 362 363 364 365 366 367
		case AUDIT_LOGINUID:
			/* bit ops not implemented for uid comparisons */
			if (f->op == Audit_bitmask || f->op == Audit_bittest)
				goto exit_free;

			f->uid = make_kuid(current_user_ns(), f->val);
			if (!uid_valid(f->uid))
				goto exit_free;
			break;
Al Viro's avatar
Al Viro committed
368 369 370 371
		case AUDIT_GID:
		case AUDIT_EGID:
		case AUDIT_SGID:
		case AUDIT_FSGID:
372 373 374 375 376 377 378 379 380
			/* bit ops not implemented for gid comparisons */
			if (f->op == Audit_bitmask || f->op == Audit_bittest)
				goto exit_free;

			f->gid = make_kgid(current_user_ns(), f->val);
			if (!gid_valid(f->gid))
				goto exit_free;
			break;
		case AUDIT_PID:
Al Viro's avatar
Al Viro committed
381 382
		case AUDIT_PERS:
		case AUDIT_MSGTYPE:
383
		case AUDIT_PPID:
Al Viro's avatar
Al Viro committed
384 385 386 387
		case AUDIT_DEVMAJOR:
		case AUDIT_DEVMINOR:
		case AUDIT_EXIT:
		case AUDIT_SUCCESS:
388
			/* bit ops are only useful on syscall args */
389
			if (f->op == Audit_bitmask || f->op == Audit_bittest)
390 391
				goto exit_free;
			break;
Al Viro's avatar
Al Viro committed
392 393 394 395 396
		case AUDIT_ARG0:
		case AUDIT_ARG1:
		case AUDIT_ARG2:
		case AUDIT_ARG3:
			break;
397 398
		/* arch is only allowed to be = or != */
		case AUDIT_ARCH:
399
			if (f->op != Audit_not_equal && f->op != Audit_equal)
400
				goto exit_free;
Amy Griffis's avatar
Amy Griffis committed
401
			entry->rule.arch_f = f;
402
			break;
Al Viro's avatar
Al Viro committed
403 404 405 406
		case AUDIT_PERM:
			if (f->val & ~15)
				goto exit_free;
			break;
407
		case AUDIT_FILETYPE:
408
			if (f->val & ~S_IFMT)
409 410
				goto exit_free;
			break;
Amy Griffis's avatar
Amy Griffis committed
411 412 413 414 415
		case AUDIT_INODE:
			err = audit_to_inode(&entry->rule, f);
			if (err)
				goto exit_free;
			break;
416
		}
417
	}
418

419 420
	if (entry->rule.inode_f && entry->rule.inode_f->op == Audit_not_equal)
		entry->rule.inode_f = NULL;
Amy Griffis's avatar
Amy Griffis committed
421

422 423 424 425 426 427
exit_nofree:
	return entry;

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

430 431 432
/* 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)
433
{
434 435 436
	int err = 0;
	struct audit_entry *entry;
	void *bufp;
437
	size_t remain = datasz - sizeof(struct audit_rule_data);
438
	int i;
439
	char *str;
440

441 442 443
	entry = audit_to_entry_common((struct audit_rule *)data);
	if (IS_ERR(entry))
		goto exit_nofree;
444

445 446 447 448 449 450
	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;
451 452 453

		f->op = audit_to_op(data->fieldflags[i]);
		if (f->op == Audit_bad)
454 455 456
			goto exit_free;

		f->type = data->fields[i];
457
		f->val = data->values[i];
458 459
		f->uid = INVALID_UID;
		f->gid = INVALID_GID;
460 461
		f->lsm_str = NULL;
		f->lsm_rule = NULL;
462
		switch(f->type) {
Al Viro's avatar
Al Viro committed
463 464 465 466
		case AUDIT_UID:
		case AUDIT_EUID:
		case AUDIT_SUID:
		case AUDIT_FSUID:
467 468 469 470 471 472 473 474 475 476
		case AUDIT_LOGINUID:
		case AUDIT_OBJ_UID:
			/* bit ops not implemented for uid comparisons */
			if (f->op == Audit_bitmask || f->op == Audit_bittest)
				goto exit_free;

			f->uid = make_kuid(current_user_ns(), f->val);
			if (!uid_valid(f->uid))
				goto exit_free;
			break;
Al Viro's avatar
Al Viro committed
477 478 479 480
		case AUDIT_GID:
		case AUDIT_EGID:
		case AUDIT_SGID:
		case AUDIT_FSGID:
481 482 483 484 485 486 487 488 489 490
		case AUDIT_OBJ_GID:
			/* bit ops not implemented for gid comparisons */
			if (f->op == Audit_bitmask || f->op == Audit_bittest)
				goto exit_free;

			f->gid = make_kgid(current_user_ns(), f->val);
			if (!gid_valid(f->gid))
				goto exit_free;
			break;
		case AUDIT_PID:
Al Viro's avatar
Al Viro committed
491 492 493 494 495 496 497 498 499 500 501 502
		case AUDIT_PERS:
		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;
Amy Griffis's avatar
Amy Griffis committed
503 504 505
		case AUDIT_ARCH:
			entry->rule.arch_f = f;
			break;
506 507 508 509 510
		case AUDIT_SUBJ_USER:
		case AUDIT_SUBJ_ROLE:
		case AUDIT_SUBJ_TYPE:
		case AUDIT_SUBJ_SEN:
		case AUDIT_SUBJ_CLR:
511 512 513 514 515
		case AUDIT_OBJ_USER:
		case AUDIT_OBJ_ROLE:
		case AUDIT_OBJ_TYPE:
		case AUDIT_OBJ_LEV_LOW:
		case AUDIT_OBJ_LEV_HIGH:
516 517 518 519 520
			str = audit_unpack_string(&bufp, &remain, f->val);
			if (IS_ERR(str))
				goto exit_free;
			entry->rule.buflen += f->val;

521
			err = security_audit_rule_init(f->type, f->op, str,
522
						       (void **)&f->lsm_rule);
523 524 525
			/* Keep currently invalid fields around in case they
			 * become valid after a policy reload. */
			if (err == -EINVAL) {
526
				printk(KERN_WARNING "audit rule for LSM "
527 528 529 530 531 532 533
				       "\'%s\' is invalid\n",  str);
				err = 0;
			}
			if (err) {
				kfree(str);
				goto exit_free;
			} else
534
				f->lsm_str = str;
535
			break;
Amy Griffis's avatar
Amy Griffis committed
536 537 538 539 540 541 542 543 544 545 546 547
		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;
Al Viro's avatar
Al Viro committed
548 549 550 551 552 553 554 555 556 557 558
		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;
Amy Griffis's avatar
Amy Griffis committed
559 560 561 562 563
		case AUDIT_INODE:
			err = audit_to_inode(&entry->rule, f);
			if (err)
				goto exit_free;
			break;
Amy Griffis's avatar
Amy Griffis committed
564 565 566 567 568 569 570 571 572
		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;
Al Viro's avatar
Al Viro committed
573 574 575 576
		case AUDIT_PERM:
			if (f->val & ~15)
				goto exit_free;
			break;
577
		case AUDIT_FILETYPE:
578
			if (f->val & ~S_IFMT)
579 580
				goto exit_free;
			break;
581 582 583 584
		case AUDIT_FIELD_COMPARE:
			if (f->val > AUDIT_MAX_FIELD_COMPARE)
				goto exit_free;
			break;
Al Viro's avatar
Al Viro committed
585 586
		default:
			goto exit_free;
Amy Griffis's avatar
Amy Griffis committed
587 588 589
		}
	}

590 591
	if (entry->rule.inode_f && entry->rule.inode_f->op == Audit_not_equal)
		entry->rule.inode_f = NULL;
592 593 594 595 596 597 598 599 600 601

exit_nofree:
	return entry;

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

/* Pack a filter field's string representation into data block. */
Al Viro's avatar
Al Viro committed
602
static inline size_t audit_pack_string(void **bufp, const char *str)
603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618
{
	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;

619
	rule = kzalloc(sizeof(*rule), GFP_KERNEL);
620
	if (unlikely(!rule))
621
		return NULL;
622 623 624 625 626 627 628 629 630

	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) {
631
			if (krule->fields[i].op == Audit_not_equal)
632 633
				rule->fields[i] |= AUDIT_NEGATE;
		} else {
634
			rule->fields[i] |= audit_ops[krule->fields[i].op];
635 636 637 638 639 640
		}
	}
	for (i = 0; i < AUDIT_BITMASK_SIZE; i++) rule->mask[i] = krule->mask[i];

	return rule;
}
641

642 643 644 645 646 647 648 649 650
/* 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))
651
		return NULL;
652 653 654 655 656 657 658 659 660 661
	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;
662
		data->fieldflags[i] = audit_ops[f->op];
663
		switch(f->type) {
664 665 666 667 668
		case AUDIT_SUBJ_USER:
		case AUDIT_SUBJ_ROLE:
		case AUDIT_SUBJ_TYPE:
		case AUDIT_SUBJ_SEN:
		case AUDIT_SUBJ_CLR:
669 670 671 672 673
		case AUDIT_OBJ_USER:
		case AUDIT_OBJ_ROLE:
		case AUDIT_OBJ_TYPE:
		case AUDIT_OBJ_LEV_LOW:
		case AUDIT_OBJ_LEV_HIGH:
674
			data->buflen += data->values[i] =
675
				audit_pack_string(&bufp, f->lsm_str);
676
			break;
Amy Griffis's avatar
Amy Griffis committed
677 678
		case AUDIT_WATCH:
			data->buflen += data->values[i] =
679 680
				audit_pack_string(&bufp,
						  audit_watch_path(krule->watch));
Amy Griffis's avatar
Amy Griffis committed
681
			break;
Al Viro's avatar
Al Viro committed
682 683 684 685 686
		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
687 688 689 690
		case AUDIT_FILTERKEY:
			data->buflen += data->values[i] =
				audit_pack_string(&bufp, krule->filterkey);
			break;
691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709
		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)
710 711 712
		return 1;

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

		switch(a->fields[i].type) {
718 719 720 721 722
		case AUDIT_SUBJ_USER:
		case AUDIT_SUBJ_ROLE:
		case AUDIT_SUBJ_TYPE:
		case AUDIT_SUBJ_SEN:
		case AUDIT_SUBJ_CLR:
723 724 725 726 727
		case AUDIT_OBJ_USER:
		case AUDIT_OBJ_ROLE:
		case AUDIT_OBJ_TYPE:
		case AUDIT_OBJ_LEV_LOW:
		case AUDIT_OBJ_LEV_HIGH:
728
			if (strcmp(a->fields[i].lsm_str, b->fields[i].lsm_str))
729 730
				return 1;
			break;
Amy Griffis's avatar
Amy Griffis committed
731
		case AUDIT_WATCH:
732 733
			if (strcmp(audit_watch_path(a->watch),
				   audit_watch_path(b->watch)))
Amy Griffis's avatar
Amy Griffis committed
734 735
				return 1;
			break;
Al Viro's avatar
Al Viro committed
736 737 738 739 740
		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
741 742 743 744 745
		case AUDIT_FILTERKEY:
			/* both filterkeys exist based on above type compare */
			if (strcmp(a->filterkey, b->filterkey))
				return 1;
			break;
746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762
		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;
763 764 765 766
		default:
			if (a->fields[i].val != b->fields[i].val)
				return 1;
		}
767 768 769 770 771 772 773 774 775
	}

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

	return 0;
}

776
/* Duplicate LSM field information.  The lsm_rule is opaque, so must be
777
 * re-initialized. */
778
static inline int audit_dupe_lsm_field(struct audit_field *df,
779 780 781
					   struct audit_field *sf)
{
	int ret = 0;
782
	char *lsm_str;
783

784 785 786
	/* our own copy of lsm_str */
	lsm_str = kstrdup(sf->lsm_str, GFP_KERNEL);
	if (unlikely(!lsm_str))
787
		return -ENOMEM;
788
	df->lsm_str = lsm_str;
789

790 791 792
	/* our own (refreshed) copy of lsm_rule */
	ret = security_audit_rule_init(df->type, df->op, df->lsm_str,
				       (void **)&df->lsm_rule);
793 794 795
	/* Keep currently invalid fields around in case they
	 * become valid after a policy reload. */
	if (ret == -EINVAL) {
796
		printk(KERN_WARNING "audit rule for LSM \'%s\' is "
797
		       "invalid\n", df->lsm_str);
798 799 800 801 802 803 804
		ret = 0;
	}

	return ret;
}

/* Duplicate an audit rule.  This will be a deep copy with the exception
805
 * of the watch - that pointer is carried over.  The LSM specific fields
806
 * will be updated in the copy.  The point is to be able to replace the old
Amy Griffis's avatar
Amy Griffis committed
807 808 809
 * 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. */
810
struct audit_entry *audit_dupe_rule(struct audit_krule *old)
811 812 813 814
{
	u32 fcount = old->field_count;
	struct audit_entry *entry;
	struct audit_krule *new;
Amy Griffis's avatar
Amy Griffis committed
815
	char *fk;
816 817 818 819 820 821 822 823 824 825 826 827 828
	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];
829
	new->prio = old->prio;
830
	new->buflen = old->buflen;
Amy Griffis's avatar
Amy Griffis committed
831
	new->inode_f = old->inode_f;
832
	new->field_count = old->field_count;
833

Al Viro's avatar
Al Viro committed
834 835 836 837 838 839 840 841
	/*
	 * 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;
842 843
	memcpy(new->fields, old->fields, sizeof(struct audit_field) * fcount);

844
	/* deep copy this information, updating the lsm_rule fields, because
845 846 847
	 * the originals will all be freed when the old rule is freed. */
	for (i = 0; i < fcount; i++) {
		switch (new->fields[i].type) {
848 849 850 851 852
		case AUDIT_SUBJ_USER:
		case AUDIT_SUBJ_ROLE:
		case AUDIT_SUBJ_TYPE:
		case AUDIT_SUBJ_SEN:
		case AUDIT_SUBJ_CLR:
853 854 855 856 857
		case AUDIT_OBJ_USER:
		case AUDIT_OBJ_ROLE:
		case AUDIT_OBJ_TYPE:
		case AUDIT_OBJ_LEV_LOW:
		case AUDIT_OBJ_LEV_HIGH:
858
			err = audit_dupe_lsm_field(&new->fields[i],
859
						       &old->fields[i]);
Amy Griffis's avatar
Amy Griffis committed
860 861 862 863 864 865 866
			break;
		case AUDIT_FILTERKEY:
			fk = kstrdup(old->filterkey, GFP_KERNEL);
			if (unlikely(!fk))
				err = -ENOMEM;
			else
				new->filterkey = fk;
867 868 869 870 871 872 873
		}
		if (err) {
			audit_free_rule(entry);
			return ERR_PTR(err);
		}
	}

874 875 876
	if (old->watch) {
		audit_get_watch(old->watch);
		new->watch = old->watch;
Amy Griffis's avatar
Amy Griffis committed
877 878
	}

879 880 881
	return entry;
}

Amy Griffis's avatar
Amy Griffis committed
882 883 884
/* 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,
Al Viro's avatar
Al Viro committed
885
					   struct list_head **p)
Amy Griffis's avatar
Amy Griffis committed
886 887
{
	struct audit_entry *e, *found = NULL;
Al Viro's avatar
Al Viro committed
888
	struct list_head *list;
Amy Griffis's avatar
Amy Griffis committed
889 890
	int h;

Al Viro's avatar
Al Viro committed
891 892 893 894
	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) {
Amy Griffis's avatar
Amy Griffis committed
895 896 897 898 899 900 901 902 903 904
		/* 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;
Al Viro's avatar
Al Viro committed
905 906
	} else {
		*p = list = &audit_filter_list[entry->rule.listnr];
Amy Griffis's avatar
Amy Griffis committed
907 908 909 910 911 912 913 914 915 916 917 918
	}

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

out:
	return found;
}

919 920 921
static u64 prio_low = ~0ULL/2;
static u64 prio_high = ~0ULL/2 - 1;

Amy Griffis's avatar
Amy Griffis committed
922
/* Add rule to given filterlist if not a duplicate. */
Al Viro's avatar
Al Viro committed
923
static inline int audit_add_rule(struct audit_entry *entry)
924
{
925
	struct audit_entry *e;
Amy Griffis's avatar
Amy Griffis committed
926
	struct audit_watch *watch = entry->rule.watch;
Al Viro's avatar
Al Viro committed
927
	struct audit_tree *tree = entry->rule.tree;
Al Viro's avatar
Al Viro committed
928
	struct list_head *list;
929
	int err;
930 931 932 933 934 935 936 937
#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
Amy Griffis's avatar
Amy Griffis committed
938 939

	mutex_lock(&audit_filter_mutex);
Al Viro's avatar
Al Viro committed
940
	e = audit_find_rule(entry, &list);
Amy Griffis's avatar
Amy Griffis committed
941
	if (e) {
942
		mutex_unlock(&audit_filter_mutex);
Amy Griffis's avatar
Amy Griffis committed
943
		err = -EEXIST;
Al Viro's avatar
Al Viro committed
944 945 946
		/* normally audit_add_tree_rule() will free it on failure */
		if (tree)
			audit_put_tree(tree);
Amy Griffis's avatar
Amy Griffis committed
947 948
		goto error;
	}
949

Amy Griffis's avatar
Amy Griffis committed
950 951
	if (watch) {
		/* audit_filter_mutex is dropped and re-taken during this call */
952
		err = audit_add_watch(&entry->rule, &list);
Amy Griffis's avatar
Amy Griffis committed
953 954 955 956
		if (err) {
			mutex_unlock(&audit_filter_mutex);
			goto error;
		}
957
	}
Al Viro's avatar
Al Viro committed
958 959 960 961 962 963 964
	if (tree) {
		err = audit_add_tree_rule(&entry->rule);
		if (err) {
			mutex_unlock(&audit_filter_mutex);
			goto error;
		}
	}
965

966 967 968 969 970 971 972 973
	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;
	}

974
	if (entry->rule.flags & AUDIT_FILTER_PREPEND) {
Al Viro's avatar
Al Viro committed
975 976
		list_add(&entry->rule.list,
			 &audit_rules_list[entry->rule.listnr]);
977
		list_add_rcu(&entry->list, list);
978
		entry->rule.flags &= ~AUDIT_FILTER_PREPEND;
979
	} else {
Al Viro's avatar
Al Viro committed
980 981
		list_add_tail(&entry->rule.list,
			      &audit_rules_list[entry->rule.listnr]);
982 983
		list_add_tail_rcu(&entry->list, list);
	}
984 985 986
#ifdef CONFIG_AUDITSYSCALL
	if (!dont_count)
		audit_n_rules++;
Amy Griffis's avatar
Amy Griffis committed
987 988 989

	if (!audit_match_signal(entry))
		audit_signals++;
990
#endif
Amy Griffis's avatar
Amy Griffis committed
991
	mutex_unlock(&audit_filter_mutex);
992

Amy Griffis's avatar
Amy Griffis committed
993 994 995 996 997 998
 	return 0;

error:
	if (watch)
		audit_put_watch(watch); /* tmp watch, matches initial get */
	return err;
999 1000
}

Amy Griffis's avatar
Amy Griffis committed
1001
/* Remove an existing rule from filterlist. */
Al Viro's avatar
Al Viro committed
1002
static inline int audit_del_rule(struct audit_entry *entry)
1003 1004
{
	struct audit_entry  *e;
1005
	struct audit_watch *watch = entry->rule.watch;
Al Viro's avatar
Al Viro committed
1006
	struct audit_tree *tree = entry->rule.tree;
Al Viro's avatar
Al Viro committed
1007 1008
	struct list_head *list;
	int ret = 0;
1009 1010 1011 1012 1013 1014 1015 1016
#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
Amy Griffis's avatar
Amy Griffis committed
1017 1018

	mutex_lock(&audit_filter_mutex);
Al Viro's avatar
Al Viro committed
1019
	e = audit_find_rule(entry, &list);
Amy Griffis's avatar
Amy Griffis committed
1020 1021 1022 1023 1024 1025
	if (!e) {
		mutex_unlock(&audit_filter_mutex);
		ret = -ENOENT;
		goto out;
	}

1026
	if (e->rule.watch)
1027
		audit_remove_watch_rule(&e->rule);
Amy Griffis's avatar
Amy Griffis committed
1028

Al Viro's avatar
Al Viro committed
1029 1030 1031
	if (e->rule.tree)
		audit_remove_tree_rule(&e->rule);

Amy Griffis's avatar
Amy Griffis committed
1032
	list_del_rcu(&e->list);
Al Viro's avatar
Al Viro committed
1033
	list_del(&e->rule.list);
Amy Griffis's avatar
Amy Griffis committed
1034 1035
	call_rcu(&e->rcu, audit_free_rule_rcu);

1036 1037 1038
#ifdef CONFIG_AUDITSYSCALL
	if (!dont_count)
		audit_n_rules--;
Amy Griffis's avatar
Amy Griffis committed
1039 1040 1041

	if (!audit_match_signal(entry))
		audit_signals--;
1042
#endif
Amy Griffis's avatar
Amy Griffis committed
1043 1044 1045
	mutex_unlock(&audit_filter_mutex);

out:
1046 1047
	if (watch)
		audit_put_watch(watch); /* match initial get */
Al Viro's avatar
Al Viro committed
1048 1049
	if (tree)
		audit_put_tree(tree);	/* that's the temporary one */
Amy Griffis's avatar
Amy Griffis committed
1050 1051

	return ret;
1052 1053
}

1054 1055
/* List rules using struct audit_rule.  Exists for backward
 * compatibility with userspace. */
1056
static void audit_list(int pid, int seq, struct sk_buff_head *q)
1057
{
1058
	struct sk_buff *skb;
Al Viro's avatar
Al Viro committed
1059
	struct audit_krule *r;
1060 1061
	int i;

Amy Griffis's avatar
Amy Griffis committed
1062 1063
	/* This is a blocking read, so use audit_filter_mutex instead of rcu
	 * iterator to sync with list writers. */
1064
	for (i=0; i<AUDIT_NR_FILTERS; i++) {
Al Viro's avatar
Al Viro committed
1065
		list_for_each_entry(r, &audit_rules_list[i], list) {
Amy Griffis's avatar
Amy Griffis committed
1066 1067
			struct audit_rule *rule;

Al Viro's avatar
Al Viro committed
1068
			rule = audit_krule_to_rule(r);
Amy Griffis's avatar
Amy Griffis committed
1069 1070 1071 1072 1073 1074 1075 1076 1077
			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);
		}
	}
1078 1079 1080
	skb = audit_make_reply(pid, seq, AUDIT_LIST, 1, 1, NULL, 0);
	if (skb)
		skb_queue_tail(q, skb);
1081 1082
}

1083
/* List rules using struct audit_rule_data. */
1084
static void audit_list_rules(int pid, int seq, struct sk_buff_head *q)
1085
{
1086
	struct sk_buff *skb;
Al Viro's avatar
Al Viro committed
1087
	struct audit_krule *r;
1088 1089
	int i;

Amy Griffis's avatar
Amy Griffis committed
1090 1091
	/* This is a blocking read, so use audit_filter_mutex instead of rcu
	 * iterator to sync with list writers. */
1092
	for (i=0; i<AUDIT_NR_FILTERS; i++) {
Al Viro's avatar
Al Viro committed
1093
		list_for_each_entry(r, &audit_rules_list[i], list) {
Amy Griffis's avatar
Amy Griffis committed
1094 1095
			struct audit_rule_data *data;

Al Viro's avatar
Al Viro committed
1096
			data = audit_krule_to_data(r);
Amy Griffis's avatar
Amy Griffis committed
1097 1098 1099 1100
			if (unlikely(!data))
				break;
			skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 0, 1,
					 data, sizeof(*data) + data->buflen);
1101 1102
			if (skb)
				skb_queue_tail(q, skb);
1103 1104 1105
			kfree(data);
		}
	}
1106 1107 1108
	skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 1, 1, NULL, 0);
	if (skb)
		skb_queue_tail(q, skb);
1109 1110
}

Amy Griffis's avatar
Amy Griffis committed
1111
/* Log rule additions and removals */
1112 1113 1114
static void audit_log_rule_change(uid_t loginuid, u32 sessionid, u32 sid,
				  char *action, struct audit_krule *rule,
				  int res)
Amy Griffis's avatar
Amy Griffis committed
1115 1116 1117
{
	struct audit_buffer *ab;

1118 1119 1120
	if (!audit_enabled)
		return;

Amy Griffis's avatar
Amy Griffis committed
1121 1122 1123
	ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
	if (!ab)
		return;
1124
	audit_log_format(ab, "auid=%u ses=%u", loginuid, sessionid);
Amy Griffis's avatar
Amy Griffis committed
1125 1126 1127
	if (sid) {
		char *ctx = NULL;
		u32 len;
1128
		if (security_secid_to_secctx(sid, &ctx, &len))
Amy Griffis's avatar
Amy Griffis committed
1129
			audit_log_format(ab, " ssid=%u", sid);
1130
		else {
Amy Griffis's avatar
Amy Griffis committed
1131
			audit_log_format(ab, " subj=%s", ctx);
1132 1133
			security_release_secctx(ctx, len);
		}
Amy Griffis's avatar
Amy Griffis committed
1134
	}
1135 1136 1137
	audit_log_format(ab, " op=");
	audit_log_string(ab, action);
	audit_log_key(ab, rule->filterkey);
Amy Griffis's avatar
Amy Griffis committed
1138 1139 1140 1141
	audit_log_format(ab, " list=%d res=%d", rule->listnr, res);
	audit_log_end(ab);
}

1142 1143 1144 1145 1146 1147 1148
/**
 * 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
1149
 * @datasz: size of payload data
1150
 * @loginuid: loginuid of sender
1151
 * @sessionid: sessionid for netlink audit message
1152
 * @sid: SE Linux Security ID of sender
1153
 */
1154
int audit_receive_filter(int type, int pid, int seq, void *data,
1155
			 size_t datasz, uid_t loginuid, u32 sessionid, u32 sid)
1156 1157
{
	struct task_struct *tsk;
1158
	struct audit_netlink_list *dest;
1159 1160
	int err = 0;
	struct audit_entry *entry;
1161 1162 1163

	switch (type) {
	case AUDIT_LIST:
1164
	case AUDIT_LIST_RULES:
1165 1166 1167 1168 1169
		/* 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 */
1170

1171
		dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL);
1172 1173
		if (!dest)
			return -ENOMEM;
1174 1175
		dest->pid = pid;
		skb_queue_head_init(&dest->q);
1176

Amy Griffis's avatar
Amy Griffis committed
1177
		mutex_lock(&audit_filter_mutex);
1178
		if (type == AUDIT_LIST)
1179
			audit_list(pid, seq, &dest->q);
1180
		else
1181
			audit_list_rules(pid, seq, &dest->q);
Amy Griffis's avatar
Amy Griffis committed
1182
		mutex_unlock(&audit_filter_mutex);
1183 1184

		tsk = kthread_run(audit_send_list, dest, "audit_send_list");
1185
		if (IS_ERR(tsk)) {
1186
			skb_queue_purge(&dest->q);
1187 1188 1189 1190 1191
			kfree(dest);
			err = PTR_ERR(tsk);
		}
		break;
	case AUDIT_ADD:
1192 1193 1194 1195 1196 1197 1198 1199
	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);

Al Viro's avatar
Al Viro committed
1200
		err = audit_add_rule(entry);
1201
		audit_log_rule_change(loginuid, sessionid, sid, "add rule",
1202
				      &entry->rule, !err);
Steve Grubb's avatar
Steve Grubb committed
1203 1204

		if (err)
1205
			audit_free_rule(entry);
1206 1207
		break;
	case AUDIT_DEL:
1208 1209 1210 1211 1212 1213 1214 1215
	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);

Al Viro's avatar
Al Viro committed
1216
		err = audit_del_rule(entry);
1217
		audit_log_rule_change(loginuid, sessionid, sid, "remove rule",
1218
				      &entry->rule, !err);
Steve Grubb's avatar
Steve Grubb committed
1219

1220
		audit_free_rule(entry);
1221 1222 1223 1224 1225 1226 1227 1228
		break;
	default:
		return -EINVAL;
	}

	return err;
}

1229
int audit_comparator(u32 left, u32 op, u32 right)
1230 1231
{
	switch (op) {
1232
	case Audit_equal:
1233
		return (left == right);
1234
	case Audit_not_equal:
1235
		return (left != right);
1236
	case Audit_lt:
1237
		return (left < right);
1238
	case Audit_le:
1239
		return (left <= right);
1240
	case Audit_gt:
1241
		return (left > right);
1242
	case Audit_ge:
1243
		return (left >= right);
1244
	case Audit_bitmask:
1245
		return (left & right);
1246
	case Audit_bittest:
1247
		return ((left & right) == right);
1248 1249 1250
	default:
		BUG();
		return 0;
1251 1252 1253
	}
}

1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299
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;
	}
}

Amy Griffis's avatar
Amy Griffis committed
1300 1301
/* Compare given dentry name with last component in given path,
 * return of 0 indicates a match. */
1302 1303
int audit_compare_dname_path(const char *dname, const char *path,
			     int *dirlen)
Amy Griffis's avatar
Amy Griffis committed
1304 1305 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
{
	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++;
	}
1331

1332 1333 1334
	/* return length of path's directory component */
	if (dirlen)
		*dirlen = p - path;
Amy Griffis's avatar
Amy Griffis committed
1335 1336
	return strncmp(p, dname, dlen);
}
1337

1338
static int audit_filter_user_rules(struct audit_krule *rule,
1339 1340 1341 1342 1343
				   enum audit_state *state)
{
	int i;

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

1348
		switch (f->type) {
1349
		case AUDIT_PID:
1350
			result = audit_comparator(task_pid_vnr(current), f->op, f->val);
1351 1352
			break;
		case AUDIT_UID:
1353
			result = audit_uid_comparator(current_uid(), f->op, f->uid);
1354 1355
			break;
		case AUDIT_GID:
1356
			result = audit_gid_comparator(current_gid(), f->op, f->gid);
1357 1358
			break;
		case AUDIT_LOGINUID:
1359 1360
			result = audit_uid_comparator(audit_get_loginuid(current),
						  f->op, f->uid);
1361
			break;
1362 1363 1364 1365 1366
		case AUDIT_SUBJ_USER:
		case AUDIT_SUBJ_ROLE:
		case AUDIT_SUBJ_TYPE:
		case AUDIT_SUBJ_SEN:
		case AUDIT_SUBJ_CLR:
1367 1368 1369
			if (f->lsm_rule) {
				security_task_getsecid(current, &sid);
				result = security_audit_rule_match(sid,
1370 1371 1372 1373
								   f->type,
								   f->op,
								   f->lsm_rule,
								   NULL);
1374
			}
1375
			break;
1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387
		}

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

1388
int audit_filter_user(void)
1389
{
1390
	enum audit_state state = AUDIT_DISABLED;
1391 1392 1393 1394 1395
	struct audit_entry *e;
	int ret = 1;

	rcu_read_lock();
	list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) {
1396
		if (audit_filter_user_rules(&e->rule, &state)) {
1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410
			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;
1411

1412 1413 1414 1415 1416 1417 1418
	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;
1419 1420 1421 1422
		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);
1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433
				if (!result)
					break;
			}
		}
		if (result)
			goto unlock_and_return;
	}
unlock_and_return:
	rcu_read_unlock();
	return result;
}
1434

Al Viro's avatar
Al Viro committed
1435
static int update_lsm_rule(struct audit_krule *r)
1436
{
Al Viro's avatar
Al Viro committed
1437
	struct audit_entry *entry = container_of(r, struct audit_entry, rule);
1438 1439 1440
	struct audit_entry *nentry;
	int err = 0;

Al Viro's avatar
Al Viro committed
1441
	if (!security_audit_rule_known(r))
1442 1443
		return 0;

1444
	nentry = audit_dupe_rule(r);
1445 1446 1447 1448 1449
	if (IS_ERR(nentry)) {
		/* save the first error encountered for the
		 * return value */
		err = PTR_ERR(nentry);
		audit_panic("error updating LSM filters");
1450
		if (r->watch)
Al Viro's avatar
Al Viro committed
1451
			list_del(&r->rlist);
1452
		list_del_rcu(&entry->list);
Al Viro's avatar
Al Viro committed
1453
		list_del(&r->list);
1454
	} else {
1455
		if (r->watch || r->tree)
Al Viro's avatar
Al Viro committed
1456
			list_replace_init(&r->rlist, &nentry->rule.rlist);
1457
		list_replace_rcu(&entry->list, &nentry->list);
Al Viro's avatar
Al Viro committed
1458
		list_replace(&r->list, &nentry->rule.list);
1459 1460 1461 1462 1463 1464
	}
	call_rcu(&entry->rcu, audit_free_rule_rcu);

	return err;
}

1465
/* This function will re-initialize the lsm_rule field of all applicable rules.
1466
 * It will traverse the filter lists serarching for rules that contain LSM
1467
 * specific filter fields.  When such a rule is found, it is copied, the
1468
 * LSM field is re-initialized, and the old rule is replaced with the
1469
 * updated rule. */
1470
int audit_update_lsm_rules(void)
1471
{
Al Viro's avatar
Al Viro committed
1472
	struct audit_krule *r, *n;
1473 1474
	int i, err = 0;

Amy Griffis's avatar
Amy Griffis committed
1475 1476
	/* audit_filter_mutex synchronizes the writers */
	mutex_lock(&audit_filter_mutex);
1477 1478

	for (i = 0; i < AUDIT_NR_FILTERS; i++) {
Al Viro's avatar
Al Viro committed
1479 1480
		list_for_each_entry_safe(r, n, &audit_rules_list[i], list) {
			int res = update_lsm_rule(r);
1481 1482
			if (!err)
				err = res;
1483 1484
		}
	}
Amy Griffis's avatar
Amy Griffis committed
1485
	mutex_unlock(&audit_filter_mutex);
1486 1487 1488

	return err;
}