Add the ability to get and set the login uid and to get the session id
using an audit netlink message using message types AUDIT_GET_LOGINUID
1024, AUDIT_SET_LOGINUID 1025 and AUDIT_GET_SESSIONID 1026 in addition
to using the proc filesystem.
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
include/uapi/linux/audit.h | 3 +++
kernel/audit.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 65 insertions(+)
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index e26729fc9943..eef42c8eea77 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -75,6 +75,9 @@
#define AUDIT_SIGNAL_INFO2 1021 /* Get info auditd signal sender */
#define AUDIT_GET_CONTID 1022 /* Get contid of a task */
#define AUDIT_SET_CONTID 1023 /* Set contid of a task */
+#define AUDIT_GET_LOGINUID 1024 /* Get loginuid of a task */
+#define AUDIT_SET_LOGINUID 1025 /* Set loginuid of a task */
+#define AUDIT_GET_SESSIONID 1026 /* Set sessionid of a task */
#define AUDIT_FIRST_USER_MSG 1100 /* Userspace messages mostly uninteresting to kernel
*/
#define AUDIT_USER_AVC 1107 /* We filter this differently */
diff --git a/kernel/audit.c b/kernel/audit.c
index df92de20ed73..9e82de13d2eb 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1184,6 +1184,15 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
{
int err = 0;
+ /* These messages can work outside the initial namespaces */
+ switch (msg_type) {
+ case AUDIT_GET_LOGINUID:
+ case AUDIT_GET_SESSIONID:
+ return 0;
+ break;
+ default: /* do more checks below */
+ break;
+ }
/* Only support initial user namespace for now. */
/*
* We return ECONNREFUSED because it tricks userspace into thinking
@@ -1218,6 +1227,7 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
case AUDIT_MAKE_EQUIV:
case AUDIT_GET_CONTID:
case AUDIT_SET_CONTID:
+ case AUDIT_SET_LOGINUID:
/* Only support auditd and auditctl in initial pid namespace
* for now. */
if (task_active_pid_ns(current) != &init_pid_ns)
@@ -1292,6 +1302,33 @@ static int audit_get_contid_status(struct sk_buff *skb)
return 0;
}
+struct audit_loginuid_status { uid_t loginuid; };
+
+static int audit_get_loginuid_status(struct sk_buff *skb)
+{
+ u32 seq;
+ uid_t loginuid;
+ struct audit_loginuid_status ls;
+
+ loginuid = from_kuid(current_user_ns(), audit_get_loginuid(current));
+ ls.loginuid = loginuid;
+
+ seq = nlmsg_hdr(skb)->nlmsg_seq;
+ audit_send_reply(skb, seq, AUDIT_GET_LOGINUID, 0, 0, &ls, sizeof(ls));
+ return loginuid;
+}
+
+static int audit_get_sessionid_status(struct sk_buff *skb)
+{
+ u32 seq;
+ struct audit_sessionid_status { u32 sessionid; };
+ struct audit_sessionid_status ss = { audit_get_sessionid(current) };
+
+ seq = nlmsg_hdr(skb)->nlmsg_seq;
+ audit_send_reply(skb, seq, AUDIT_GET_SESSIONID, 0, 0, &ss, sizeof(ss));
+ return audit_get_sessionid(current);
+}
+
static void audit_log_feature_change(int which, u32 old_feature, u32 new_feature,
u32 old_lock, u32 new_lock, int res)
{
@@ -1740,6 +1777,31 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr
*nlh)
if (err)
return err;
break;
+ case AUDIT_SET_LOGINUID: {
+ uid_t *loginuid = data;
+ kuid_t kloginuid;
+
+ /* check if new data is valid */
+ if (nlmsg_len(nlh) < sizeof(u32))
+ return -EINVAL;
+
+ kloginuid = make_kuid(current_user_ns(), *loginuid);
+ if (!uid_valid(kloginuid))
+ return -EINVAL;
+
+ return audit_set_loginuid(kloginuid);
+ break;
+ }
+ case AUDIT_GET_LOGINUID:
+ err = audit_get_loginuid_status(skb);
+ if (err)
+ return err;
+ break;
+ case AUDIT_GET_SESSIONID:
+ err = audit_get_sessionid_status(skb);
+ if (err)
+ return err;
+ break;
default:
err = -EINVAL;
break;
--
1.8.3.1