audit: Add typespecific uid and gid comparators
[linux-2.6-block.git] / kernel / auditsc.c
index 4b96415527b8664753e18cb169f0de9f391f9314..0b5b8a232b55c900bf620f7c3acf434198385404 100644 (file)
@@ -113,8 +113,8 @@ struct audit_names {
        unsigned long   ino;
        dev_t           dev;
        umode_t         mode;
-       uid_t           uid;
-       gid_t           gid;
+       kuid_t          uid;
+       kgid_t          gid;
        dev_t           rdev;
        u32             osid;
        struct audit_cap_data fcap;
@@ -464,37 +464,47 @@ static int match_tree_refs(struct audit_context *ctx, struct audit_tree *tree)
        return 0;
 }
 
-static int audit_compare_id(uid_t uid1,
-                           struct audit_names *name,
-                           unsigned long name_offset,
-                           struct audit_field *f,
-                           struct audit_context *ctx)
+static int audit_compare_uid(kuid_t uid,
+                            struct audit_names *name,
+                            struct audit_field *f,
+                            struct audit_context *ctx)
 {
        struct audit_names *n;
-       unsigned long addr;
-       uid_t uid2;
        int rc;
-
-       BUILD_BUG_ON(sizeof(uid_t) != sizeof(gid_t));
-
        if (name) {
-               addr = (unsigned long)name;
-               addr += name_offset;
-
-               uid2 = *(uid_t *)addr;
-               rc = audit_comparator(uid1, f->op, uid2);
+               rc = audit_uid_comparator(uid, f->op, name->uid);
                if (rc)
                        return rc;
        }
-
        if (ctx) {
                list_for_each_entry(n, &ctx->names_list, list) {
-                       addr = (unsigned long)n;
-                       addr += name_offset;
-
-                       uid2 = *(uid_t *)addr;
+                       rc = audit_uid_comparator(uid, f->op, n->uid);
+                       if (rc)
+                               return rc;
+               }
+       }
+       return 0;
+}
 
