audit: audit feature to only allow unsetting the loginuid
authorEric Paris <eparis@redhat.com>
Fri, 24 May 2013 13:18:04 +0000 (09:18 -0400)
committerEric Paris <eparis@redhat.com>
Tue, 5 Nov 2013 16:08:13 +0000 (11:08 -0500)
This is a new audit feature which only grants processes with
CAP_AUDIT_CONTROL the ability to unset their loginuid.  They cannot
directly set it from a valid uid to another valid uid.  The ability to
unset the loginuid is nice because a priviledged task, like that of
container creation, can unset the loginuid and then priv is not needed
inside the container when a login daemon needs to set the loginuid.

Signed-off-by: Eric Paris <eparis@redhat.com>
Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
Signed-off-by: Eric Paris <eparis@redhat.com>
include/uapi/linux/audit.h
kernel/audit.c
kernel/auditsc.c

index 9eddf2ca614f4c79c986cad8e98dccc6f0763f10..05e5e8fc2ac41d89e55712d5486ecb19f0f80025 100644 (file)
@@ -386,7 +386,8 @@ struct audit_features {
        __u32   lock;           /* which features to lock */
 };
 
-#define AUDIT_LAST_FEATURE     -1
+#define AUDIT_FEATURE_ONLY_UNSET_LOGINUID      0
+#define AUDIT_LAST_FEATURE                     AUDIT_FEATURE_ONLY_UNSET_LOGINUID
 
 #define audit_feature_valid(x)         ((x) >= 0 && (x) <= AUDIT_LAST_FEATURE)
 #define AUDIT_FEATURE_TO_MASK(x)       (1 << ((x) & 31)) /* mask for __u32 */
index 29ee6a421c6c8ce3d1eaf94cddba2dffdaef1c1b..fbfa3a74decb43820ee67b2e127c0256d8b5c62a 100644 (file)
@@ -144,7 +144,8 @@ static struct audit_features af = {.vers = AUDIT_FEATURE_VERSION,
                                   .features = 0,
                                   .lock = 0,};
 
-static char *audit_feature_names[0] = {
+static char *audit_feature_names[1] = {
+       "only_unset_loginuid",
 };
 
 
index c75d7813aef28cd181685080769036d5d53ad0b5..924c0bf048d284876912d762cd5945b44a1c1130 100644 (file)
@@ -1974,6 +1974,9 @@ static int audit_set_loginuid_perm(kuid_t loginuid)
        /* it is set, you need permission */
        if (!capable(CAP_AUDIT_CONTROL))
                return -EPERM;
+       /* reject if this is not an unset and we don't allow that */
+       if (is_audit_feature_set(AUDIT_FEATURE_ONLY_UNSET_LOGINUID) && uid_valid(loginuid))
+               return -EPERM;
        return 0;
 }