From 780a7654cee8d61819512385e778e4827db4bfbc Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 9 Apr 2013 02:22:10 -0700 Subject: audit: Make testing for a valid loginuid explicit. audit rule additions containing "-F auid!=4294967295" were failing with EINVAL because of a regression caused by e1760bd. Apparently some userland audit rule sets want to know if loginuid uid has been set and are using a test for auid != 4294967295 to determine that. In practice that is a horrible way to ask if a value has been set, because it relies on subtle implementation details and will break every time the uid implementation in the kernel changes. So add a clean way to test if the audit loginuid has been set, and silently convert the old idiom to the cleaner and more comprehensible new idiom. Cc: # 3.7 Reported-By: Richard Guy Briggs Signed-off-by: "Eric W. Biederman" Tested-by: Richard Guy Briggs Signed-off-by: Eric Paris --- kernel/auditfilter.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'kernel/auditfilter.c') diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 478f4602c96b..bc6595fe952e 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -365,7 +365,10 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f) case AUDIT_DIR: case AUDIT_FILTERKEY: break; - /* arch is only allowed to be = or != */ + case AUDIT_LOGINUID_SET: + if ((f->val != 0) && (f->val != 1)) + return -EINVAL; + /* FALL THROUGH */ case AUDIT_ARCH: if (f->op != Audit_not_equal && f->op != Audit_equal) return -EINVAL; @@ -419,17 +422,23 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, f->lsm_str = NULL; f->lsm_rule = NULL; + /* Support legacy tests for a valid loginuid */ + if ((f->type == AUDIT_LOGINUID) && (f->val == 4294967295)) { + f->type = AUDIT_LOGINUID_SET; + f->val = 0; + } + err = audit_field_valid(entry, f); if (err) goto exit_free; err = -EINVAL; switch (f->type) { + case AUDIT_LOGINUID: case AUDIT_UID: case AUDIT_EUID: case AUDIT_SUID: case AUDIT_FSUID: - case AUDIT_LOGINUID: case AUDIT_OBJ_UID: f->uid = make_kuid(current_user_ns(), f->val); if (!uid_valid(f->uid)) @@ -1222,6 +1231,10 @@ static int audit_filter_user_rules(struct audit_krule *rule, int type, result = audit_uid_comparator(audit_get_loginuid(current), f->op, f->uid); break; + case AUDIT_LOGINUID_SET: + result = audit_comparator(audit_loginuid_set(current), + f->op, f->val); + break; case AUDIT_MSGTYPE: result = audit_comparator(type, f->op, f->val); break; -- cgit v1.2.3-59-g8ed1b