]> Pileus Git - ~andy/linux/blobdiff - kernel/auditsc.c
audit: audit feature to only allow unsetting the loginuid
[~andy/linux] / kernel / auditsc.c
index 72684679e8bdd133f8f7e1091ee4af934445439e..924c0bf048d284876912d762cd5945b44a1c1130 100644 (file)
@@ -1968,15 +1968,16 @@ static atomic_t session_id = ATOMIC_INIT(0);
 
 static int audit_set_loginuid_perm(kuid_t loginuid)
 {
-#ifdef CONFIG_AUDIT_LOGINUID_IMMUTABLE
        /* if we are unset, we don't need privs */
        if (!audit_loginuid_set(current))
                return 0;
-#else  /* CONFIG_AUDIT_LOGINUID_IMMUTABLE */
-       if (capable(CAP_AUDIT_CONTROL))
-               return 0;
-#endif /* CONFIG_AUDIT_LOGINUID_IMMUTABLE */
-       return -EPERM;
+       /* 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;
 }
 
 static void audit_log_set_loginuid(kuid_t koldloginuid, kuid_t kloginuid,
@@ -2021,7 +2022,9 @@ int audit_set_loginuid(kuid_t loginuid)
        if (rc)
                goto out;
 
-       sessionid = atomic_inc_return(&session_id);
+       /* are we setting or clearing? */
+       if (uid_valid(loginuid))
+               sessionid = atomic_inc_return(&session_id);
 
        task->sessionid = sessionid;
        task->loginuid = loginuid;