-                       rc = audit_comparator(uid1, f->op, uid2);
+static int audit_compare_gid(kgid_t gid,
+                            struct audit_names *name,
+                            struct audit_field *f,
+                            struct audit_context *ctx)
+{
+       struct audit_names *n;
+       int rc;
+       if (name) {
+               rc = audit_gid_comparator(gid, f->op, name->gid);
+               if (rc)
+                       return rc;
+       }
+       if (ctx) {
+               list_for_each_entry(n, &ctx->names_list, list) {
+                       rc = audit_gid_comparator(gid, f->op, n->gid);
                        if (rc)
                                return rc;
                }
@@ -511,80 +521,62 @@ static int audit_field_compare(struct task_struct *tsk,
        switch (f->val) {
        /* process to file object comparisons */
        case AUDIT_COMPARE_UID_TO_OBJ_UID:
-               return audit_compare_id(cred->uid,
-                                       name, offsetof(struct audit_names, uid),
-                                       f, ctx);
+               return audit_compare_uid(cred->uid, name, f, ctx);
        case AUDIT_COMPARE_GID_TO_OBJ_GID:
-               return audit_compare_id(cred->gid,
-                                       name, offsetof(struct audit_names, gid),
-                                       f, ctx);
+               return audit_compare_gid(cred->gid, name, f, ctx);
        case AUDIT_COMPARE_EUID_TO_OBJ_UID:
-               return audit_compare_id(cred->euid,
-                                       name, offsetof(struct audit_names, uid),
-                                       f, ctx);
+               return audit_compare_uid(cred->euid, name, f, ctx);
        case AUDIT_COMPARE_EGID_TO_OBJ_GID:
-               return audit_compare_id(cred->egid,
-                                       name, offsetof(struct audit_names, gid),
-                                       f, ctx);
+               return audit_compare_gid(cred->egid, name, f, ctx);
        case AUDIT_COMPARE_AUID_TO_OBJ_UID:
-               return audit_compare_id(tsk->loginuid,
-                                       name, offsetof(struct audit_names, uid),
-                                       f, ctx);
+               return audit_compare_uid(tsk->loginuid, name, f, ctx);
        case AUDIT_COMPARE_SUID_TO_OBJ_UID:
-               return audit_compare_id(cred->suid,
-                                       name, offsetof(struct audit_names, uid),
-                                       f, ctx);
+               return audit_compare_uid(cred->suid, name, f, ctx);
        case AUDIT_COMPARE_SGID_TO_OBJ_GID:
-               return audit_compare_id(cred->sgid,
-                                       name, offsetof(struct audit_names, gid),
-                                       f, ctx);
+               return audit_compare_gid(cred->sgid, name, f, ctx);
        case AUDIT_COMPARE_FSUID_TO_OBJ_UID:
-               return audit_compare_id(cred->fsuid,
-                                       name, offsetof(struct audit_names, uid),
-                                       f, ctx);
+               return audit_compare_uid(cred->fsuid, name, f, ctx);
        case AUDIT_COMPARE_FSGID_TO_OBJ_GID:
-               return audit_compare_id(cred->fsgid,
-                                       name, offsetof(struct audit_names, gid),
-                                       f, ctx);
+               return audit_compare_gid(cred->fsgid, name, f, ctx);
        /* uid comparisons */
        case AUDIT_COMPARE_UID_TO_AUID:
-               return audit_comparator(cred->uid, f->op, tsk->loginuid);
+               return audit_uid_comparator(cred->uid, f->op, tsk->loginuid);
        case AUDIT_COMPARE_UID_TO_EUID:
-               return audit_comparator(cred->uid, f->op, cred->euid);
+               return audit_uid_comparator(cred->uid, f->op, cred->euid);
        case AUDIT_COMPARE_UID_TO_SUID:
-               return audit_comparator(cred->uid, f->op, cred->suid);
+               return audit_uid_comparator(cred->uid, f->op, cred->suid);
        case AUDIT_COMPARE_UID_TO_FSUID:
-               return audit_comparator(cred->uid, f->op, cred->fsuid);
+               return audit_uid_comparator(cred->uid, f->op, cred->fsuid);
        /* auid comparisons */
        case AUDIT_COMPARE_AUID_TO_EUID:
-               return audit_comparator(tsk->loginuid, f->op, cred->euid);
+               return audit_uid_comparator(tsk->loginuid, f->op, cred->euid);
        case AUDIT_COMPARE_AUID_TO_SUID:
-               return audit_comparator(tsk->loginuid, f->op, cred->suid);
+               return audit_uid_comparator(tsk->loginuid, f->op, cred->suid);
        case AUDIT_COMPARE_AUID_TO_FSUID:
-               return audit_comparator(tsk->loginuid, f->op, cred->fsuid);
+               return audit_uid_comparator(tsk->loginuid, f->op, cred->fsuid);
        /* euid comparisons */
        case AUDIT_COMPARE_EUID_TO_SUID:
-               return audit_comparator(cred->euid, f->op, cred->suid);
+               return audit_uid_comparator(cred->euid, f->op, cred->suid);
        case AUDIT_COMPARE_EUID_TO_FSUID:
-               return audit_comparator(cred->euid, f->op, cred->fsuid);
+               return audit_uid_comparator(cred->euid, f->op, cred->fsuid);
        /* suid comparisons */
        case AUDIT_COMPARE_SUID_TO_FSUID:
-               return audit_comparator(cred->suid, f->op, cred->fsuid);
+               return audit_uid_comparator(cred->suid, f->op, cred->fsuid);
        /* gid comparisons */
        case AUDIT_COMPARE_GID_TO_EGID:
-               return audit_comparator(cred->gid, f->op, cred->egid);
+               return audit_gid_comparator(cred->gid, f->op, cred->egid);
        case AUDIT_COMPARE_GID_TO_SGID:
-               return audit_comparator(cred->gid, f->op, cred->sgid);
+               return audit_gid_comparator(cred->gid, f->op, cred->sgid);
        case AUDIT_COMPARE_GID_TO_FSGID:
-               return audit_comparator(cred->gid, f->op, cred->fsgid);
+               return audit_gid_comparator(cred->gid, f->op, cred->fsgid);
        /* egid comparisons */
        case AUDIT_COMPARE_EGID_TO_SGID:
-               return audit_comparator(cred->egid, f->op, cred->sgid);
+               return audit_gid_comparator(cred->egid, f->op, cred->sgid);
        case AUDIT_COMPARE_EGID_TO_FSGID:
-               return audit_comparator(cred->egid, f->op, cred->fsgid);
+               return audit_gid_comparator(cred->egid, f->op, cred->fsgid);
        /* sgid comparison */
        case AUDIT_COMPARE_SGID_TO_FSGID:
-               return audit_comparator(cred->sgid, f->op, cred->fsgid);
+               return audit_gid_comparator(cred->sgid, f->op, cred->fsgid);
        default:
                WARN(1, "Missing AUDIT_COMPARE define.  Report as a bug\n");
                return 0;
@@ -630,28 +622,28 @@ static int audit_filter_rules(struct task_struct *tsk,
                        }
                        break;
                case AUDIT_UID:
-                       result = audit_comparator(cred->uid, f->op, f->val);
+                       result = audit_uid_comparator(cred->uid, f->op, f->uid);
                        break;
                case AUDIT_EUID:
-                       result = audit_comparator(cred->euid, f->op, f->val);
+                       result = audit_uid_comparator(cred->euid, f->op, f->uid);
                        break;
                case AUDIT_SUID:
-                       result = audit_comparator(cred->suid, f->op, f->val);
+                       result = audit_uid_comparator(cred->suid, f->op, f->uid);
                        break;
                case AUDIT_FSUID:
-                       result = audit_comparator(cred->fsuid, f->op, f->val);
+                       result = audit_uid_comparator(cred->fsuid, f->op, f->uid);
                        break;
                case AUDIT_GID:
-                       result = audit_comparator(cred->gid, f->op, f->val);
+                       result = audit_gid_comparator(cred->gid, f->op, f->gid);
                        break;
                case AUDIT_EGID:
-                       result = audit_comparator(cred->egid, f->op, f->val);
+                       result = audit_gid_comparator(cred->egid, f->op, f->gid);
                        break;
                case AUDIT_SGID:
-                       result = audit_comparator(cred->sgid, f->op, f->val);
+                       result = audit_gid_comparator(cred->sgid, f->op, f->gid);
                        break;
                case AUDIT_FSGID:
-                       result = audit_comparator(cred->fsgid, f->op, f->val);
+                       result = audit_gid_comparator(cred->fsgid, f->op, f->gid);
                        break;
                case AUDIT_PERS:
                        result = audit_comparator(tsk->personality, f->op, f->val);
@@ -717,10 +709,10 @@ static int audit_filter_rules(struct task_struct *tsk,
                        break;
                case AUDIT_OBJ_UID:
                        if (name) {
-                               result = audit_comparator(name->uid, f->op, f->val);
+                               result = audit_uid_comparator(name->uid, f->op, f->uid);
                        } else if (ctx) {
                                list_for_each_entry(n, &ctx->names_list, list) {
-                                       if (audit_comparator(n->uid, f->op, f->val)) {
+                                       if (audit_uid_comparator(n->uid, f->op, f->uid)) {
                                                ++result;
                                                break;
                                        }
@@ -729,10 +721,10 @@ static int audit_filter_rules(struct task_struct *tsk,
                        break;
                case AUDIT_OBJ_GID:
                        if (name) {
-                               result = audit_comparator(name->gid, f->op, f->val);
+                               result = audit_gid_comparator(name->gid, f->op, f->gid);
                        } else if (ctx) {
                                list_for_each_entry(n, &ctx->names_list, list) {
-                                       if (audit_comparator(n->gid, f->op, f->val)) {
+                                       if (audit_gid_comparator(n->gid, f->op, f->gid)) {
                                                ++result;
                                                break;
                                        }
@@ -750,7 +742,7 @@ static int audit_filter_rules(struct task_struct *tsk,
                case AUDIT_LOGINUID:
                        result = 0;
                        if (ctx)
-                               result = audit_comparator(tsk->loginuid, f->op, f->val);
+                               result = audit_uid_comparator(tsk->loginuid, f->op, f->uid);
                        break;
                case AUDIT_SUBJ_USER:
                case AUDIT_SUBJ_ROLE: