diff options
author | Dustin Kirkland <dustin.kirkland@us.ibm.com> | 2006-02-16 14:40:01 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2006-03-20 14:08:55 -0500 |
commit | d9d9ec6e2c45b22282cd36cf92fcb23d504350a8 (patch) | |
tree | 88e861cee6de93d931325b9bdb2cd867afc6decd /kernel | |
parent | 5bdb98868062c1b14025883049551af343233187 (diff) |
[PATCH] Fix audit operators
Darrel Goeddel initiated a discussion on IRC regarding the possibility
of audit_comparator() returning -EINVAL signaling an invalid operator.
It is possible when creating the rule to assure that the operator is one
of the 6 sane values. Here's a snip from include/linux/audit.h Note
that 0 (nonsense) and 7 (all operators) are not valid values for an
operator.
...
/* These are the supported operators.
* 4 2 1
* = > <
* -------
* 0 0 0 0 nonsense
* 0 0 1 1 <
* 0 1 0 2 >
* 0 1 1 3 !=
* 1 0 0 4 =
* 1 0 1 5 <=
* 1 1 0 6 >=
* 1 1 1 7 all operators
*/
...
Furthermore, prior to adding these extended operators, flagging the
AUDIT_NEGATE bit implied !=, and otherwise == was assumed.
The following code forces the operator to be != if the AUDIT_NEGATE bit
was flipped on. And if no operator was specified, == is assumed. The
only invalid condition is if the AUDIT_NEGATE bit is off and all of the
AUDIT_EQUAL, AUDIT_LESS_THAN, and AUDIT_GREATER_THAN bits are
on--clearly a nonsensical operator.
Now that this is handled at rule insertion time, the default -EINVAL
return of audit_comparator() is eliminated such that the function can
only return 1 or 0.
If this is acceptable, let's get this applied to the current tree.
:-Dustin
--
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
(cherry picked from 9bf0a8e137040f87d1b563336d4194e38fb2ba1a commit)
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/auditfilter.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 35f8fa82bb8b..b85fd8cce11f 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c | |||
@@ -160,11 +160,17 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule) | |||
160 | f->val = rule->values[i]; | 160 | f->val = rule->values[i]; |
161 | 161 | ||
162 | entry->rule.vers_ops = (f->op & AUDIT_OPERATORS) ? 2 : 1; | 162 | entry->rule.vers_ops = (f->op & AUDIT_OPERATORS) ? 2 : 1; |
163 | |||
164 | /* Support for legacy operators where | ||
165 | * AUDIT_NEGATE bit signifies != and otherwise assumes == */ | ||
163 | if (f->op & AUDIT_NEGATE) | 166 | if (f->op & AUDIT_NEGATE) |
164 | f->op |= AUDIT_NOT_EQUAL; | 167 | f->op = AUDIT_NOT_EQUAL; |
165 | else if (!(f->op & AUDIT_OPERATORS)) | 168 | else if (!f->op) |
166 | f->op |= AUDIT_EQUAL; | 169 | f->op = AUDIT_EQUAL; |
167 | f->op &= ~AUDIT_NEGATE; | 170 | else if (f->op == AUDIT_OPERATORS) { |
171 | err = -EINVAL; | ||
172 | goto exit_free; | ||
173 | } | ||
168 | } | 174 | } |
169 | 175 | ||
170 | exit_nofree: | 176 | exit_nofree: |
@@ -533,9 +539,9 @@ int audit_comparator(const u32 left, const u32 op, const u32 right) | |||
533 | return (left > right); | 539 | return (left > right); |
534 | case AUDIT_GREATER_THAN_OR_EQUAL: | 540 | case AUDIT_GREATER_THAN_OR_EQUAL: |
535 | return (left >= right); | 541 | return (left >= right); |
536 | default: | ||
537 | return -EINVAL; | ||
538 | } | 542 | } |
543 | BUG(); | ||
544 | return 0; | ||
539 | } | 545 | } |
540 | 546 | ||
541 | 547 | ||