diff options
Diffstat (limited to 'kernel/auditfilter.c')
-rw-r--r-- | kernel/auditfilter.c | 367 |
1 files changed, 114 insertions, 253 deletions
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index f9fc54bbe06f..6bd4a90d1991 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c | |||
@@ -310,121 +310,83 @@ static u32 audit_to_op(u32 op) | |||
310 | return n; | 310 | return n; |
311 | } | 311 | } |
312 | 312 | ||
313 | 313 | /* check if an audit field is valid */ | |
314 | /* Translate struct audit_rule to kernel's rule respresentation. | 314 | static int audit_field_valid(struct audit_entry *entry, struct audit_field *f) |
315 | * Exists for backward compatibility with userspace. */ | ||
316 | static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule) | ||
317 | { | 315 | { |
318 | struct audit_entry *entry; | 316 | switch(f->type) { |
319 | int err = 0; | 317 | case AUDIT_MSGTYPE: |
320 | int i; | 318 | if (entry->rule.listnr != AUDIT_FILTER_TYPE && |
321 | 319 | entry->rule.listnr != AUDIT_FILTER_USER) | |
322 | entry = audit_to_entry_common(rule); | 320 | return -EINVAL; |
323 | if (IS_ERR(entry)) | 321 | break; |
324 | goto exit_nofree; | 322 | }; |
325 | |||
326 | for (i = 0; i < rule->field_count; i++) { | ||
327 | struct audit_field *f = &entry->rule.fields[i]; | ||
328 | u32 n; | ||
329 | |||
330 | n = rule->fields[i] & (AUDIT_NEGATE|AUDIT_OPERATORS); | ||
331 | |||
332 | /* Support for legacy operators where | ||
333 | * AUDIT_NEGATE bit signifies != and otherwise assumes == */ | ||
334 | if (n & AUDIT_NEGATE) | ||
335 | f->op = Audit_not_equal; | ||
336 | else if (!n) | ||
337 | f->op = Audit_equal; | ||
338 | else | ||
339 | f->op = audit_to_op(n); | ||
340 | |||
341 | entry->rule.vers_ops = (n & AUDIT_OPERATORS) ? 2 : 1; | ||
342 | |||
343 | f->type = rule->fields[i] & ~(AUDIT_NEGATE|AUDIT_OPERATORS); | ||
344 | f->val = rule->values[i]; | ||
345 | f->uid = INVALID_UID; | ||
346 | f->gid = INVALID_GID; | ||
347 | |||
348 | err = -EINVAL; | ||
349 | if (f->op == Audit_bad) | ||
350 | goto exit_free; | ||
351 | |||
352 | switch(f->type) { | ||
353 | default: | ||
354 | goto exit_free; | ||
355 | case AUDIT_UID: | ||
356 | case AUDIT_EUID: | ||
357 | case AUDIT_SUID: | ||
358 | case AUDIT_FSUID: | ||
359 | case AUDIT_LOGINUID: | ||
360 | /* bit ops not implemented for uid comparisons */ | ||
361 | if (f->op == Audit_bitmask || f->op == Audit_bittest) | ||
362 | goto exit_free; | ||
363 | |||
364 | f->uid = make_kuid(current_user_ns(), f->val); | ||
365 | if (!uid_valid(f->uid)) | ||
366 | goto exit_free; | ||
367 | break; | ||
368 | case AUDIT_GID: | ||
369 | case AUDIT_EGID: | ||
370 | case AUDIT_SGID: | ||
371 | case AUDIT_FSGID: | ||
372 | /* bit ops not implemented for gid comparisons */ | ||
373 | if (f->op == Audit_bitmask || f->op == Audit_bittest) | ||
374 | goto exit_free; | ||
375 | |||
376 | f->gid = make_kgid(current_user_ns(), f->val); | ||
377 | if (!gid_valid(f->gid)) | ||
378 | goto exit_free; | ||
379 | break; | ||
380 | case AUDIT_PID: | ||
381 | case AUDIT_PERS: | ||
382 | case AUDIT_MSGTYPE: | ||
383 | case AUDIT_PPID: | ||
384 | case AUDIT_DEVMAJOR: | ||
385 | case AUDIT_DEVMINOR: | ||
386 | case AUDIT_EXIT: | ||
387 | case AUDIT_SUCCESS: | ||
388 | /* bit ops are only useful on syscall args */ | ||
389 | if (f->op == Audit_bitmask || f->op == Audit_bittest) | ||
390 | goto exit_free; | ||
391 | break; | ||
392 | case AUDIT_ARG0: | ||
393 | case AUDIT_ARG1: | ||
394 | case AUDIT_ARG2: | ||
395 | case AUDIT_ARG3: | ||
396 | break; | ||
397 | /* arch is only allowed to be = or != */ | ||
398 | case AUDIT_ARCH: | ||
399 | if (f->op != Audit_not_equal && f->op != Audit_equal) | ||
400 | goto exit_free; | ||
401 | entry->rule.arch_f = f; | ||
402 | break; | ||
403 | case AUDIT_PERM: | ||
404 | if (f->val & ~15) | ||
405 | goto exit_free; | ||
406 | break; | ||
407 | case AUDIT_FILETYPE: | ||
408 | if (f->val & ~S_IFMT) | ||
409 | goto exit_free; | ||
410 | break; | ||
411 | case AUDIT_INODE: | ||
412 | err = audit_to_inode(&entry->rule, f); | ||
413 | if (err) | ||
414 | goto exit_free; | ||
415 | break; | ||
416 | } | ||
417 | } | ||
418 | |||
419 | if (entry->rule.inode_f && entry->rule.inode_f->op == Audit_not_equal) | ||
420 | entry->rule.inode_f = NULL; | ||
421 | |||
422 | exit_nofree: | ||
423 | return entry; | ||
424 | 323 | ||
425 | exit_free: | 324 | switch(f->type) { |
426 | audit_free_rule(entry); | 325 | default: |
427 | return ERR_PTR(err); | 326 | return -EINVAL; |
327 | case AUDIT_UID: | ||
328 | case AUDIT_EUID: | ||
329 | case AUDIT_SUID: | ||
330 | case AUDIT_FSUID: | ||
331 | case AUDIT_LOGINUID: | ||
332 | case AUDIT_OBJ_UID: | ||
333 | case AUDIT_GID: | ||
334 | case AUDIT_EGID: | ||
335 | case AUDIT_SGID: | ||
336 | case AUDIT_FSGID: | ||
337 | case AUDIT_OBJ_GID: | ||
338 | case AUDIT_PID: | ||
339 | case AUDIT_PERS: | ||
340 | case AUDIT_MSGTYPE: | ||
341 | case AUDIT_PPID: | ||
342 | case AUDIT_DEVMAJOR: | ||
343 | case AUDIT_DEVMINOR: | ||
344 | case AUDIT_EXIT: | ||
345 | case AUDIT_SUCCESS: | ||
346 | /* bit ops are only useful on syscall args */ | ||
347 | if (f->op == Audit_bitmask || f->op == Audit_bittest) | ||
348 | return -EINVAL; | ||
349 | break; | ||
350 | case AUDIT_ARG0: | ||
351 | case AUDIT_ARG1: | ||
352 | case AUDIT_ARG2: | ||
353 | case AUDIT_ARG3: | ||
354 | case AUDIT_SUBJ_USER: | ||
355 | case AUDIT_SUBJ_ROLE: | ||
356 | case AUDIT_SUBJ_TYPE: | ||
357 | case AUDIT_SUBJ_SEN: | ||
358 | case AUDIT_SUBJ_CLR: | ||
359 | case AUDIT_OBJ_USER: | ||
360 | case AUDIT_OBJ_ROLE: | ||
361 | case AUDIT_OBJ_TYPE: | ||
362 | case AUDIT_OBJ_LEV_LOW: | ||
363 | case AUDIT_OBJ_LEV_HIGH: | ||
364 | case AUDIT_WATCH: | ||
365 | case AUDIT_DIR: | ||
366 | case AUDIT_FILTERKEY: | ||
367 | break; | ||
368 | case AUDIT_LOGINUID_SET: | ||
369 | if ((f->val != 0) && (f->val != 1)) | ||
370 | return -EINVAL; | ||
371 | /* FALL THROUGH */ | ||
372 | case AUDIT_ARCH: | ||
373 | if (f->op != Audit_not_equal && f->op != Audit_equal) | ||
374 | return -EINVAL; | ||
375 | break; | ||
376 | case AUDIT_PERM: | ||
377 | if (f->val & ~15) | ||
378 | return -EINVAL; | ||
379 | break; | ||
380 | case AUDIT_FILETYPE: | ||
381 | if (f->val & ~S_IFMT) | ||
382 | return -EINVAL; | ||
383 | break; | ||
384 | case AUDIT_FIELD_COMPARE: | ||
385 | if (f->val > AUDIT_MAX_FIELD_COMPARE) | ||
386 | return -EINVAL; | ||
387 | break; | ||
388 | }; | ||
389 | return 0; | ||
428 | } | 390 | } |
429 | 391 | ||
430 | /* Translate struct audit_rule_data to kernel's rule respresentation. */ | 392 | /* Translate struct audit_rule_data to kernel's rule respresentation. */ |
@@ -459,17 +421,25 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, | |||
459 | f->gid = INVALID_GID; | 421 | f->gid = INVALID_GID; |
460 | f->lsm_str = NULL; | 422 | f->lsm_str = NULL; |
461 | f->lsm_rule = NULL; | 423 | f->lsm_rule = NULL; |
462 | switch(f->type) { | 424 | |
425 | /* Support legacy tests for a valid loginuid */ | ||
426 | if ((f->type == AUDIT_LOGINUID) && (f->val == 4294967295)) { | ||
427 | f->type = AUDIT_LOGINUID_SET; | ||
428 | f->val = 0; | ||
429 | } | ||
430 | |||
431 | err = audit_field_valid(entry, f); | ||
432 | if (err) | ||
433 | goto exit_free; | ||
434 | |||
435 | err = -EINVAL; | ||
436 | switch (f->type) { | ||
437 | case AUDIT_LOGINUID: | ||
463 | case AUDIT_UID: | 438 | case AUDIT_UID: |
464 | case AUDIT_EUID: | 439 | case AUDIT_EUID: |
465 | case AUDIT_SUID: | 440 | case AUDIT_SUID: |
466 | case AUDIT_FSUID: | 441 | case AUDIT_FSUID: |
467 | case AUDIT_LOGINUID: | ||
468 | case AUDIT_OBJ_UID: | 442 | case AUDIT_OBJ_UID: |
469 | /* bit ops not implemented for uid comparisons */ | ||
470 | if (f->op == Audit_bitmask || f->op == Audit_bittest) | ||
471 | goto exit_free; | ||
472 | |||
473 | f->uid = make_kuid(current_user_ns(), f->val); | 443 | f->uid = make_kuid(current_user_ns(), f->val); |
474 | if (!uid_valid(f->uid)) | 444 | if (!uid_valid(f->uid)) |
475 | goto exit_free; | 445 | goto exit_free; |
@@ -479,27 +449,10 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, | |||
479 | case AUDIT_SGID: | 449 | case AUDIT_SGID: |
480 | case AUDIT_FSGID: | 450 | case AUDIT_FSGID: |
481 | case AUDIT_OBJ_GID: | 451 | case AUDIT_OBJ_GID: |
482 | /* bit ops not implemented for gid comparisons */ | ||
483 | if (f->op == Audit_bitmask || f->op == Audit_bittest) | ||
484 | goto exit_free; | ||
485 | |||
486 | f->gid = make_kgid(current_user_ns(), f->val); | 452 | f->gid = make_kgid(current_user_ns(), f->val); |
487 | if (!gid_valid(f->gid)) | 453 | if (!gid_valid(f->gid)) |
488 | goto exit_free; | 454 | goto exit_free; |
489 | break; | 455 | break; |
490 | case AUDIT_PID: | ||
491 | case AUDIT_PERS: | ||
492 | case AUDIT_MSGTYPE: | ||
493 | case AUDIT_PPID: | ||
494 | case AUDIT_DEVMAJOR: | ||
495 | case AUDIT_DEVMINOR: | ||
496 | case AUDIT_EXIT: | ||
497 | case AUDIT_SUCCESS: | ||
498 | case AUDIT_ARG0: | ||
499 | case AUDIT_ARG1: | ||
500 | case AUDIT_ARG2: | ||
501 | case AUDIT_ARG3: | ||
502 | break; | ||
503 | case AUDIT_ARCH: | 456 | case AUDIT_ARCH: |
504 | entry->rule.arch_f = f; | 457 | entry->rule.arch_f = f; |
505 | break; | 458 | break; |
@@ -570,20 +523,6 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, | |||
570 | entry->rule.buflen += f->val; | 523 | entry->rule.buflen += f->val; |
571 | entry->rule.filterkey = str; | 524 | entry->rule.filterkey = str; |
572 | break; | 525 | break; |
573 | case AUDIT_PERM: | ||
574 | if (f->val & ~15) | ||
575 | goto exit_free; | ||
576 | break; | ||
577 | case AUDIT_FILETYPE: | ||
578 | if (f->val & ~S_IFMT) | ||
579 | goto exit_free; | ||
580 | break; | ||
581 | case AUDIT_FIELD_COMPARE: | ||
582 | if (f->val > AUDIT_MAX_FIELD_COMPARE) | ||
583 | goto exit_free; | ||
584 | break; | ||
585 | default: | ||
586 | goto exit_free; | ||
587 | } | 526 | } |
588 | } | 527 | } |
589 | 528 | ||
@@ -594,6 +533,10 @@ exit_nofree: | |||
594 | return entry; | 533 | return entry; |
595 | 534 | ||
596 | exit_free: | 535 | exit_free: |
536 | if (entry->rule.watch) | ||
537 | audit_put_watch(entry->rule.watch); /* matches initial get */ | ||
538 | if (entry->rule.tree) | ||
539 | audit_put_tree(entry->rule.tree); /* that's the temporary one */ | ||
597 | audit_free_rule(entry); | 540 | audit_free_rule(entry); |
598 | return ERR_PTR(err); | 541 | return ERR_PTR(err); |
599 | } | 542 | } |
@@ -609,36 +552,6 @@ static inline size_t audit_pack_string(void **bufp, const char *str) | |||
609 | return len; | 552 | return len; |
610 | } | 553 | } |
611 | 554 | ||
612 | /* Translate kernel rule respresentation to struct audit_rule. | ||
613 | * Exists for backward compatibility with userspace. */ | ||
614 | static struct audit_rule *audit_krule_to_rule(struct audit_krule *krule) | ||
615 | { | ||
616 | struct audit_rule *rule; | ||
617 | int i; | ||
618 | |||
619 | rule = kzalloc(sizeof(*rule), GFP_KERNEL); | ||
620 | if (unlikely(!rule)) | ||
621 | return NULL; | ||
622 | |||
623 | rule->flags = krule->flags | krule->listnr; | ||
624 | rule->action = krule->action; | ||
625 | rule->field_count = krule->field_count; | ||
626 | for (i = 0; i < rule->field_count; i++) { | ||
627 | rule->values[i] = krule->fields[i].val; | ||
628 | rule->fields[i] = krule->fields[i].type; | ||
629 | |||
630 | if (krule->vers_ops == 1) { | ||
631 | if (krule->fields[i].op == Audit_not_equal) | ||
632 | rule->fields[i] |= AUDIT_NEGATE; | ||
633 | } else { | ||
634 | rule->fields[i] |= audit_ops[krule->fields[i].op]; | ||
635 | } | ||
636 | } | ||
637 | for (i = 0; i < AUDIT_BITMASK_SIZE; i++) rule->mask[i] = krule->mask[i]; | ||
638 | |||
639 | return rule; | ||
640 | } | ||
641 | |||
642 | /* Translate kernel rule respresentation to struct audit_rule_data. */ | 555 | /* Translate kernel rule respresentation to struct audit_rule_data. */ |
643 | static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule) | 556 | static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule) |
644 | { | 557 | { |
@@ -1051,35 +964,6 @@ out: | |||
1051 | return ret; | 964 | return ret; |
1052 | } | 965 | } |
1053 | 966 | ||
1054 | /* List rules using struct audit_rule. Exists for backward | ||
1055 | * compatibility with userspace. */ | ||
1056 | static void audit_list(int pid, int seq, struct sk_buff_head *q) | ||
1057 | { | ||
1058 | struct sk_buff *skb; | ||
1059 | struct audit_krule *r; | ||
1060 | int i; | ||
1061 | |||
1062 | /* This is a blocking read, so use audit_filter_mutex instead of rcu | ||
1063 | * iterator to sync with list writers. */ | ||
1064 | for (i=0; i<AUDIT_NR_FILTERS; i++) { | ||
1065 | list_for_each_entry(r, &audit_rules_list[i], list) { | ||
1066 | struct audit_rule *rule; | ||
1067 | |||
1068 | rule = audit_krule_to_rule(r); | ||
1069 | if (unlikely(!rule)) | ||
1070 | break; | ||
1071 | skb = audit_make_reply(pid, seq, AUDIT_LIST, 0, 1, | ||
1072 | rule, sizeof(*rule)); | ||
1073 | if (skb) | ||
1074 | skb_queue_tail(q, skb); | ||
1075 | kfree(rule); | ||
1076 | } | ||
1077 | } | ||
1078 | skb = audit_make_reply(pid, seq, AUDIT_LIST, 1, 1, NULL, 0); | ||
1079 | if (skb) | ||
1080 | skb_queue_tail(q, skb); | ||
1081 | } | ||
1082 | |||
1083 | /* List rules using struct audit_rule_data. */ | 967 | /* List rules using struct audit_rule_data. */ |
1084 | static void audit_list_rules(int pid, int seq, struct sk_buff_head *q) | 968 | static void audit_list_rules(int pid, int seq, struct sk_buff_head *q) |
1085 | { | 969 | { |
@@ -1109,11 +993,11 @@ static void audit_list_rules(int pid, int seq, struct sk_buff_head *q) | |||
1109 | } | 993 | } |
1110 | 994 | ||
1111 | /* Log rule additions and removals */ | 995 | /* Log rule additions and removals */ |
1112 | static void audit_log_rule_change(kuid_t loginuid, u32 sessionid, u32 sid, | 996 | static void audit_log_rule_change(char *action, struct audit_krule *rule, int res) |
1113 | char *action, struct audit_krule *rule, | ||
1114 | int res) | ||
1115 | { | 997 | { |
1116 | struct audit_buffer *ab; | 998 | struct audit_buffer *ab; |
999 | uid_t loginuid = from_kuid(&init_user_ns, audit_get_loginuid(current)); | ||
1000 | u32 sessionid = audit_get_sessionid(current); | ||
1117 | 1001 | ||
1118 | if (!audit_enabled) | 1002 | if (!audit_enabled) |
1119 | return; | 1003 | return; |
@@ -1121,18 +1005,8 @@ static void audit_log_rule_change(kuid_t loginuid, u32 sessionid, u32 sid, | |||
1121 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); | 1005 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); |
1122 | if (!ab) | 1006 | if (!ab) |
1123 | return; | 1007 | return; |
1124 | audit_log_format(ab, "auid=%u ses=%u", | 1008 | audit_log_format(ab, "auid=%u ses=%u" ,loginuid, sessionid); |
1125 | from_kuid(&init_user_ns, loginuid), sessionid); | 1009 | audit_log_task_context(ab); |
1126 | if (sid) { | ||
1127 | char *ctx = NULL; | ||
1128 | u32 len; | ||
1129 | if (security_secid_to_secctx(sid, &ctx, &len)) | ||
1130 | audit_log_format(ab, " ssid=%u", sid); | ||
1131 | else { | ||
1132 | audit_log_format(ab, " subj=%s", ctx); | ||
1133 | security_release_secctx(ctx, len); | ||
1134 | } | ||
1135 | } | ||
1136 | audit_log_format(ab, " op="); | 1010 | audit_log_format(ab, " op="); |
1137 | audit_log_string(ab, action); | 1011 | audit_log_string(ab, action); |
1138 | audit_log_key(ab, rule->filterkey); | 1012 | audit_log_key(ab, rule->filterkey); |
@@ -1147,12 +1021,8 @@ static void audit_log_rule_change(kuid_t loginuid, u32 sessionid, u32 sid, | |||
1147 | * @seq: netlink audit message sequence (serial) number | 1021 | * @seq: netlink audit message sequence (serial) number |
1148 | * @data: payload data | 1022 | * @data: payload data |
1149 | * @datasz: size of payload data | 1023 | * @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 | */ | 1024 | */ |
1154 | int audit_receive_filter(int type, int pid, int seq, void *data, | 1025 | int audit_receive_filter(int type, int pid, int seq, void *data, size_t datasz) |
1155 | size_t datasz, kuid_t loginuid, u32 sessionid, u32 sid) | ||
1156 | { | 1026 | { |
1157 | struct task_struct *tsk; | 1027 | struct task_struct *tsk; |
1158 | struct audit_netlink_list *dest; | 1028 | struct audit_netlink_list *dest; |
@@ -1160,7 +1030,6 @@ int audit_receive_filter(int type, int pid, int seq, void *data, | |||
1160 | struct audit_entry *entry; | 1030 | struct audit_entry *entry; |
1161 | 1031 | ||
1162 | switch (type) { | 1032 | switch (type) { |
1163 | case AUDIT_LIST: | ||
1164 | case AUDIT_LIST_RULES: | 1033 | case AUDIT_LIST_RULES: |
1165 | /* We can't just spew out the rules here because we might fill | 1034 | /* We can't just spew out the rules here because we might fill |
1166 | * the available socket buffer space and deadlock waiting for | 1035 | * the available socket buffer space and deadlock waiting for |
@@ -1175,10 +1044,7 @@ int audit_receive_filter(int type, int pid, int seq, void *data, | |||
1175 | skb_queue_head_init(&dest->q); | 1044 | skb_queue_head_init(&dest->q); |
1176 | 1045 | ||
1177 | mutex_lock(&audit_filter_mutex); | 1046 | mutex_lock(&audit_filter_mutex); |
1178 | if (type == AUDIT_LIST) | 1047 | audit_list_rules(pid, seq, &dest->q); |
1179 | audit_list(pid, seq, &dest->q); | ||
1180 | else | ||
1181 | audit_list_rules(pid, seq, &dest->q); | ||
1182 | mutex_unlock(&audit_filter_mutex); | 1048 | mutex_unlock(&audit_filter_mutex); |
1183 | 1049 | ||
1184 | tsk = kthread_run(audit_send_list, dest, "audit_send_list"); | 1050 | tsk = kthread_run(audit_send_list, dest, "audit_send_list"); |
@@ -1188,35 +1054,23 @@ int audit_receive_filter(int type, int pid, int seq, void *data, | |||
1188 | err = PTR_ERR(tsk); | 1054 | err = PTR_ERR(tsk); |
1189 | } | 1055 | } |
1190 | break; | 1056 | break; |
1191 | case AUDIT_ADD: | ||
1192 | case AUDIT_ADD_RULE: | 1057 | case AUDIT_ADD_RULE: |
1193 | if (type == AUDIT_ADD) | 1058 | entry = audit_data_to_entry(data, datasz); |
1194 | entry = audit_rule_to_entry(data); | ||
1195 | else | ||
1196 | entry = audit_data_to_entry(data, datasz); | ||
1197 | if (IS_ERR(entry)) | 1059 | if (IS_ERR(entry)) |
1198 | return PTR_ERR(entry); | 1060 | return PTR_ERR(entry); |
1199 | 1061 | ||
1200 | err = audit_add_rule(entry); | 1062 | err = audit_add_rule(entry); |
1201 | audit_log_rule_change(loginuid, sessionid, sid, "add rule", | 1063 | audit_log_rule_change("add rule", &entry->rule, !err); |
1202 | &entry->rule, !err); | ||
1203 | |||
1204 | if (err) | 1064 | if (err) |
1205 | audit_free_rule(entry); | 1065 | audit_free_rule(entry); |
1206 | break; | 1066 | break; |
1207 | case AUDIT_DEL: | ||
1208 | case AUDIT_DEL_RULE: | 1067 | case AUDIT_DEL_RULE: |
1209 | if (type == AUDIT_DEL) | 1068 | entry = audit_data_to_entry(data, datasz); |
1210 | entry = audit_rule_to_entry(data); | ||
1211 | else | ||
1212 | entry = audit_data_to_entry(data, datasz); | ||
1213 | if (IS_ERR(entry)) | 1069 | if (IS_ERR(entry)) |
1214 | return PTR_ERR(entry); | 1070 | return PTR_ERR(entry); |
1215 | 1071 | ||
1216 | err = audit_del_rule(entry); | 1072 | err = audit_del_rule(entry); |
1217 | audit_log_rule_change(loginuid, sessionid, sid, "remove rule", | 1073 | audit_log_rule_change("remove rule", &entry->rule, !err); |
1218 | &entry->rule, !err); | ||
1219 | |||
1220 | audit_free_rule(entry); | 1074 | audit_free_rule(entry); |
1221 | break; | 1075 | break; |
1222 | default: | 1076 | default: |
@@ -1354,7 +1208,7 @@ int audit_compare_dname_path(const char *dname, const char *path, int parentlen) | |||
1354 | return strncmp(p, dname, dlen); | 1208 | return strncmp(p, dname, dlen); |
1355 | } | 1209 | } |
1356 | 1210 | ||
1357 | static int audit_filter_user_rules(struct audit_krule *rule, | 1211 | static int audit_filter_user_rules(struct audit_krule *rule, int type, |
1358 | enum audit_state *state) | 1212 | enum audit_state *state) |
1359 | { | 1213 | { |
1360 | int i; | 1214 | int i; |
@@ -1378,6 +1232,13 @@ static int audit_filter_user_rules(struct audit_krule *rule, | |||
1378 | result = audit_uid_comparator(audit_get_loginuid(current), | 1232 | result = audit_uid_comparator(audit_get_loginuid(current), |
1379 | f->op, f->uid); | 1233 | f->op, f->uid); |
1380 | break; | 1234 | break; |
1235 | case AUDIT_LOGINUID_SET: | ||
1236 | result = audit_comparator(audit_loginuid_set(current), | ||
1237 | f->op, f->val); | ||
1238 | break; | ||
1239 | case AUDIT_MSGTYPE: | ||
1240 | result = audit_comparator(type, f->op, f->val); | ||
1241 | break; | ||
1381 | case AUDIT_SUBJ_USER: | 1242 | case AUDIT_SUBJ_USER: |
1382 | case AUDIT_SUBJ_ROLE: | 1243 | case AUDIT_SUBJ_ROLE: |
1383 | case AUDIT_SUBJ_TYPE: | 1244 | case AUDIT_SUBJ_TYPE: |
@@ -1404,7 +1265,7 @@ static int audit_filter_user_rules(struct audit_krule *rule, | |||
1404 | return 1; | 1265 | return 1; |
1405 | } | 1266 | } |
1406 | 1267 | ||
1407 | int audit_filter_user(void) | 1268 | int audit_filter_user(int type) |
1408 | { | 1269 | { |
1409 | enum audit_state state = AUDIT_DISABLED; | 1270 | enum audit_state state = AUDIT_DISABLED; |
1410 | struct audit_entry *e; | 1271 | struct audit_entry *e; |
@@ -1412,7 +1273,7 @@ int audit_filter_user(void) | |||
1412 | 1273 | ||
1413 | rcu_read_lock(); | 1274 | rcu_read_lock(); |
1414 | list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) { | 1275 | list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) { |
1415 | if (audit_filter_user_rules(&e->rule, &state)) { | 1276 | if (audit_filter_user_rules(&e->rule, type, &state)) { |
1416 | if (state == AUDIT_DISABLED) | 1277 | if (state == AUDIT_DISABLED) |
1417 | ret = 0; | 1278 | ret = 0; |
1418 | break; | 1279 | break; |