audit: validate comparison operations, store them in sane form
Subsystems (4)
PATCH 15/15 audit: validate comparison operations, store them in sane form
Don't store the field->op in the messy (and very inconvenient for e.g. audit_comparator()) form; translate to dense set of values and do full validation of userland-submitted value while we are at it.
->audit_init_rule() and ->audit_match_rule() get new values now; in-tree instances updated.
Signed-off-by Al Viro <[email protected]>
--- include/linux/audit.h | 12 ++++ kernel/audit_tree.c | 2 +- kernel/auditfilter.c | 132 ++++++++++++++++++++-------------------- security/selinux/ss/services.c | 26 ++++---- security/smack/smack_lsm.c | 6 +- 5 files changed, 94 insertions(+), 84 deletions(-)
include/linux/audit.h +12 -0
@@ -245,6 +245,18 @@#define AUDIT_GREATER_THAN_OR_EQUAL (AUDIT_GREATER_THAN|AUDIT_EQUAL)#define AUDIT_OPERATORS (AUDIT_EQUAL|AUDIT_NOT_EQUAL|AUDIT_BIT_MASK) +enum { + Audit_equal, + Audit_not_equal, + Audit_bitmask, + Audit_bittest, + Audit_lt, + Audit_gt, + Audit_le, + Audit_ge, + Audit_bad +}; +/* Status symbols */ /* Mask values */ #define AUDIT_STATUS_ENABLED 0x0001
kernel/audit_tree.c +1 -1
@@ -618,7 +618,7 @@ int audit_make_tree(struct audit_krule *rule, char *pathname, u32 op)if (pathname[0 ] !='/' || rule->listnr !=AUDIT_FILTER_EXIT || - op & ~AUDIT_EQUAL || + op != Audit_equal || rule->inode_f || rule->watch || rule->tree)return -EINVAL ; rule->tree =alloc_tree (pathname);
kernel/auditfilter.c +65 -67
239 lines not on this page · raw message
security/selinux/ss/services.c +13 -13
@@ -2602,7 +2602,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)case AUDIT_OBJ_ROLE :case AUDIT_OBJ_TYPE :/* only 'equals' and 'not equals' fit user, role, and type */ -if (op !=AUDIT_EQUAL && op !=AUDIT_NOT_EQUAL ) +if (op != Audit_equal && op != Audit_not_equal)return -EINVAL ;break ;case AUDIT_SUBJ_SEN :
@@ -2736,10 +2736,10 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,case AUDIT_SUBJ_USER :case AUDIT_OBJ_USER :switch (op) { -case AUDIT_EQUAL : +case Audit_equal: match = (ctxt->user == rule->au_ctxt.user);break ; -case AUDIT_NOT_EQUAL : +case Audit_not_equal: match = (ctxt->user != rule->au_ctxt.user);break ; }
@@ -2747,10 +2747,10 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,case AUDIT_SUBJ_ROLE :case AUDIT_OBJ_ROLE :switch (op) { -case AUDIT_EQUAL : +case Audit_equal: match = (ctxt->role == rule->au_ctxt.role);break ; -case AUDIT_NOT_EQUAL : +case Audit_not_equal: match = (ctxt->role != rule->au_ctxt.role);break ; }
@@ -2758,10 +2758,10 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,case AUDIT_SUBJ_TYPE :case AUDIT_OBJ_TYPE :switch (op) { -case AUDIT_EQUAL : +case Audit_equal: match = (ctxt->type == rule->au_ctxt.type);break ; -case AUDIT_NOT_EQUAL : +case Audit_not_equal: match = (ctxt->type != rule->au_ctxt.type);break ; }
@@ -2774,31 +2774,31 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, field == AUDIT_OBJ_LEV_LOW) ? &ctxt->range.level[0] : &ctxt->range.level[1]);switch (op) { -case AUDIT_EQUAL : +case Audit_equal: match =mls_level_eq (&rule->au_ctxt.range.level[0 ], level);break ; -case AUDIT_NOT_EQUAL : +case Audit_not_equal: match = !mls_level_eq (&rule->au_ctxt.range.level[0 ], level);break ; -case AUDIT_LESS_THAN : +case Audit_lt: match = (mls_level_dom (&rule->au_ctxt.range.level[0 ], level) && !mls_level_eq (&rule->au_ctxt.range.level[0 ], level));break ; -case AUDIT_LESS_THAN_OR_EQUAL : +case Audit_le: match =mls_level_dom (&rule->au_ctxt.range.level[0 ], level);break ; -case AUDIT_GREATER_THAN : +case Audit_gt: match = (mls_level_dom (level, &rule->au_ctxt.range.level[0 ]) && !mls_level_eq (level, &rule->au_ctxt.range.level[0 ]));break ; -case AUDIT_GREATER_THAN_OR_EQUAL : +case Audit_ge: match =mls_level_dom (level, &rule->au_ctxt.range.level[0 ]);break ;
security/smack/smack_lsm.c +3 -3
@@ -2443,7 +2443,7 @@ static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)if (field !=AUDIT_SUBJ_USER && field !=AUDIT_OBJ_USER )return -EINVAL ; -if (op !=AUDIT_EQUAL && op !=AUDIT_NOT_EQUAL ) +if (op != Audit_equal && op != Audit_not_equal)return -EINVAL ; *rule =smk_import (rulestr,0 );
@@ -2507,9 +2507,9 @@ static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,* both pointers will point to the same smack_known * label. */ -if (op ==AUDIT_EQUAL ) +if (op == Audit_equal)return (rule == smack); -if (op ==AUDIT_NOT_EQUAL ) +if (op == Audit_not_equal)return (rule != smack);return 0 ;
Signature · 1 line
1.5.6.5
Quoted 9 lines · Al Viro
Don't store the
field->opin the messy (and very inconvenient for e.g.audit_comparator()) form; translate to dense set of values and do full validation of userland-submitted value while we are at it.->audit_init_rule() and ->audit_match_rule() get new values now; in-tree instances updated.
Signed-off-by Al Viro <[email protected]>
Reviewed-by James Morris <[email protected]>
Signature · 2 lines
James Morris <[email protected]>