Add new SCM type called SCM_AUDIT to send loginuid and sessionuid in SCM. This is useful for journald (systemd logging daemon) to get additional context with each log line received using UNIX socket. Signed-off-by: Jan Kaluza <jkaluza@xxxxxxxxxx> --- include/linux/socket.h | 6 ++++++ include/net/af_unix.h | 2 ++ include/net/scm.h | 28 ++++++++++++++++++++++++++-- net/unix/af_unix.c | 7 +++++++ 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/include/linux/socket.h b/include/linux/socket.h index 445ef75..505047a 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -130,6 +130,7 @@ static inline struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr #define SCM_RIGHTS 0x01 /* rw: access rights (array of int) */ #define SCM_CREDENTIALS 0x02 /* rw: struct ucred */ #define SCM_SECURITY 0x03 /* rw: security label */ +#define SCM_AUDIT 0x04 /* rw: struct uaudit */ struct ucred { __u32 pid; @@ -137,6 +138,11 @@ struct ucred { __u32 gid; }; +struct uaudit { + __u32 loginuid; + __u32 sessionid; +}; + /* Supported address families. */ #define AF_UNSPEC 0 #define AF_UNIX 1 /* Unix domain sockets */ diff --git a/include/net/af_unix.h b/include/net/af_unix.h index a175ba4..3b9d22a 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -36,6 +36,8 @@ struct unix_skb_parms { u32 secid; /* Security ID */ #endif u32 consumed; + kuid_t loginuid; + unsigned int sessionid; }; #define UNIXCB(skb) (*(struct unix_skb_parms *)&((skb)->cb)) diff --git a/include/net/scm.h b/include/net/scm.h index 8de2d37..e349a25 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -6,6 +6,7 @@ #include <linux/security.h> #include <linux/pid.h> #include <linux/nsproxy.h> +#include <linux/audit.h> /* Well, we should have at least one descriptor open * to accept passed FDs 8) @@ -18,6 +19,11 @@ struct scm_creds { kgid_t gid; }; +struct scm_audit { + kuid_t loginuid; + unsigned int sessionid; +}; + struct scm_fp_list { short count; short max; @@ -28,6 +34,7 @@ struct scm_cookie { struct pid *pid; /* Skb credentials */ struct scm_fp_list *fp; /* Passed files */ struct scm_creds creds; /* Skb credentials */ + struct scm_audit audit; /* Skb audit */ #ifdef CONFIG_SECURITY_NETWORK u32 secid; /* Passed security ID */ #endif @@ -58,6 +65,13 @@ static __inline__ void scm_set_cred(struct scm_cookie *scm, scm->creds.gid = gid; } +static inline void scm_set_audit(struct scm_cookie *scm, + kuid_t loginuid, unsigned int sessionid) +{ + scm->audit.loginuid = loginuid; + scm->audit.sessionid = sessionid; +} + static __inline__ void scm_destroy_cred(struct scm_cookie *scm) { put_pid(scm->pid); @@ -77,8 +91,12 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg, memset(scm, 0, sizeof(*scm)); scm->creds.uid = INVALID_UID; scm->creds.gid = INVALID_GID; - if (forcecreds) - scm_set_cred(scm, task_tgid(current), current_uid(), current_gid()); + if (forcecreds) { + scm_set_cred(scm, task_tgid(current), current_uid(), + current_gid()); + scm_set_audit(scm, audit_get_loginuid(current), + audit_get_sessionid(current)); + } unix_get_peersec_dgram(sock, scm); if (msg->msg_controllen <= 0) return 0; @@ -123,7 +141,13 @@ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg, .uid = from_kuid_munged(current_ns, scm->creds.uid), .gid = from_kgid_munged(current_ns, scm->creds.gid), }; + struct uaudit uaudits = { + .loginuid = from_kuid_munged(current_ns, + scm->audit.loginuid), + .sessionid = scm->audit.sessionid, + }; put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(ucreds), &ucreds); + put_cmsg(msg, SOL_SOCKET, SCM_AUDIT, sizeof(uaudits), &uaudits); } scm_destroy_cred(scm); diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 86de99a..c410f76 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1393,6 +1393,8 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen UNIXCB(skb).pid = get_pid(scm->pid); UNIXCB(skb).uid = scm->creds.uid; UNIXCB(skb).gid = scm->creds.gid; + UNIXCB(skb).loginuid = scm->audit.loginuid; + UNIXCB(skb).sessionid = scm->audit.sessionid; UNIXCB(skb).fp = NULL; if (scm->fp && send_fds) err = unix_attach_fds(scm, skb); @@ -1416,6 +1418,8 @@ static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock, test_bit(SOCK_PASSCRED, &other->sk_socket->flags)) { UNIXCB(skb).pid = get_pid(task_tgid(current)); current_uid_gid(&UNIXCB(skb).uid, &UNIXCB(skb).gid); + UNIXCB(skb).loginuid = audit_get_loginuid(current); + UNIXCB(skb).sessionid = audit_get_sessionid(current); } } @@ -1812,6 +1816,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, memset(&tmp_scm, 0, sizeof(tmp_scm)); } scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid); + scm_set_audit(siocb->scm, UNIXCB(skb).loginuid, UNIXCB(skb).sessionid); unix_set_secdata(siocb->scm, skb); if (!(flags & MSG_PEEK)) { @@ -1993,6 +1998,8 @@ again: } else if (test_bit(SOCK_PASSCRED, &sock->flags)) { /* Copy credentials */ scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid); + scm_set_audit(siocb->scm, UNIXCB(skb).loginuid, + UNIXCB(skb).sessionid); check_creds = 1; } -- 1.8.3.1 _______________________________________________ Containers mailing list Containers@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linuxfoundation.org/mailman/listinfo/containers