--- linux-2.4.21/drivers/audit/filter.c 2003-10-09 10:43:09.000000000 +0200 +++ smp/drivers/audit/filter.c 2003-10-20 10:57:16.000000000 +0200 @@ -645,6 +645,7 @@ struct visitor * prev; struct aud_filter * node; struct sysarg_data * target; + const char * tag; }; int @@ -654,6 +655,8 @@ struct visitor vstack[DEF_VISITOR_STACK], *vstack_top; unsigned int nvisitors = 0, ntargets = 0; struct visitor *v = NULL, *vnew; + struct aud_filter *next; + const char *tag = NULL; int r, res = 0, flags = 0; tstack_top = tstack + DEF_TARGET_STACK; @@ -665,13 +668,17 @@ if ((r = __audit_predicate_eval(filt->af_left, ev, tgt)) < 0) goto error; flags |= r; - if (r & AUDIT_LOG) + if (r & AUDIT_LOG) { + if (!tag) + tag = filt->af_evname; goto up; + } filt = filt->af_right; } - /* Apply predicate to target? */ - if (filt->af_op == AUD_FILT_OP_APPLY) { + switch (filt->af_op) { + case AUD_FILT_OP_APPLY: + /* Apply predicate to target */ if (ntargets >= DEF_TARGET_STACK) { printk(KERN_NOTICE "%s: Too many nested " "targets in filter expression\n", @@ -693,20 +700,25 @@ } if (tgt == &tstack[ntargets]) ntargets++; - filt = filt->af_predicate; + next = filt->af_predicate; #ifdef DEBUG_FILTER __audit_print_target(tgt); #endif - continue; - } + goto push_node; - /* Deal with AND OR NOT expressions. - * First, we need to push the current node onto the - * visitor stack, then we continue evaluating the left - * term. - */ - if (!__is_predicate(filt)) { - /* Need to push this node */ + case AUD_FILT_OP_AND: + case AUD_FILT_OP_OR: + case AUD_FILT_OP_NOT: + /* First, we need to push the current node onto the + * visitor stack, then we continue evaluating the left + * term. + */ + next = filt->af_left; + + push_node: + /* Copy the node's tag in case it matches */ + if (!tag) + tag = filt->af_evname; if (nvisitors < DEF_VISITOR_STACK) { vnew = &vstack[nvisitors++]; } else @@ -716,23 +728,33 @@ vnew->prev = v; vnew->node = filt; vnew->target = tgt; + vnew->tag = tag; v = vnew; - filt = filt->af_left; + filt = next; + tag = NULL; continue; - } - /* We have a predicate. Evaluate */ - if ((r = __audit_predicate_eval(filt, ev, tgt)) < 0) - goto error; - flags |= r; + default: + /* We have a predicate. Evaluate */ + if ((r = __audit_predicate_eval(filt, ev, tgt)) < 0) + goto error; + flags |= r; + if ((r & AUDIT_LOG) && !tag) + tag = filt->af_evname; + break; + } up: /* Combine with result of parent node */ filt = NULL; while (v != NULL && filt == NULL) { + if (!(r & AUDIT_LOG)) + tag = NULL; + switch (v->node->af_op) { case AUD_FILT_OP_NOT: + tag = NULL; r ^= AUDIT_LOG; break; case AUD_FILT_OP_OR: @@ -751,6 +773,11 @@ break; } + /* This node _may_ evaluate to true. Keep the tag. + * If it's false, we'll dump the tag later */ + if (tag == NULL) + tag = v->tag; + /* Pop the visitor node */ vnew = v->prev; if (vstack <= v && v < vstack_top) { @@ -770,6 +797,8 @@ res = r; } + if (tag) + strncpy(ev->name, tag, sizeof(ev->name)); return res; enomem: r = -ENOMEM;