Rather than code the same loop over and over implement a helper function which
uses some pointer magic to make it generic enough to be used numerous places
as we implement more audit interfield comparisons

Signed-off-by: Eric Paris <[email protected]>
---

 kernel/auditsc.c |   51 ++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 40 insertions(+), 11 deletions(-)

diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 104967d..848a84b 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -463,25 +463,54 @@ static int match_tree_refs(struct audit_context *ctx, 
struct audit_tree *tree)
        return 0;
 }
 
+static int audit_compare_id(const struct cred *cred,
+                           unsigned long cred_offset,
+                           struct audit_names *name,
+                           unsigned long name_offset,
+                           struct audit_field *f,
+                           struct audit_context *ctx)
+{
+       struct audit_names *n;
+       unsigned long addr;
+       uid_t cred_uid, name_uid;
+
+       addr = (unsigned long)cred;
+       addr += cred_offset;
+
+       cred_uid = *(uid_t *)addr;
+
+       if (name) {
+               addr = (unsigned long)name;
+               addr += name_offset;
+
+               name_uid = *(uid_t *)addr;
+               return audit_comparator(cred_uid, f->op, name_uid);
+       }
+
+       if (ctx) {
+               list_for_each_entry(n, &ctx->names_list, list) {
+                       addr = (unsigned long)n;
+                       addr += name_offset;
+
+                       name_uid = *(uid_t *)addr;
+                       if (audit_comparator(cred_uid, f->op, name_uid))
+                               return 1;
+               }
+       }
+       return 0;
+}
+
 static int audit_field_compare(struct task_struct *tsk,
                               const struct cred *cred,
                               struct audit_field *f,
                               struct audit_context *ctx,
                               struct audit_names *name)
 {
-       struct audit_names *n;
-
        switch (f->val) {
        case AUDIT_COMPARE_UID_TO_OBJ_UID:
-               if (name) {
-                       return audit_comparator(cred->uid, f->op, name->uid);
-               } else if (ctx) {
-                       list_for_each_entry(n, &ctx->names_list, list) {
-                               if (audit_comparator(cred->uid, f->op, n->uid))
-                                       return 1;
-                       }
-               }
-               break;
+               return audit_compare_id(cred, offsetof(struct cred, uid),
+                                       name, offsetof(struct audit_names, uid),
+                                       f, ctx);
        default:
                return 0;
        }

--
Linux-audit mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/linux-audit

Reply via email to