Re: [PATCH] Inter-field comparisons between uid/euid and gid/egid

Peter Moody
2011-12-14T00:18:23Z

On Mon, Dec 12, 2011 at 9:48 AM, Steve Grubb <sgrubb@redhat.com> wrote:

> Closer. All permutations of uid and gid being able to compare against either
> object or process credentials. Like auid!=ouid or auid!=uid.

Ok, I think I got them all.

This is the kernel change to allow comparison between the various uids
(uid, euid, suid, fsuid, loginuid, obj_uid) and the various gids (gid,
egid, sgid, fsgid). One other possible catch is that loginuid and auid
seem to already be used interchangeably. I've referred to as auid
where I could just because it's shorter. I hope that isn't too
confusing.

I've got a little more work to do on the user-land component, and I
haven't been able to get the LIST_RULES to list the first field of the
interfield comparisons. I'll keep poking at that, but I suspect it
requires deeper auditd knowledge than I can muster (at least for now).

This still requires the same patches from Eric that I mentioned in my
first email

Cheers,
peter

Signed-off-by: Peter Moody <pmoody@google.com>
---
include/linux/audit.h | 37 ++++++++++++++--
kernel/auditsc.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 140 insertions(+), 11 deletions(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index 4c5437f..72f00d2 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -180,10 +180,39 @@
#define AUDIT_UNUSED_BITS 0x07FFFC00

/* AUDIT_FIELD_COMPARE rule list */
-#define AUDIT_COMPARE_UID_TO_OBJ_UID 1
-#define AUDIT_COMPARE_GID_TO_OBJ_GID 2
-
-#define AUDIT_MAX_FIELD_COMPARE AUDIT_COMPARE_GID_TO_OBJ_GID
+#define AUDIT_COMPARE_UID_TO_OBJ_UID 1
+#define AUDIT_COMPARE_GID_TO_OBJ_GID 2
+#define AUDIT_COMPARE_EUID_TO_OBJ_UID 3
+#define AUDIT_COMPARE_EGID_TO_OBJ_GID 4
+#define AUDIT_COMPARE_AUID_TO_OBJ_UID 5
+#define AUDIT_COMPARE_SUID_TO_OBJ_UID 6
+#define AUDIT_COMPARE_SGID_TO_OBJ_GID 7
+#define AUDIT_COMPARE_FSUID_TO_OBJ_UID 8
+#define AUDIT_COMPARE_FSGID_TO_OBJ_GID 9
+
+#define AUDIT_COMPARE_UID_TO_AUID 10
+#define AUDIT_COMPARE_UID_TO_EUID 11
+#define AUDIT_COMPARE_UID_TO_FSUID 12
+#define AUDIT_COMPARE_UID_TO_SUID 13
+
+#define AUDIT_COMPARE_AUID_TO_FSUID 14
+#define AUDIT_COMPARE_AUID_TO_SUID 15
+#define AUDIT_COMPARE_AUID_TO_EUID 16
+
+#define AUDIT_COMPARE_EUID_TO_SUID 17
+#define AUDIT_COMPARE_EUID_TO_FSUID 18
+
+#define AUDIT_COMPARE_SUID_TO_FSUID 19
+
+#define AUDIT_COMPARE_GID_TO_EGID 20
+#define AUDIT_COMPARE_GID_TO_FSGID 21
+#define AUDIT_COMPARE_GID_TO_SGID 22
+
+#define AUDIT_COMPARE_EGID_TO_FSGID 23
+#define AUDIT_COMPARE_EGID_TO_SGID 24
+#define AUDIT_COMPARE_SGID_TO_FSGID 25
+
+#define AUDIT_MAX_FIELD_COMPARE AUDIT_COMPARE_SGID_TO_FSGID
/* Rule fields */
/* These are useful when checking the
* task structure at task creation time
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 2be8bf3..a1ead88 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -458,9 +458,9 @@ static int match_tree_refs(struct audit_context
*ctx, struct audit_tree *tree)
return 0;
}

-static int audit_compare_id(const struct cred *cred,
+static int audit_compare_id(const void *cred,
unsigned long cred_offset,
- struct audit_names *name,
+ void *name,
unsigned long name_offset,
struct audit_field *f,
struct audit_context *ctx)
@@ -506,14 +506,114 @@ static int audit_field_compare(struct task_struct *tsk,

switch (f->val) {
+ /* obj_uid/obj_gid comparisons */
case AUDIT_COMPARE_UID_TO_OBJ_UID:
- return audit_compare_id(cred, offsetof(struct cred, uid),
- name, offsetof(struct audit_names, uid),
+ return audit_compare_id((void*)cred, offsetof(struct cred, uid),
+ (void*)name, offsetof(struct audit_names, uid),
f, ctx);
case AUDIT_COMPARE_GID_TO_OBJ_GID:
- return audit_compare_id(cred, offsetof(struct cred, gid),
- name, offsetof(struct audit_names, gid),
- f, ctx);
+ return audit_compare_id((void*)cred, offsetof(struct cred, gid),
+ (void*)name, offsetof(struct audit_names, gid),
+ f, ctx);
+ case AUDIT_COMPARE_EUID_TO_OBJ_UID:
+ return audit_compare_id((void*)cred, offsetof(struct cred, euid),
+ (void*)name, offsetof(struct audit_names, uid),
+ f, ctx);
+ case AUDIT_COMPARE_EGID_TO_OBJ_GID:
+ return audit_compare_id((void*)cred, offsetof(struct cred, egid),
+ (void*)name, offsetof(struct audit_names, gid),
+ f, ctx);
+ case AUDIT_COMPARE_AUID_TO_OBJ_UID:
+ return audit_compare_id((void*)tsk, offsetof(struct task_struct, loginuid),
+ (void*)name, offsetof(struct audit_names, uid),
+ f, ctx);
+ case AUDIT_COMPARE_SUID_TO_OBJ_UID:
+ return audit_compare_id((void*)cred, offsetof(struct cred, suid),
+ (void*)name, offsetof(struct audit_names, uid),
+ f, ctx);
+ case AUDIT_COMPARE_SGID_TO_OBJ_GID:
+ return audit_compare_id((void*)cred, offsetof(struct cred, sgid),
+ (void*)name, offsetof(struct audit_names, gid),
+ f, ctx);
+ case AUDIT_COMPARE_FSUID_TO_OBJ_UID:
+ return audit_compare_id((void*)cred, offsetof(struct cred, fsuid),
+ (void*)name, offsetof(struct audit_names, uid),
+ f, ctx);
+ case AUDIT_COMPARE_FSGID_TO_OBJ_GID:
+ return audit_compare_id((void*)cred, offsetof(struct cred, fsgid),
+ (void*)name, offsetof(struct audit_names, gid),
+ f, ctx);
+ /* uid comparisons */
+ case AUDIT_COMPARE_UID_TO_AUID:
+ return audit_compare_id((void*)cred, offsetof(struct cred, uid),
+ (void*)tsk, offsetof(struct task_struct, loginuid),
+ f, ctx);
+ case AUDIT_COMPARE_UID_TO_EUID:
+ return audit_compare_id((void*)cred, offsetof(struct cred, uid),
+ (void*)cred, offsetof(struct cred, euid),
+ f, ctx);
+ case AUDIT_COMPARE_UID_TO_FSUID:
+ return audit_compare_id((void*)cred, offsetof(struct cred, uid),
+ (void*)cred, offsetof(struct cred, fsuid),
+ f, ctx);
+ case AUDIT_COMPARE_UID_TO_SUID:
+ return audit_compare_id((void*)cred, offsetof(struct cred, uid),
+ (void*)cred, offsetof(struct cred, suid),
+ f, ctx);
+ /* auid comparisons */
+ case AUDIT_COMPARE_AUID_TO_FSUID:
+ return audit_compare_id((void*)tsk, offsetof(struct task_struct, loginuid),
+ (void*)cred, offsetof(struct cred, fsuid),
+ f, ctx);
+ case AUDIT_COMPARE_AUID_TO_SUID:
+ return audit_compare_id((void*)tsk, offsetof(struct task_struct, loginuid),
+ (void*)cred, offsetof(struct cred, suid),
+ f, ctx);
+ case AUDIT_COMPARE_AUID_TO_EUID:
+ return audit_compare_id((void*)tsk, offsetof(struct task_struct, loginuid),
+ (void*)cred, offsetof(struct cred, euid),
+ f, ctx);
+ /* euid comparisons */
+ case AUDIT_COMPARE_EUID_TO_SUID:
+ return audit_compare_id((void*)cred, offsetof(struct cred, euid),
+ (void*)cred, offsetof(struct cred, suid),
+ f, ctx);
+ case AUDIT_COMPARE_EUID_TO_FSUID:
+ return audit_compare_id((void*)cred, offsetof(struct cred, euid),
+ (void*)cred, offsetof(struct cred, fsuid),
+ f, ctx);
+ /* suid comparisons */
+ case AUDIT_COMPARE_SUID_TO_FSUID:
+ return audit_compare_id((void*)cred, offsetof(struct cred, suid),
+ (void*)cred, offsetof(struct cred, fsuid),
+ f, ctx);
+ /* gd comparisons */
+ case AUDIT_COMPARE_GID_TO_EGID:
+ return audit_compare_id((void*)cred, offsetof(struct cred, gid),
+ (void*)cred, offsetof(struct cred, egid),
+ f, ctx);
+ case AUDIT_COMPARE_GID_TO_FSGID:
+ return audit_compare_id((void*)cred, offsetof(struct cred, gid),
+ (void*)cred, offsetof(struct cred, fsgid),
+ f, ctx);
+ case AUDIT_COMPARE_GID_TO_SGID:
+ return audit_compare_id((void*)cred, offsetof(struct cred, gid),
+ (void*)cred, offsetof(struct cred, sgid),
+ f, ctx);
+ /* egid comparisons */
+ case AUDIT_COMPARE_EGID_TO_FSGID:
+ return audit_compare_id((void*)cred, offsetof(struct cred, egid),
+ (void*)cred, offsetof(struct cred, fsgid),
+ f, ctx);
+ case AUDIT_COMPARE_EGID_TO_SGID:
+ return audit_compare_id((void*)cred, offsetof(struct cred, egid),
+ (void*)cred, offsetof(struct cred, sgid),
+ f, ctx);
+ /* sgid comparison */
+ case AUDIT_COMPARE_SGID_TO_FSGID:
+ return audit_compare_id((void*)cred, offsetof(struct cred, sgid),
+ (void*)cred, offsetof(struct cred, fsgid),
+ f, ctx);
default:
return 0;
}
--
1.7.3.1