On Friday, May 24, 2013 12:11:50 PM Eric Paris wrote:
This adds a new 'audit_feature' bit which allows userspace to
set it
such that the loginuid is absolutely immutable, even if you have
CAP_AUDIT_CONTROL.
I'm also not sure I like it done this way. What I was thinking about is that
we should set this at boot so that no matter what happens during boot, the
policy is for setting loginuid cannot be messed with. We really do not want
this to be changeable after the system comes up. I'd much rather see this as
audit=4 on the boot prompt (meaning enabled and immutable). This way its clear
to everyone that it can only be changed by rebooting the system and the policy
is in effect for the duration of the session.
-Steve
Signed-off-by: Eric Paris <eparis(a)redhat.com>
---
include/uapi/linux/audit.h | 3 ++-
kernel/audit.c | 3 ++-
kernel/auditsc.c | 3 +++
3 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 2963b5a..9539ea9 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -381,7 +381,8 @@ struct audit_features {
};
#define AUDIT_FEATURE_ONLY_UNSET_LOGINUID 0
-#define AUDIT_LAST_FEATURE AUDIT_FEATURE_ONLY_UNSET_LOGINUID
+#define AUDIT_FEATURE_LOGINUID_IMMUTABLE 1
+#define AUDIT_LAST_FEATURE AUDIT_FEATURE_LOGINUID_IMMUTABLE
#define audit_feature_valid(x) ((x) >= 0 && (x) <= AUDIT_LAST_FEATURE)
#define AUDIT_FEATURE_TO_MASK(x) (1 << ((x) & 31)) /* mask for __u32 */
diff --git a/kernel/audit.c b/kernel/audit.c
index a5c470b..900d61d 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -145,8 +145,9 @@ static struct audit_features af = {.vers =
AUDIT_FEATURE_VERSION, .features = 0,
.lock = 0,};
-static char *audit_feature_names[1] = {
+static char *audit_feature_names[2] = {
"only_unset_loginuid",
+ "loginuid_immutable",
};
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index e5dbbc6..aace3ac 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1969,6 +1969,9 @@ static int audit_set_loginuid_perm(kuid_t loginuid)
/* if we are unset, we don't need privs */
if (!audit_loginuid_set(current))
return 0;
+ /* if AUDIT_FEATURE_LOGINUID_IMMUTABLE means never ever allow a change*/
+ if (is_audit_feature_set(AUDIT_FEATURE_LOGINUID_IMMUTABLE))
+ return -EPERM;
/* it is set, you need permission */
if (!capable(CAP_AUDIT_CONTROL))
return -EPERM;