All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] Send audit/procinfo/cgroup data in socket-level control message
@ 2013-08-27 14:39 Jan Kaluza
  2013-08-27 14:39 ` [PATCH 1/3] Send loginuid and sessionid in SCM_AUDIT Jan Kaluza
                   ` (3 more replies)
  0 siblings, 4 replies; 79+ messages in thread
From: Jan Kaluza @ 2013-08-27 14:39 UTC (permalink / raw)
  To: davem; +Cc: LKML, netdev, eparis, rgb, Jan Kaluza

Hi,

this patchset against net-next (applies also to linux-next) adds 3 new types
of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).
This is needed by journald (logging daemon used as part of systemd ecosystem)
to get additional context together with log messages received using UNIX socket.

Jan Kaluza (3):
  Send loginuid and sessionid in SCM_AUDIT
  Send comm and cmdline in SCM_PROCINFO
  Send cgroup_path in SCM_CGROUP

 include/linux/socket.h |  9 ++++++
 include/net/af_unix.h  | 10 ++++++
 include/net/scm.h      | 67 ++++++++++++++++++++++++++++++++++++++--
 net/core/scm.c         | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++
 net/unix/af_unix.c     | 70 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 237 insertions(+), 2 deletions(-)

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 79+ messages in thread

* [PATCH 1/3] Send loginuid and sessionid in SCM_AUDIT
  2013-08-27 14:39 [PATCH 0/3] Send audit/procinfo/cgroup data in socket-level control message Jan Kaluza
@ 2013-08-27 14:39 ` Jan Kaluza
  2013-08-27 14:39 ` [PATCH 2/3] Send comm and cmdline in SCM_PROCINFO Jan Kaluza
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluza @ 2013-08-27 14:39 UTC (permalink / raw)
  To: davem; +Cc: LKML, netdev, eparis, rgb, Jan Kaluza

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
---
 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


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 2/3] Send comm and cmdline in SCM_PROCINFO
  2013-08-27 14:39 [PATCH 0/3] Send audit/procinfo/cgroup data in socket-level control message Jan Kaluza
  2013-08-27 14:39 ` [PATCH 1/3] Send loginuid and sessionid in SCM_AUDIT Jan Kaluza
@ 2013-08-27 14:39 ` Jan Kaluza
  2013-09-09  6:52   ` Eric W. Biederman
  2013-08-27 14:40 ` [PATCH 3/3] Send cgroup_path in SCM_CGROUP Jan Kaluza
       [not found] ` <1377614400-27122-1-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
  3 siblings, 1 reply; 79+ messages in thread
From: Jan Kaluza @ 2013-08-27 14:39 UTC (permalink / raw)
  To: davem; +Cc: LKML, netdev, eparis, rgb, Jan Kaluza

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
---
 include/linux/socket.h |  2 ++
 include/net/af_unix.h  | 11 +++++++--
 include/net/scm.h      | 24 +++++++++++++++++++
 net/core/scm.c         | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++
 net/unix/af_unix.c     | 57 +++++++++++++++++++++++++++++++++++++------
 5 files changed, 150 insertions(+), 9 deletions(-)

diff --git a/include/linux/socket.h b/include/linux/socket.h
index 505047a..6c7ace0 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -131,6 +131,8 @@ static inline struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr
 #define SCM_CREDENTIALS 0x02		/* rw: struct ucred		*/
 #define SCM_SECURITY	0x03		/* rw: security label		*/
 #define SCM_AUDIT	0x04		/* rw: struct uaudit		*/
+#define SCM_PROCINFO	0x05	/* rw: comm + cmdline (NULL terminated
+					   array of char *) */
 
 struct ucred {
 	__u32	pid;
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index 3b9d22a..05c7678 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -27,6 +27,13 @@ struct unix_address {
 	struct sockaddr_un name[0];
 };
 
+struct unix_skb_parms_scm {
+	kuid_t loginuid;
+	unsigned int sessionid;
+	char *procinfo;
+	int procinfo_len;
+};
+
 struct unix_skb_parms {
 	struct pid		*pid;		/* Skb credentials	*/
 	kuid_t			uid;
@@ -36,12 +43,12 @@ struct unix_skb_parms {
 	u32			secid;		/* Security ID		*/
 #endif
 	u32			consumed;
-	kuid_t			loginuid;
-	unsigned int		sessionid;
+	struct unix_skb_parms_scm *scm;
 };
 
 #define UNIXCB(skb) 	(*(struct unix_skb_parms *)&((skb)->cb))
 #define UNIXSID(skb)	(&UNIXCB((skb)).secid)
+#define UNIXSCM(skb)	(*(UNIXCB((skb)).scm))
 
 #define unix_state_lock(s)	spin_lock(&unix_sk(s)->lock)
 #define unix_state_unlock(s)	spin_unlock(&unix_sk(s)->lock)
diff --git a/include/net/scm.h b/include/net/scm.h
index e349a25..3346030 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -30,11 +30,17 @@ struct scm_fp_list {
 	struct file		*fp[SCM_MAX_FD];
 };
 
+struct scm_procinfo {
+	char *procinfo;
+	int len;
+};
+
 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	*/
+	struct scm_procinfo	procinfo;	/* Skb procinfo */
 #ifdef CONFIG_SECURITY_NETWORK
 	u32			secid;		/* Passed security ID 	*/
 #endif
@@ -45,6 +51,7 @@ extern void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm);
 extern int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm);
 extern void __scm_destroy(struct scm_cookie *scm);
 extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl);
+extern int scm_get_current_procinfo(char **procinfo);
 
 #ifdef CONFIG_SECURITY_NETWORK
 static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
@@ -72,10 +79,20 @@ static inline void scm_set_audit(struct scm_cookie *scm,
 	scm->audit.sessionid = sessionid;
 }
 
+static inline void scm_set_procinfo(struct scm_cookie *scm,
+				    char *procinfo, int len)
+{
+	scm->procinfo.procinfo = procinfo;
+	scm->procinfo.len = len;
+}
+
 static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
 {
 	put_pid(scm->pid);
 	scm->pid  = NULL;
+	kfree(scm->procinfo.procinfo);
+	scm->procinfo.procinfo = NULL;
+	scm->procinfo.len = 0;
 }
 
 static __inline__ void scm_destroy(struct scm_cookie *scm)
@@ -88,6 +105,8 @@ static __inline__ void scm_destroy(struct scm_cookie *scm)
 static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
 			       struct scm_cookie *scm, bool forcecreds)
 {
+	char *procinfo;
+	int len;
 	memset(scm, 0, sizeof(*scm));
 	scm->creds.uid = INVALID_UID;
 	scm->creds.gid = INVALID_GID;
@@ -96,6 +115,9 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
 			     current_gid());
 		scm_set_audit(scm, audit_get_loginuid(current),
 			      audit_get_sessionid(current));
+		len = scm_get_current_procinfo(&procinfo);
+		if (len > 0)
+			scm_set_procinfo(scm, procinfo, len);
 	}
 	unix_get_peersec_dgram(sock, scm);
 	if (msg->msg_controllen <= 0)
@@ -148,6 +170,8 @@ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
 		};
 		put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(ucreds), &ucreds);
 		put_cmsg(msg, SOL_SOCKET, SCM_AUDIT, sizeof(uaudits), &uaudits);
+		put_cmsg(msg, SOL_SOCKET, SCM_PROCINFO, scm->procinfo.len,
+				 scm->procinfo.procinfo);
 	}
 
 	scm_destroy_cred(scm);
diff --git a/net/core/scm.c b/net/core/scm.c
index 03795d0..09ec044 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -339,3 +339,68 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)
 	return new_fpl;
 }
 EXPORT_SYMBOL(scm_fp_dup);
+
+int scm_get_current_procinfo(char **procinfo)
+{
+	int res = 0;
+	unsigned int len;
+	char *buffer = NULL;
+	struct mm_struct *mm;
+	int comm_len = strlen(current->comm);
+
+	*procinfo = NULL;
+
+	buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	mm = get_task_mm(current);
+	if (!mm)
+		goto out;
+	if (!mm->arg_end)
+		goto out_mm;    /* Shh! No looking before we're done */
+
+	len = mm->arg_end - mm->arg_start;
+
+	if (len > PAGE_SIZE)
+		len = PAGE_SIZE;
+
+	res = access_process_vm(current, mm->arg_start, buffer, len, 0);
+
+	/* If the nul at the end of args has been overwritten, then
+	 * assume application is using setproctitle(3).
+	 */
+	if (res > 0 && buffer[res-1] != '\0' && len < PAGE_SIZE) {
+		len = strnlen(buffer, res);
+		if (len < res) {
+			res = len;
+		} else {
+			len = mm->env_end - mm->env_start;
+			if (len > PAGE_SIZE - res)
+				len = PAGE_SIZE - res;
+			res += access_process_vm(current, mm->env_start,
+						 buffer+res, len, 0);
+			res = strnlen(buffer, res);
+		}
+	}
+
+	/* strlen(comm) + \0 + len of cmdline */
+	len = comm_len + 1 + res;
+	*procinfo = kmalloc(len, GFP_KERNEL);
+	if (!*procinfo) {
+		res = -ENOMEM;
+		goto out_mm;
+	}
+
+	memcpy(*procinfo, current->comm, comm_len + 1); /* include \0 */
+	if (res > 0)
+		memcpy(*procinfo + comm_len + 1, buffer, res);
+	res = len;
+
+out_mm:
+	mmput(mm);
+out:
+	kfree(buffer);
+	return res;
+}
+EXPORT_SYMBOL(scm_get_current_procinfo);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index c410f76..ab0be13 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1341,9 +1341,14 @@ static void unix_destruct_scm(struct sk_buff *skb)
 	struct scm_cookie scm;
 	memset(&scm, 0, sizeof(scm));
 	scm.pid  = UNIXCB(skb).pid;
+	if (UNIXCB(skb).scm) {
+		scm.procinfo.procinfo = UNIXSCM(skb).procinfo;
+		scm.procinfo.len = UNIXSCM(skb).procinfo_len;
+	}
 	if (UNIXCB(skb).fp)
 		unix_detach_fds(&scm, skb);
 
+	kfree(UNIXCB(skb).scm);
 	/* Alas, it calls VFS */
 	/* So fscking what? fput() had been SMP-safe since the last Summer */
 	scm_destroy(&scm);
@@ -1390,15 +1395,31 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen
 {
 	int err = 0;
 
+	if (!UNIXCB(skb).scm) {
+		UNIXCB(skb).scm = kmalloc(sizeof(struct unix_skb_parms_scm),
+					  GFP_KERNEL);
+		if (!UNIXCB(skb).scm)
+			return -ENOMEM;
+	}
+
 	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;
+	UNIXSCM(skb).loginuid = scm->audit.loginuid;
+	UNIXSCM(skb).sessionid = scm->audit.sessionid;
 	UNIXCB(skb).fp = NULL;
 	if (scm->fp && send_fds)
 		err = unix_attach_fds(scm, skb);
 
+	UNIXSCM(skb).procinfo = NULL;
+	if (scm->procinfo.procinfo) {
+		UNIXSCM(skb).procinfo_len = scm->procinfo.len;
+		UNIXSCM(skb).procinfo = kmemdup(scm->procinfo.procinfo,
+					scm->procinfo.len, GFP_KERNEL);
+		if (!UNIXSCM(skb).procinfo)
+			return -ENOMEM;
+	}
+
 	skb->destructor = unix_destruct_scm;
 	return err;
 }
@@ -1418,8 +1439,10 @@ 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);
+		UNIXSCM(skb).loginuid = audit_get_loginuid(current);
+		UNIXSCM(skb).sessionid = audit_get_sessionid(current);
+		UNIXSCM(skb).procinfo_len = scm_get_current_procinfo(
+			&UNIXSCM(skb).procinfo);
 	}
 }
 
@@ -1816,7 +1839,17 @@ 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);
+	if (UNIXCB(skb).scm) {
+		scm_set_audit(siocb->scm, UNIXSCM(skb).loginuid,
+			      UNIXSCM(skb).sessionid);
+		if (UNIXSCM(skb).procinfo) {
+			scm_set_procinfo(siocb->scm,
+					 kmemdup(UNIXSCM(skb).procinfo,
+						 UNIXSCM(skb).procinfo_len,
+						 GFP_KERNEL),
+					 UNIXSCM(skb).procinfo_len);
+		}
+	}
 	unix_set_secdata(siocb->scm, skb);
 
 	if (!(flags & MSG_PEEK)) {
@@ -1998,8 +2031,18 @@ 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);
+			if (UNIXCB(skb).scm) {
+				scm_set_audit(siocb->scm,
+					      UNIXSCM(skb).loginuid,
+					      UNIXSCM(skb).sessionid);
+				if (UNIXSCM(skb).procinfo) {
+					scm_set_procinfo(siocb->scm,
+						kmemdup(UNIXSCM(skb).procinfo,
+						UNIXSCM(skb).procinfo_len,
+						GFP_KERNEL),
+						UNIXSCM(skb).procinfo_len);
+				}
+			}
 			check_creds = 1;
 		}
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH 3/3] Send cgroup_path in SCM_CGROUP
  2013-08-27 14:39 [PATCH 0/3] Send audit/procinfo/cgroup data in socket-level control message Jan Kaluza
  2013-08-27 14:39 ` [PATCH 1/3] Send loginuid and sessionid in SCM_AUDIT Jan Kaluza
  2013-08-27 14:39 ` [PATCH 2/3] Send comm and cmdline in SCM_PROCINFO Jan Kaluza
@ 2013-08-27 14:40 ` Jan Kaluza
  2013-08-28 14:00   ` Tejun Heo
       [not found] ` <1377614400-27122-1-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
  3 siblings, 1 reply; 79+ messages in thread
From: Jan Kaluza @ 2013-08-27 14:40 UTC (permalink / raw)
  To: davem; +Cc: LKML, netdev, eparis, rgb, Jan Kaluza

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
---
 include/linux/socket.h |  1 +
 include/net/af_unix.h  |  1 +
 include/net/scm.h      | 15 +++++++++++++++
 net/core/scm.c         | 18 ++++++++++++++++++
 net/unix/af_unix.c     | 20 ++++++++++++++++++++
 5 files changed, 55 insertions(+)

diff --git a/include/linux/socket.h b/include/linux/socket.h
index 6c7ace0..621fff1 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -133,6 +133,7 @@ static inline struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr
 #define SCM_AUDIT	0x04		/* rw: struct uaudit		*/
 #define SCM_PROCINFO	0x05	/* rw: comm + cmdline (NULL terminated
 					   array of char *) */
+#define SCM_CGROUP	0x06		/* rw: cgroup path */
 
 struct ucred {
 	__u32	pid;
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index 05c7678..c49bf35 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -32,6 +32,7 @@ struct unix_skb_parms_scm {
 	unsigned int sessionid;
 	char *procinfo;
 	int procinfo_len;
+	char *cgroup_path;
 };
 
 struct unix_skb_parms {
diff --git a/include/net/scm.h b/include/net/scm.h
index 3346030..5398826 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -41,6 +41,7 @@ struct scm_cookie {
 	struct scm_creds	creds;		/* Skb credentials	*/
 	struct scm_audit	audit;		/* Skb audit	*/
 	struct scm_procinfo	procinfo;	/* Skb procinfo */
+	char *cgroup_path;
 #ifdef CONFIG_SECURITY_NETWORK
 	u32			secid;		/* Passed security ID 	*/
 #endif
@@ -52,6 +53,7 @@ extern int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie
 extern void __scm_destroy(struct scm_cookie *scm);
 extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl);
 extern int scm_get_current_procinfo(char **procinfo);
+extern int scm_get_current_cgroup_path(char **cgroup_path);
 
 #ifdef CONFIG_SECURITY_NETWORK
 static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
@@ -86,6 +88,12 @@ static inline void scm_set_procinfo(struct scm_cookie *scm,
 	scm->procinfo.len = len;
 }
 
+static inline void scm_set_cgroup_path(struct scm_cookie *scm,
+				    char *cgroup_path)
+{
+	scm->cgroup_path = cgroup_path;
+}
+
 static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
 {
 	put_pid(scm->pid);
@@ -140,6 +148,9 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc
 			security_release_secctx(secdata, seclen);
 		}
 	}
+
+	kfree(scm->cgroup_path);
+	scm->cgroup_path = NULL;
 }
 #else
 static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
@@ -172,6 +183,10 @@ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
 		put_cmsg(msg, SOL_SOCKET, SCM_AUDIT, sizeof(uaudits), &uaudits);
 		put_cmsg(msg, SOL_SOCKET, SCM_PROCINFO, scm->procinfo.len,
 				 scm->procinfo.procinfo);
+		if (scm->cgroup_path) {
+			put_cmsg(msg, SOL_SOCKET, SCM_CGROUP,
+				 strlen(scm->cgroup_path), scm->cgroup_path);
+		}
 	}
 
 	scm_destroy_cred(scm);
diff --git a/net/core/scm.c b/net/core/scm.c
index 09ec044..2d408b9 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -404,3 +404,21 @@ out:
 	return res;
 }
 EXPORT_SYMBOL(scm_get_current_procinfo);
+
+int scm_get_current_cgroup_path(char **cgroup_path)
+{
+	int ret = 0;
+
+	*cgroup_path = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!(*cgroup_path))
+		return -ENOMEM;
+
+	ret = task_cgroup_path(current, *cgroup_path, PAGE_SIZE);
+	if (ret < 0) {
+		kfree(*cgroup_path);
+		*cgroup_path = NULL;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(scm_get_current_cgroup_path);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index ab0be13..b638083 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1344,6 +1344,7 @@ static void unix_destruct_scm(struct sk_buff *skb)
 	if (UNIXCB(skb).scm) {
 		scm.procinfo.procinfo = UNIXSCM(skb).procinfo;
 		scm.procinfo.len = UNIXSCM(skb).procinfo_len;
+		scm.cgroup_path = UNIXSCM(skb).cgroup_path;
 	}
 	if (UNIXCB(skb).fp)
 		unix_detach_fds(&scm, skb);
@@ -1420,6 +1421,14 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen
 			return -ENOMEM;
 	}
 
+	UNIXSCM(skb).cgroup_path = NULL;
+	if (scm->cgroup_path) {
+		UNIXSCM(skb).cgroup_path = kstrdup(scm->cgroup_path,
+						   GFP_KERNEL);
+		if (!UNIXSCM(skb).cgroup_path)
+			return -ENOMEM;
+	}
+
 	skb->destructor = unix_destruct_scm;
 	return err;
 }
@@ -1443,6 +1452,7 @@ static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
 		UNIXSCM(skb).sessionid = audit_get_sessionid(current);
 		UNIXSCM(skb).procinfo_len = scm_get_current_procinfo(
 			&UNIXSCM(skb).procinfo);
+		scm_get_current_cgroup_path(&UNIXSCM(skb).cgroup_path);
 	}
 }
 
@@ -1849,6 +1859,11 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
 						 GFP_KERNEL),
 					 UNIXSCM(skb).procinfo_len);
 		}
+		if (UNIXSCM(skb).cgroup_path) {
+			scm_set_cgroup_path(siocb->scm,
+					    kstrdup(UNIXSCM(skb).cgroup_path,
+						    GFP_KERNEL));
+		}
 	}
 	unix_set_secdata(siocb->scm, skb);
 
@@ -2042,6 +2057,11 @@ again:
 						GFP_KERNEL),
 						UNIXSCM(skb).procinfo_len);
 				}
+				if (UNIXSCM(skb).cgroup_path) {
+					scm_set_cgroup_path(siocb->scm,
+							    kstrdup(UNIXSCM(skb).cgroup_path,
+							    GFP_KERNEL));
+				}
 			}
 			check_creds = 1;
 		}
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* Re: [PATCH 3/3] Send cgroup_path in SCM_CGROUP
  2013-08-27 14:40 ` [PATCH 3/3] Send cgroup_path in SCM_CGROUP Jan Kaluza
@ 2013-08-28 14:00   ` Tejun Heo
  0 siblings, 0 replies; 79+ messages in thread
From: Tejun Heo @ 2013-08-28 14:00 UTC (permalink / raw)
  To: Jan Kaluza; +Cc: davem, LKML, netdev, eparis, rgb

Hello, Jan.

Can you please cc cgroup maintainers and mailing lists from
MAINTAINERS for cgroup related changes?

On Tue, Aug 27, 2013 at 04:40:00PM +0200, Jan Kaluza wrote:

Also, please describe what change is being made why on each patch.
Repeating the same description is fine but each patch descrption
should be more or less self-sufficient.

> +int scm_get_current_cgroup_path(char **cgroup_path)
> +{
> +	int ret = 0;
> +
> +	*cgroup_path = kmalloc(PAGE_SIZE, GFP_KERNEL);

PATH_MAX?

> +	if (!(*cgroup_path))
> +		return -ENOMEM;
> +
> +	ret = task_cgroup_path(current, *cgroup_path, PAGE_SIZE);
> +	if (ret < 0) {
> +		kfree(*cgroup_path);
> +		*cgroup_path = NULL;
> +	}
> +
> +	return ret;
> +}

Other than that, cgroup side looks fine to me.  For cgroup bits,

  Reviewed-by: Tejun Heo <tj@kernel.org>

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 79+ messages in thread

* [PATCH v2 0/3] Send audit/procinfo/cgroup data in socket-level control message
  2013-08-27 14:39 [PATCH 0/3] Send audit/procinfo/cgroup data in socket-level control message Jan Kaluza
@ 2013-08-29 14:13     ` Jan Kaluza
  2013-08-27 14:39 ` [PATCH 2/3] Send comm and cmdline in SCM_PROCINFO Jan Kaluza
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluza @ 2013-08-29 14:13 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: Jan Kaluza, rgb-H+wXaHxf7aLQT0dZR+AlfA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, tj-DgEjT+Ai2ygdnm+yROfE0A,
	cgroups-u79uwXL29TY76Z2rM5mHXA

Hi,

this patchset against net-next (applies also to linux-next) adds 3 new types
of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).
This is needed by journald (logging daemon used as part of systemd ecosystem)
to get additional context together with log messages received using UNIX socket.

Changes in v2:
- use PATH_MAX instead of PAGE_SIZE in SCM_CGROUP patch
- describe each patch individually

Jan Kaluza (3):
  Send loginuid and sessionid in SCM_AUDIT
  Send comm and cmdline in SCM_PROCINFO
  Send cgroup_path in SCM_CGROUP

 include/linux/socket.h |  9 ++++++
 include/net/af_unix.h  | 10 ++++++
 include/net/scm.h      | 67 ++++++++++++++++++++++++++++++++++++++--
 net/core/scm.c         | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++
 net/unix/af_unix.c     | 70 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 237 insertions(+), 2 deletions(-)

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 79+ messages in thread

* [PATCH v2 0/3] Send audit/procinfo/cgroup data in socket-level control message
@ 2013-08-29 14:13     ` Jan Kaluza
  0 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluza @ 2013-08-29 14:13 UTC (permalink / raw)
  To: davem
  Cc: LKML, netdev, eparis, rgb, tj, lizefan, containers, cgroups,
	viro, Jan Kaluza

Hi,

this patchset against net-next (applies also to linux-next) adds 3 new types
of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).
This is needed by journald (logging daemon used as part of systemd ecosystem)
to get additional context together with log messages received using UNIX socket.

Changes in v2:
- use PATH_MAX instead of PAGE_SIZE in SCM_CGROUP patch
- describe each patch individually

Jan Kaluza (3):
  Send loginuid and sessionid in SCM_AUDIT
  Send comm and cmdline in SCM_PROCINFO
  Send cgroup_path in SCM_CGROUP

 include/linux/socket.h |  9 ++++++
 include/net/af_unix.h  | 10 ++++++
 include/net/scm.h      | 67 ++++++++++++++++++++++++++++++++++++++--
 net/core/scm.c         | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++
 net/unix/af_unix.c     | 70 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 237 insertions(+), 2 deletions(-)

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 79+ messages in thread

* [PATCH v2 1/3] Send loginuid and sessionid in SCM_AUDIT
  2013-08-29 14:13     ` Jan Kaluza
@ 2013-08-29 14:13         ` Jan Kaluza
  -1 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluza @ 2013-08-29 14:13 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: Jan Kaluza, rgb-H+wXaHxf7aLQT0dZR+AlfA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, tj-DgEjT+Ai2ygdnm+yROfE0A,
	cgroups-u79uwXL29TY76Z2rM5mHXA

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-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 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

^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH v2 1/3] Send loginuid and sessionid in SCM_AUDIT
@ 2013-08-29 14:13         ` Jan Kaluza
  0 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluza @ 2013-08-29 14:13 UTC (permalink / raw)
  To: davem
  Cc: LKML, netdev, eparis, rgb, tj, lizefan, containers, cgroups,
	viro, Jan Kaluza

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@redhat.com>
---
 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


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH v2 2/3] Send comm and cmdline in SCM_PROCINFO
  2013-08-29 14:13     ` Jan Kaluza
@ 2013-08-29 14:13         ` Jan Kaluza
  -1 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluza @ 2013-08-29 14:13 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: Jan Kaluza, rgb-H+wXaHxf7aLQT0dZR+AlfA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, tj-DgEjT+Ai2ygdnm+yROfE0A,
	cgroups-u79uwXL29TY76Z2rM5mHXA

Add new SCM type called SCM_PROCINFO to send "comm" and "cmdline" in SCM.
This is useful for journald (systemd logging daemon) to get additional context
with each log line received using UNIX socket.

To achieve that I had to create new struct called unix_skb_parms_scm, because
unix_skb_parms was too big. This change made a patch more complex, because
this new struct has to be allocated/freed.

scm_get_current_procinfo is inspired by ./fs/proc/base.c.

Signed-off-by: Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 include/linux/socket.h |  2 ++
 include/net/af_unix.h  | 11 +++++++--
 include/net/scm.h      | 24 +++++++++++++++++++
 net/core/scm.c         | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++
 net/unix/af_unix.c     | 57 +++++++++++++++++++++++++++++++++++++------
 5 files changed, 150 insertions(+), 9 deletions(-)

diff --git a/include/linux/socket.h b/include/linux/socket.h
index 505047a..6c7ace0 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -131,6 +131,8 @@ static inline struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr
 #define SCM_CREDENTIALS 0x02		/* rw: struct ucred		*/
 #define SCM_SECURITY	0x03		/* rw: security label		*/
 #define SCM_AUDIT	0x04		/* rw: struct uaudit		*/
+#define SCM_PROCINFO	0x05	/* rw: comm + cmdline (NULL terminated
+					   array of char *) */
 
 struct ucred {
 	__u32	pid;
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index 3b9d22a..05c7678 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -27,6 +27,13 @@ struct unix_address {
 	struct sockaddr_un name[0];
 };
 
+struct unix_skb_parms_scm {
+	kuid_t loginuid;
+	unsigned int sessionid;
+	char *procinfo;
+	int procinfo_len;
+};
+
 struct unix_skb_parms {
 	struct pid		*pid;		/* Skb credentials	*/
 	kuid_t			uid;
@@ -36,12 +43,12 @@ struct unix_skb_parms {
 	u32			secid;		/* Security ID		*/
 #endif
 	u32			consumed;
-	kuid_t			loginuid;
-	unsigned int		sessionid;
+	struct unix_skb_parms_scm *scm;
 };
 
 #define UNIXCB(skb) 	(*(struct unix_skb_parms *)&((skb)->cb))
 #define UNIXSID(skb)	(&UNIXCB((skb)).secid)
+#define UNIXSCM(skb)	(*(UNIXCB((skb)).scm))
 
 #define unix_state_lock(s)	spin_lock(&unix_sk(s)->lock)
 #define unix_state_unlock(s)	spin_unlock(&unix_sk(s)->lock)
diff --git a/include/net/scm.h b/include/net/scm.h
index e349a25..3346030 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -30,11 +30,17 @@ struct scm_fp_list {
 	struct file		*fp[SCM_MAX_FD];
 };
 
+struct scm_procinfo {
+	char *procinfo;
+	int len;
+};
+
 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	*/
+	struct scm_procinfo	procinfo;	/* Skb procinfo */
 #ifdef CONFIG_SECURITY_NETWORK
 	u32			secid;		/* Passed security ID 	*/
 #endif
@@ -45,6 +51,7 @@ extern void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm);
 extern int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm);
 extern void __scm_destroy(struct scm_cookie *scm);
 extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl);
+extern int scm_get_current_procinfo(char **procinfo);
 
 #ifdef CONFIG_SECURITY_NETWORK
 static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
@@ -72,10 +79,20 @@ static inline void scm_set_audit(struct scm_cookie *scm,
 	scm->audit.sessionid = sessionid;
 }
 
+static inline void scm_set_procinfo(struct scm_cookie *scm,
+				    char *procinfo, int len)
+{
+	scm->procinfo.procinfo = procinfo;
+	scm->procinfo.len = len;
+}
+
 static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
 {
 	put_pid(scm->pid);
 	scm->pid  = NULL;
+	kfree(scm->procinfo.procinfo);
+	scm->procinfo.procinfo = NULL;
+	scm->procinfo.len = 0;
 }
 
 static __inline__ void scm_destroy(struct scm_cookie *scm)
@@ -88,6 +105,8 @@ static __inline__ void scm_destroy(struct scm_cookie *scm)
 static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
 			       struct scm_cookie *scm, bool forcecreds)
 {
+	char *procinfo;
+	int len;
 	memset(scm, 0, sizeof(*scm));
 	scm->creds.uid = INVALID_UID;
 	scm->creds.gid = INVALID_GID;
@@ -96,6 +115,9 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
 			     current_gid());
 		scm_set_audit(scm, audit_get_loginuid(current),
 			      audit_get_sessionid(current));
+		len = scm_get_current_procinfo(&procinfo);
+		if (len > 0)
+			scm_set_procinfo(scm, procinfo, len);
 	}
 	unix_get_peersec_dgram(sock, scm);
 	if (msg->msg_controllen <= 0)
@@ -148,6 +170,8 @@ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
 		};
 		put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(ucreds), &ucreds);
 		put_cmsg(msg, SOL_SOCKET, SCM_AUDIT, sizeof(uaudits), &uaudits);
+		put_cmsg(msg, SOL_SOCKET, SCM_PROCINFO, scm->procinfo.len,
+				 scm->procinfo.procinfo);
 	}
 
 	scm_destroy_cred(scm);
diff --git a/net/core/scm.c b/net/core/scm.c
index 03795d0..09ec044 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -339,3 +339,68 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)
 	return new_fpl;
 }
 EXPORT_SYMBOL(scm_fp_dup);
+
+int scm_get_current_procinfo(char **procinfo)
+{
+	int res = 0;
+	unsigned int len;
+	char *buffer = NULL;
+	struct mm_struct *mm;
+	int comm_len = strlen(current->comm);
+
+	*procinfo = NULL;
+
+	buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	mm = get_task_mm(current);
+	if (!mm)
+		goto out;
+	if (!mm->arg_end)
+		goto out_mm;    /* Shh! No looking before we're done */
+
+	len = mm->arg_end - mm->arg_start;
+
+	if (len > PAGE_SIZE)
+		len = PAGE_SIZE;
+
+	res = access_process_vm(current, mm->arg_start, buffer, len, 0);
+
+	/* If the nul at the end of args has been overwritten, then
+	 * assume application is using setproctitle(3).
+	 */
+	if (res > 0 && buffer[res-1] != '\0' && len < PAGE_SIZE) {
+		len = strnlen(buffer, res);
+		if (len < res) {
+			res = len;
+		} else {
+			len = mm->env_end - mm->env_start;
+			if (len > PAGE_SIZE - res)
+				len = PAGE_SIZE - res;
+			res += access_process_vm(current, mm->env_start,
+						 buffer+res, len, 0);
+			res = strnlen(buffer, res);
+		}
+	}
+
+	/* strlen(comm) + \0 + len of cmdline */
+	len = comm_len + 1 + res;
+	*procinfo = kmalloc(len, GFP_KERNEL);
+	if (!*procinfo) {
+		res = -ENOMEM;
+		goto out_mm;
+	}
+
+	memcpy(*procinfo, current->comm, comm_len + 1); /* include \0 */
+	if (res > 0)
+		memcpy(*procinfo + comm_len + 1, buffer, res);
+	res = len;
+
+out_mm:
+	mmput(mm);
+out:
+	kfree(buffer);
+	return res;
+}
+EXPORT_SYMBOL(scm_get_current_procinfo);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index c410f76..ab0be13 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1341,9 +1341,14 @@ static void unix_destruct_scm(struct sk_buff *skb)
 	struct scm_cookie scm;
 	memset(&scm, 0, sizeof(scm));
 	scm.pid  = UNIXCB(skb).pid;
+	if (UNIXCB(skb).scm) {
+		scm.procinfo.procinfo = UNIXSCM(skb).procinfo;
+		scm.procinfo.len = UNIXSCM(skb).procinfo_len;
+	}
 	if (UNIXCB(skb).fp)
 		unix_detach_fds(&scm, skb);
 
+	kfree(UNIXCB(skb).scm);
 	/* Alas, it calls VFS */
 	/* So fscking what? fput() had been SMP-safe since the last Summer */
 	scm_destroy(&scm);
@@ -1390,15 +1395,31 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen
 {
 	int err = 0;
 
+	if (!UNIXCB(skb).scm) {
+		UNIXCB(skb).scm = kmalloc(sizeof(struct unix_skb_parms_scm),
+					  GFP_KERNEL);
+		if (!UNIXCB(skb).scm)
+			return -ENOMEM;
+	}
+
 	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;
+	UNIXSCM(skb).loginuid = scm->audit.loginuid;
+	UNIXSCM(skb).sessionid = scm->audit.sessionid;
 	UNIXCB(skb).fp = NULL;
 	if (scm->fp && send_fds)
 		err = unix_attach_fds(scm, skb);
 
+	UNIXSCM(skb).procinfo = NULL;
+	if (scm->procinfo.procinfo) {
+		UNIXSCM(skb).procinfo_len = scm->procinfo.len;
+		UNIXSCM(skb).procinfo = kmemdup(scm->procinfo.procinfo,
+					scm->procinfo.len, GFP_KERNEL);
+		if (!UNIXSCM(skb).procinfo)
+			return -ENOMEM;
+	}
+
 	skb->destructor = unix_destruct_scm;
 	return err;
 }
@@ -1418,8 +1439,10 @@ 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);
+		UNIXSCM(skb).loginuid = audit_get_loginuid(current);
+		UNIXSCM(skb).sessionid = audit_get_sessionid(current);
+		UNIXSCM(skb).procinfo_len = scm_get_current_procinfo(
+			&UNIXSCM(skb).procinfo);
 	}
 }
 
@@ -1816,7 +1839,17 @@ 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);
+	if (UNIXCB(skb).scm) {
+		scm_set_audit(siocb->scm, UNIXSCM(skb).loginuid,
+			      UNIXSCM(skb).sessionid);
+		if (UNIXSCM(skb).procinfo) {
+			scm_set_procinfo(siocb->scm,
+					 kmemdup(UNIXSCM(skb).procinfo,
+						 UNIXSCM(skb).procinfo_len,
+						 GFP_KERNEL),
+					 UNIXSCM(skb).procinfo_len);
+		}
+	}
 	unix_set_secdata(siocb->scm, skb);
 
 	if (!(flags & MSG_PEEK)) {
@@ -1998,8 +2031,18 @@ 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);
+			if (UNIXCB(skb).scm) {
+				scm_set_audit(siocb->scm,
+					      UNIXSCM(skb).loginuid,
+					      UNIXSCM(skb).sessionid);
+				if (UNIXSCM(skb).procinfo) {
+					scm_set_procinfo(siocb->scm,
+						kmemdup(UNIXSCM(skb).procinfo,
+						UNIXSCM(skb).procinfo_len,
+						GFP_KERNEL),
+						UNIXSCM(skb).procinfo_len);
+				}
+			}
 			check_creds = 1;
 		}
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH v2 2/3] Send comm and cmdline in SCM_PROCINFO
@ 2013-08-29 14:13         ` Jan Kaluza
  0 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluza @ 2013-08-29 14:13 UTC (permalink / raw)
  To: davem
  Cc: LKML, netdev, eparis, rgb, tj, lizefan, containers, cgroups,
	viro, Jan Kaluza

Add new SCM type called SCM_PROCINFO to send "comm" and "cmdline" in SCM.
This is useful for journald (systemd logging daemon) to get additional context
with each log line received using UNIX socket.

To achieve that I had to create new struct called unix_skb_parms_scm, because
unix_skb_parms was too big. This change made a patch more complex, because
this new struct has to be allocated/freed.

scm_get_current_procinfo is inspired by ./fs/proc/base.c.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
---
 include/linux/socket.h |  2 ++
 include/net/af_unix.h  | 11 +++++++--
 include/net/scm.h      | 24 +++++++++++++++++++
 net/core/scm.c         | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++
 net/unix/af_unix.c     | 57 +++++++++++++++++++++++++++++++++++++------
 5 files changed, 150 insertions(+), 9 deletions(-)

diff --git a/include/linux/socket.h b/include/linux/socket.h
index 505047a..6c7ace0 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -131,6 +131,8 @@ static inline struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr
 #define SCM_CREDENTIALS 0x02		/* rw: struct ucred		*/
 #define SCM_SECURITY	0x03		/* rw: security label		*/
 #define SCM_AUDIT	0x04		/* rw: struct uaudit		*/
+#define SCM_PROCINFO	0x05	/* rw: comm + cmdline (NULL terminated
+					   array of char *) */
 
 struct ucred {
 	__u32	pid;
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index 3b9d22a..05c7678 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -27,6 +27,13 @@ struct unix_address {
 	struct sockaddr_un name[0];
 };
 
+struct unix_skb_parms_scm {
+	kuid_t loginuid;
+	unsigned int sessionid;
+	char *procinfo;
+	int procinfo_len;
+};
+
 struct unix_skb_parms {
 	struct pid		*pid;		/* Skb credentials	*/
 	kuid_t			uid;
@@ -36,12 +43,12 @@ struct unix_skb_parms {
 	u32			secid;		/* Security ID		*/
 #endif
 	u32			consumed;
-	kuid_t			loginuid;
-	unsigned int		sessionid;
+	struct unix_skb_parms_scm *scm;
 };
 
 #define UNIXCB(skb) 	(*(struct unix_skb_parms *)&((skb)->cb))
 #define UNIXSID(skb)	(&UNIXCB((skb)).secid)
+#define UNIXSCM(skb)	(*(UNIXCB((skb)).scm))
 
 #define unix_state_lock(s)	spin_lock(&unix_sk(s)->lock)
 #define unix_state_unlock(s)	spin_unlock(&unix_sk(s)->lock)
diff --git a/include/net/scm.h b/include/net/scm.h
index e349a25..3346030 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -30,11 +30,17 @@ struct scm_fp_list {
 	struct file		*fp[SCM_MAX_FD];
 };
 
+struct scm_procinfo {
+	char *procinfo;
+	int len;
+};
+
 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	*/
+	struct scm_procinfo	procinfo;	/* Skb procinfo */
 #ifdef CONFIG_SECURITY_NETWORK
 	u32			secid;		/* Passed security ID 	*/
 #endif
@@ -45,6 +51,7 @@ extern void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm);
 extern int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm);
 extern void __scm_destroy(struct scm_cookie *scm);
 extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl);
+extern int scm_get_current_procinfo(char **procinfo);
 
 #ifdef CONFIG_SECURITY_NETWORK
 static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
@@ -72,10 +79,20 @@ static inline void scm_set_audit(struct scm_cookie *scm,
 	scm->audit.sessionid = sessionid;
 }
 
+static inline void scm_set_procinfo(struct scm_cookie *scm,
+				    char *procinfo, int len)
+{
+	scm->procinfo.procinfo = procinfo;
+	scm->procinfo.len = len;
+}
+
 static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
 {
 	put_pid(scm->pid);
 	scm->pid  = NULL;
+	kfree(scm->procinfo.procinfo);
+	scm->procinfo.procinfo = NULL;
+	scm->procinfo.len = 0;
 }
 
 static __inline__ void scm_destroy(struct scm_cookie *scm)
@@ -88,6 +105,8 @@ static __inline__ void scm_destroy(struct scm_cookie *scm)
 static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
 			       struct scm_cookie *scm, bool forcecreds)
 {
+	char *procinfo;
+	int len;
 	memset(scm, 0, sizeof(*scm));
 	scm->creds.uid = INVALID_UID;
 	scm->creds.gid = INVALID_GID;
@@ -96,6 +115,9 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
 			     current_gid());
 		scm_set_audit(scm, audit_get_loginuid(current),
 			      audit_get_sessionid(current));
+		len = scm_get_current_procinfo(&procinfo);
+		if (len > 0)
+			scm_set_procinfo(scm, procinfo, len);
 	}
 	unix_get_peersec_dgram(sock, scm);
 	if (msg->msg_controllen <= 0)
@@ -148,6 +170,8 @@ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
 		};
 		put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(ucreds), &ucreds);
 		put_cmsg(msg, SOL_SOCKET, SCM_AUDIT, sizeof(uaudits), &uaudits);
+		put_cmsg(msg, SOL_SOCKET, SCM_PROCINFO, scm->procinfo.len,
+				 scm->procinfo.procinfo);
 	}
 
 	scm_destroy_cred(scm);
diff --git a/net/core/scm.c b/net/core/scm.c
index 03795d0..09ec044 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -339,3 +339,68 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)
 	return new_fpl;
 }
 EXPORT_SYMBOL(scm_fp_dup);
+
+int scm_get_current_procinfo(char **procinfo)
+{
+	int res = 0;
+	unsigned int len;
+	char *buffer = NULL;
+	struct mm_struct *mm;
+	int comm_len = strlen(current->comm);
+
+	*procinfo = NULL;
+
+	buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	mm = get_task_mm(current);
+	if (!mm)
+		goto out;
+	if (!mm->arg_end)
+		goto out_mm;    /* Shh! No looking before we're done */
+
+	len = mm->arg_end - mm->arg_start;
+
+	if (len > PAGE_SIZE)
+		len = PAGE_SIZE;
+
+	res = access_process_vm(current, mm->arg_start, buffer, len, 0);
+
+	/* If the nul at the end of args has been overwritten, then
+	 * assume application is using setproctitle(3).
+	 */
+	if (res > 0 && buffer[res-1] != '\0' && len < PAGE_SIZE) {
+		len = strnlen(buffer, res);
+		if (len < res) {
+			res = len;
+		} else {
+			len = mm->env_end - mm->env_start;
+			if (len > PAGE_SIZE - res)
+				len = PAGE_SIZE - res;
+			res += access_process_vm(current, mm->env_start,
+						 buffer+res, len, 0);
+			res = strnlen(buffer, res);
+		}
+	}
+
+	/* strlen(comm) + \0 + len of cmdline */
+	len = comm_len + 1 + res;
+	*procinfo = kmalloc(len, GFP_KERNEL);
+	if (!*procinfo) {
+		res = -ENOMEM;
+		goto out_mm;
+	}
+
+	memcpy(*procinfo, current->comm, comm_len + 1); /* include \0 */
+	if (res > 0)
+		memcpy(*procinfo + comm_len + 1, buffer, res);
+	res = len;
+
+out_mm:
+	mmput(mm);
+out:
+	kfree(buffer);
+	return res;
+}
+EXPORT_SYMBOL(scm_get_current_procinfo);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index c410f76..ab0be13 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1341,9 +1341,14 @@ static void unix_destruct_scm(struct sk_buff *skb)
 	struct scm_cookie scm;
 	memset(&scm, 0, sizeof(scm));
 	scm.pid  = UNIXCB(skb).pid;
+	if (UNIXCB(skb).scm) {
+		scm.procinfo.procinfo = UNIXSCM(skb).procinfo;
+		scm.procinfo.len = UNIXSCM(skb).procinfo_len;
+	}
 	if (UNIXCB(skb).fp)
 		unix_detach_fds(&scm, skb);
 
+	kfree(UNIXCB(skb).scm);
 	/* Alas, it calls VFS */
 	/* So fscking what? fput() had been SMP-safe since the last Summer */
 	scm_destroy(&scm);
@@ -1390,15 +1395,31 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen
 {
 	int err = 0;
 
+	if (!UNIXCB(skb).scm) {
+		UNIXCB(skb).scm = kmalloc(sizeof(struct unix_skb_parms_scm),
+					  GFP_KERNEL);
+		if (!UNIXCB(skb).scm)
+			return -ENOMEM;
+	}
+
 	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;
+	UNIXSCM(skb).loginuid = scm->audit.loginuid;
+	UNIXSCM(skb).sessionid = scm->audit.sessionid;
 	UNIXCB(skb).fp = NULL;
 	if (scm->fp && send_fds)
 		err = unix_attach_fds(scm, skb);
 
+	UNIXSCM(skb).procinfo = NULL;
+	if (scm->procinfo.procinfo) {
+		UNIXSCM(skb).procinfo_len = scm->procinfo.len;
+		UNIXSCM(skb).procinfo = kmemdup(scm->procinfo.procinfo,
+					scm->procinfo.len, GFP_KERNEL);
+		if (!UNIXSCM(skb).procinfo)
+			return -ENOMEM;
+	}
+
 	skb->destructor = unix_destruct_scm;
 	return err;
 }
@@ -1418,8 +1439,10 @@ 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);
+		UNIXSCM(skb).loginuid = audit_get_loginuid(current);
+		UNIXSCM(skb).sessionid = audit_get_sessionid(current);
+		UNIXSCM(skb).procinfo_len = scm_get_current_procinfo(
+			&UNIXSCM(skb).procinfo);
 	}
 }
 
@@ -1816,7 +1839,17 @@ 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);
+	if (UNIXCB(skb).scm) {
+		scm_set_audit(siocb->scm, UNIXSCM(skb).loginuid,
+			      UNIXSCM(skb).sessionid);
+		if (UNIXSCM(skb).procinfo) {
+			scm_set_procinfo(siocb->scm,
+					 kmemdup(UNIXSCM(skb).procinfo,
+						 UNIXSCM(skb).procinfo_len,
+						 GFP_KERNEL),
+					 UNIXSCM(skb).procinfo_len);
+		}
+	}
 	unix_set_secdata(siocb->scm, skb);
 
 	if (!(flags & MSG_PEEK)) {
@@ -1998,8 +2031,18 @@ 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);
+			if (UNIXCB(skb).scm) {
+				scm_set_audit(siocb->scm,
+					      UNIXSCM(skb).loginuid,
+					      UNIXSCM(skb).sessionid);
+				if (UNIXSCM(skb).procinfo) {
+					scm_set_procinfo(siocb->scm,
+						kmemdup(UNIXSCM(skb).procinfo,
+						UNIXSCM(skb).procinfo_len,
+						GFP_KERNEL),
+						UNIXSCM(skb).procinfo_len);
+				}
+			}
 			check_creds = 1;
 		}
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH v2 3/3] Send cgroup_path in SCM_CGROUP
  2013-08-29 14:13     ` Jan Kaluza
@ 2013-08-29 14:13         ` Jan Kaluza
  -1 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluza @ 2013-08-29 14:13 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: Jan Kaluza, rgb-H+wXaHxf7aLQT0dZR+AlfA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, tj-DgEjT+Ai2ygdnm+yROfE0A,
	cgroups-u79uwXL29TY76Z2rM5mHXA

Add new SCM type called SCM_CGROUP to send "cgroup_path" 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-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 include/linux/socket.h |  1 +
 include/net/af_unix.h  |  1 +
 include/net/scm.h      | 15 +++++++++++++++
 net/core/scm.c         | 18 ++++++++++++++++++
 net/unix/af_unix.c     | 20 ++++++++++++++++++++
 5 files changed, 55 insertions(+)

diff --git a/include/linux/socket.h b/include/linux/socket.h
index 6c7ace0..621fff1 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -133,6 +133,7 @@ static inline struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr
 #define SCM_AUDIT	0x04		/* rw: struct uaudit		*/
 #define SCM_PROCINFO	0x05	/* rw: comm + cmdline (NULL terminated
 					   array of char *) */
+#define SCM_CGROUP	0x06		/* rw: cgroup path */
 
 struct ucred {
 	__u32	pid;
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index 05c7678..c49bf35 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -32,6 +32,7 @@ struct unix_skb_parms_scm {
 	unsigned int sessionid;
 	char *procinfo;
 	int procinfo_len;
+	char *cgroup_path;
 };
 
 struct unix_skb_parms {
diff --git a/include/net/scm.h b/include/net/scm.h
index 3346030..5398826 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -41,6 +41,7 @@ struct scm_cookie {
 	struct scm_creds	creds;		/* Skb credentials	*/
 	struct scm_audit	audit;		/* Skb audit	*/
 	struct scm_procinfo	procinfo;	/* Skb procinfo */
+	char *cgroup_path;
 #ifdef CONFIG_SECURITY_NETWORK
 	u32			secid;		/* Passed security ID 	*/
 #endif
@@ -52,6 +53,7 @@ extern int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie
 extern void __scm_destroy(struct scm_cookie *scm);
 extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl);
 extern int scm_get_current_procinfo(char **procinfo);
+extern int scm_get_current_cgroup_path(char **cgroup_path);
 
 #ifdef CONFIG_SECURITY_NETWORK
 static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
@@ -86,6 +88,12 @@ static inline void scm_set_procinfo(struct scm_cookie *scm,
 	scm->procinfo.len = len;
 }
 
+static inline void scm_set_cgroup_path(struct scm_cookie *scm,
+				    char *cgroup_path)
+{
+	scm->cgroup_path = cgroup_path;
+}
+
 static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
 {
 	put_pid(scm->pid);
@@ -140,6 +148,9 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc
 			security_release_secctx(secdata, seclen);
 		}
 	}
+
+	kfree(scm->cgroup_path);
+	scm->cgroup_path = NULL;
 }
 #else
 static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
@@ -172,6 +183,10 @@ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
 		put_cmsg(msg, SOL_SOCKET, SCM_AUDIT, sizeof(uaudits), &uaudits);
 		put_cmsg(msg, SOL_SOCKET, SCM_PROCINFO, scm->procinfo.len,
 				 scm->procinfo.procinfo);
+		if (scm->cgroup_path) {
+			put_cmsg(msg, SOL_SOCKET, SCM_CGROUP,
+				 strlen(scm->cgroup_path), scm->cgroup_path);
+		}
 	}
 
 	scm_destroy_cred(scm);
diff --git a/net/core/scm.c b/net/core/scm.c
index 09ec044..2d408b9 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -404,3 +404,21 @@ out:
 	return res;
 }
 EXPORT_SYMBOL(scm_get_current_procinfo);
+
+int scm_get_current_cgroup_path(char **cgroup_path)
+{
+	int ret = 0;
+
+	*cgroup_path = kmalloc(PATH_MAX, GFP_KERNEL);
+	if (!(*cgroup_path))
+		return -ENOMEM;
+
+	ret = task_cgroup_path(current, *cgroup_path, PATH_MAX);
+	if (ret < 0) {
+		kfree(*cgroup_path);
+		*cgroup_path = NULL;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(scm_get_current_cgroup_path);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index ab0be13..b638083 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1344,6 +1344,7 @@ static void unix_destruct_scm(struct sk_buff *skb)
 	if (UNIXCB(skb).scm) {
 		scm.procinfo.procinfo = UNIXSCM(skb).procinfo;
 		scm.procinfo.len = UNIXSCM(skb).procinfo_len;
+		scm.cgroup_path = UNIXSCM(skb).cgroup_path;
 	}
 	if (UNIXCB(skb).fp)
 		unix_detach_fds(&scm, skb);
@@ -1420,6 +1421,14 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen
 			return -ENOMEM;
 	}
 
+	UNIXSCM(skb).cgroup_path = NULL;
+	if (scm->cgroup_path) {
+		UNIXSCM(skb).cgroup_path = kstrdup(scm->cgroup_path,
+						   GFP_KERNEL);
+		if (!UNIXSCM(skb).cgroup_path)
+			return -ENOMEM;
+	}
+
 	skb->destructor = unix_destruct_scm;
 	return err;
 }
@@ -1443,6 +1452,7 @@ static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
 		UNIXSCM(skb).sessionid = audit_get_sessionid(current);
 		UNIXSCM(skb).procinfo_len = scm_get_current_procinfo(
 			&UNIXSCM(skb).procinfo);
+		scm_get_current_cgroup_path(&UNIXSCM(skb).cgroup_path);
 	}
 }
 
@@ -1849,6 +1859,11 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
 						 GFP_KERNEL),
 					 UNIXSCM(skb).procinfo_len);
 		}
+		if (UNIXSCM(skb).cgroup_path) {
+			scm_set_cgroup_path(siocb->scm,
+					    kstrdup(UNIXSCM(skb).cgroup_path,
+						    GFP_KERNEL));
+		}
 	}
 	unix_set_secdata(siocb->scm, skb);
 
@@ -2042,6 +2057,11 @@ again:
 						GFP_KERNEL),
 						UNIXSCM(skb).procinfo_len);
 				}
+				if (UNIXSCM(skb).cgroup_path) {
+					scm_set_cgroup_path(siocb->scm,
+							    kstrdup(UNIXSCM(skb).cgroup_path,
+							    GFP_KERNEL));
+				}
 			}
 			check_creds = 1;
 		}
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH v2 3/3] Send cgroup_path in SCM_CGROUP
@ 2013-08-29 14:13         ` Jan Kaluza
  0 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluza @ 2013-08-29 14:13 UTC (permalink / raw)
  To: davem
  Cc: LKML, netdev, eparis, rgb, tj, lizefan, containers, cgroups,
	viro, Jan Kaluza

Add new SCM type called SCM_CGROUP to send "cgroup_path" 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@redhat.com>
---
 include/linux/socket.h |  1 +
 include/net/af_unix.h  |  1 +
 include/net/scm.h      | 15 +++++++++++++++
 net/core/scm.c         | 18 ++++++++++++++++++
 net/unix/af_unix.c     | 20 ++++++++++++++++++++
 5 files changed, 55 insertions(+)

diff --git a/include/linux/socket.h b/include/linux/socket.h
index 6c7ace0..621fff1 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -133,6 +133,7 @@ static inline struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr
 #define SCM_AUDIT	0x04		/* rw: struct uaudit		*/
 #define SCM_PROCINFO	0x05	/* rw: comm + cmdline (NULL terminated
 					   array of char *) */
+#define SCM_CGROUP	0x06		/* rw: cgroup path */
 
 struct ucred {
 	__u32	pid;
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index 05c7678..c49bf35 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -32,6 +32,7 @@ struct unix_skb_parms_scm {
 	unsigned int sessionid;
 	char *procinfo;
 	int procinfo_len;
+	char *cgroup_path;
 };
 
 struct unix_skb_parms {
diff --git a/include/net/scm.h b/include/net/scm.h
index 3346030..5398826 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -41,6 +41,7 @@ struct scm_cookie {
 	struct scm_creds	creds;		/* Skb credentials	*/
 	struct scm_audit	audit;		/* Skb audit	*/
 	struct scm_procinfo	procinfo;	/* Skb procinfo */
+	char *cgroup_path;
 #ifdef CONFIG_SECURITY_NETWORK
 	u32			secid;		/* Passed security ID 	*/
 #endif
@@ -52,6 +53,7 @@ extern int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie
 extern void __scm_destroy(struct scm_cookie *scm);
 extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl);
 extern int scm_get_current_procinfo(char **procinfo);
+extern int scm_get_current_cgroup_path(char **cgroup_path);
 
 #ifdef CONFIG_SECURITY_NETWORK
 static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
@@ -86,6 +88,12 @@ static inline void scm_set_procinfo(struct scm_cookie *scm,
 	scm->procinfo.len = len;
 }
 
+static inline void scm_set_cgroup_path(struct scm_cookie *scm,
+				    char *cgroup_path)
+{
+	scm->cgroup_path = cgroup_path;
+}
+
 static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
 {
 	put_pid(scm->pid);
@@ -140,6 +148,9 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc
 			security_release_secctx(secdata, seclen);
 		}
 	}
+
+	kfree(scm->cgroup_path);
+	scm->cgroup_path = NULL;
 }
 #else
 static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
@@ -172,6 +183,10 @@ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
 		put_cmsg(msg, SOL_SOCKET, SCM_AUDIT, sizeof(uaudits), &uaudits);
 		put_cmsg(msg, SOL_SOCKET, SCM_PROCINFO, scm->procinfo.len,
 				 scm->procinfo.procinfo);
+		if (scm->cgroup_path) {
+			put_cmsg(msg, SOL_SOCKET, SCM_CGROUP,
+				 strlen(scm->cgroup_path), scm->cgroup_path);
+		}
 	}
 
 	scm_destroy_cred(scm);
diff --git a/net/core/scm.c b/net/core/scm.c
index 09ec044..2d408b9 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -404,3 +404,21 @@ out:
 	return res;
 }
 EXPORT_SYMBOL(scm_get_current_procinfo);
+
+int scm_get_current_cgroup_path(char **cgroup_path)
+{
+	int ret = 0;
+
+	*cgroup_path = kmalloc(PATH_MAX, GFP_KERNEL);
+	if (!(*cgroup_path))
+		return -ENOMEM;
+
+	ret = task_cgroup_path(current, *cgroup_path, PATH_MAX);
+	if (ret < 0) {
+		kfree(*cgroup_path);
+		*cgroup_path = NULL;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(scm_get_current_cgroup_path);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index ab0be13..b638083 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1344,6 +1344,7 @@ static void unix_destruct_scm(struct sk_buff *skb)
 	if (UNIXCB(skb).scm) {
 		scm.procinfo.procinfo = UNIXSCM(skb).procinfo;
 		scm.procinfo.len = UNIXSCM(skb).procinfo_len;
+		scm.cgroup_path = UNIXSCM(skb).cgroup_path;
 	}
 	if (UNIXCB(skb).fp)
 		unix_detach_fds(&scm, skb);
@@ -1420,6 +1421,14 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen
 			return -ENOMEM;
 	}
 
+	UNIXSCM(skb).cgroup_path = NULL;
+	if (scm->cgroup_path) {
+		UNIXSCM(skb).cgroup_path = kstrdup(scm->cgroup_path,
+						   GFP_KERNEL);
+		if (!UNIXSCM(skb).cgroup_path)
+			return -ENOMEM;
+	}
+
 	skb->destructor = unix_destruct_scm;
 	return err;
 }
@@ -1443,6 +1452,7 @@ static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
 		UNIXSCM(skb).sessionid = audit_get_sessionid(current);
 		UNIXSCM(skb).procinfo_len = scm_get_current_procinfo(
 			&UNIXSCM(skb).procinfo);
+		scm_get_current_cgroup_path(&UNIXSCM(skb).cgroup_path);
 	}
 }
 
@@ -1849,6 +1859,11 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
 						 GFP_KERNEL),
 					 UNIXSCM(skb).procinfo_len);
 		}
+		if (UNIXSCM(skb).cgroup_path) {
+			scm_set_cgroup_path(siocb->scm,
+					    kstrdup(UNIXSCM(skb).cgroup_path,
+						    GFP_KERNEL));
+		}
 	}
 	unix_set_secdata(siocb->scm, skb);
 
@@ -2042,6 +2057,11 @@ again:
 						GFP_KERNEL),
 						UNIXSCM(skb).procinfo_len);
 				}
+				if (UNIXSCM(skb).cgroup_path) {
+					scm_set_cgroup_path(siocb->scm,
+							    kstrdup(UNIXSCM(skb).cgroup_path,
+							    GFP_KERNEL));
+				}
 			}
 			check_creds = 1;
 		}
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 3/3] Send cgroup_path in SCM_CGROUP
  2013-08-29 14:13         ` Jan Kaluza
@ 2013-09-02 17:17             ` Kay Sievers
  -1 siblings, 0 replies; 79+ messages in thread
From: Kay Sievers @ 2013-09-02 17:17 UTC (permalink / raw)
  To: Jan Kaluza
  Cc: rgb-H+wXaHxf7aLQT0dZR+AlfA, netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, Tejun Heo,
	cgroups-u79uwXL29TY76Z2rM5mHXA, davem-fT/PcQaiUtIeIZ0/mPfg9Q

On Thu, Aug 29, 2013 at 4:13 PM, Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> Add new SCM type called SCM_CGROUP to send "cgroup_path" 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-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

In many cases it's generally more useful to explain *why* something is
done, not *where* it is used. It makes it easier for people to match
the described problem to their own use-cases, where it possibly occurs
too. The problem this patch solves is very generic and not so much
specific to logging or the journal. Maybe something like this:

"Server-like processes in many cases need credentials and other
metadata of the peer, to decide if the calling process is allowed to
request a specific action, or the server just wants to log away this
type of information for auditing tasks.

The current practice to retrieve such process metadata is to look that
information up in procfs with the $PID received over SCM_CREDENTIALS.
This is sufficient for long-running tasks, but introduces a race which
cannot be worked around for short-living processes; the calling
process and all the information in /proc/$PID/ is gone before the
receiver of the socket message can look it up.

This introduces a new SCM type called SCM_CGROUP to allow the direct
attaching of "cgroup_path" to SCM, which is significantly more
efficient and will reliably avoid the race with the round-trip over
procfs."

Thanks,
Kay

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v2 3/3] Send cgroup_path in SCM_CGROUP
@ 2013-09-02 17:17             ` Kay Sievers
  0 siblings, 0 replies; 79+ messages in thread
From: Kay Sievers @ 2013-09-02 17:17 UTC (permalink / raw)
  To: Jan Kaluza
  Cc: davem, LKML, netdev, eparis, rgb, Tejun Heo, lizefan, containers,
	cgroups, viro

On Thu, Aug 29, 2013 at 4:13 PM, Jan Kaluza <jkaluza@redhat.com> wrote:
> Add new SCM type called SCM_CGROUP to send "cgroup_path" 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@redhat.com>

In many cases it's generally more useful to explain *why* something is
done, not *where* it is used. It makes it easier for people to match
the described problem to their own use-cases, where it possibly occurs
too. The problem this patch solves is very generic and not so much
specific to logging or the journal. Maybe something like this:

"Server-like processes in many cases need credentials and other
metadata of the peer, to decide if the calling process is allowed to
request a specific action, or the server just wants to log away this
type of information for auditing tasks.

The current practice to retrieve such process metadata is to look that
information up in procfs with the $PID received over SCM_CREDENTIALS.
This is sufficient for long-running tasks, but introduces a race which
cannot be worked around for short-living processes; the calling
process and all the information in /proc/$PID/ is gone before the
receiver of the socket message can look it up.

This introduces a new SCM type called SCM_CGROUP to allow the direct
attaching of "cgroup_path" to SCM, which is significantly more
efficient and will reliably avoid the race with the round-trip over
procfs."

Thanks,
Kay

^ permalink raw reply	[flat|nested] 79+ messages in thread

* [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message
  2013-08-27 14:39 [PATCH 0/3] Send audit/procinfo/cgroup data in socket-level control message Jan Kaluza
@ 2013-09-04  6:14     ` Jan Kaluza
  2013-08-27 14:39 ` [PATCH 2/3] Send comm and cmdline in SCM_PROCINFO Jan Kaluza
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluza @ 2013-09-04  6:14 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: Jan Kaluza, rgb-H+wXaHxf7aLQT0dZR+AlfA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, tj-DgEjT+Ai2ygdnm+yROfE0A,
	cgroups-u79uwXL29TY76Z2rM5mHXA

Hi,

this patchset against net-next (applies also to linux-next) adds 3 new types
of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).

Server-like processes in many cases need credentials and other
metadata of the peer, to decide if the calling process is allowed to
request a specific action, or the server just wants to log away this
type of information for auditing tasks.

The current practice to retrieve such process metadata is to look that
information up in procfs with the $PID received over SCM_CREDENTIALS.
This is sufficient for long-running tasks, but introduces a race which
cannot be worked around for short-living processes; the calling
process and all the information in /proc/$PID/ is gone before the
receiver of the socket message can look it up.

Changes introduced in this patchset can also increase performance
of such server-like processes, because current way of opening and
parsing /proc/$PID/* files is much more expensive than receiving these
metadata using SCM.

Changes in v3:
- Better description of patches (Thanks to Kay Sievers)

Changes in v2:
- use PATH_MAX instead of PAGE_SIZE in SCM_CGROUP patch
- describe each patch individually

Jan Kaluza (3):
  Send loginuid and sessionid in SCM_AUDIT
  Send comm and cmdline in SCM_PROCINFO
  Send cgroup_path in SCM_CGROUP

 include/linux/socket.h |  9 ++++++
 include/net/af_unix.h  | 10 ++++++
 include/net/scm.h      | 67 ++++++++++++++++++++++++++++++++++++++--
 net/core/scm.c         | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++
 net/unix/af_unix.c     | 70 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 237 insertions(+), 2 deletions(-)

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 79+ messages in thread

* [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message
@ 2013-09-04  6:14     ` Jan Kaluza
  0 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluza @ 2013-09-04  6:14 UTC (permalink / raw)
  To: davem
  Cc: LKML, netdev, eparis, rgb, tj, lizefan, containers, cgroups,
	viro, Jan Kaluza

Hi,

this patchset against net-next (applies also to linux-next) adds 3 new types
of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).

Server-like processes in many cases need credentials and other
metadata of the peer, to decide if the calling process is allowed to
request a specific action, or the server just wants to log away this
type of information for auditing tasks.

The current practice to retrieve such process metadata is to look that
information up in procfs with the $PID received over SCM_CREDENTIALS.
This is sufficient for long-running tasks, but introduces a race which
cannot be worked around for short-living processes; the calling
process and all the information in /proc/$PID/ is gone before the
receiver of the socket message can look it up.

Changes introduced in this patchset can also increase performance
of such server-like processes, because current way of opening and
parsing /proc/$PID/* files is much more expensive than receiving these
metadata using SCM.

Changes in v3:
- Better description of patches (Thanks to Kay Sievers)

Changes in v2:
- use PATH_MAX instead of PAGE_SIZE in SCM_CGROUP patch
- describe each patch individually

Jan Kaluza (3):
  Send loginuid and sessionid in SCM_AUDIT
  Send comm and cmdline in SCM_PROCINFO
  Send cgroup_path in SCM_CGROUP

 include/linux/socket.h |  9 ++++++
 include/net/af_unix.h  | 10 ++++++
 include/net/scm.h      | 67 ++++++++++++++++++++++++++++++++++++++--
 net/core/scm.c         | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++
 net/unix/af_unix.c     | 70 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 237 insertions(+), 2 deletions(-)

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 79+ messages in thread

* [PATCH v3 1/3] Send loginuid and sessionid in SCM_AUDIT
  2013-09-04  6:14     ` Jan Kaluza
@ 2013-09-04  6:14         ` Jan Kaluza
  -1 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluza @ 2013-09-04  6:14 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: Jan Kaluza, rgb-H+wXaHxf7aLQT0dZR+AlfA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, tj-DgEjT+Ai2ygdnm+yROfE0A,
	cgroups-u79uwXL29TY76Z2rM5mHXA

Server-like processes in many cases need credentials and other
metadata of the peer, to decide if the calling process is allowed to
request a specific action, or the server just wants to log away this
type of information for auditing tasks.

The current practice to retrieve such process metadata is to look that
information up in procfs with the $PID received over SCM_CREDENTIALS.
This is sufficient for long-running tasks, but introduces a race which
cannot be worked around for short-living processes; the calling
process and all the information in /proc/$PID/ is gone before the
receiver of the socket message can look it up.

This introduces a new SCM type called SCM_AUDIT to allow the direct
attaching of "loginuid" and "sessionid" to SCM, which is significantly more
efficient and will reliably avoid the race with the round-trip over
procfs.

Signed-off-by: Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 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

^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH v3 1/3] Send loginuid and sessionid in SCM_AUDIT
@ 2013-09-04  6:14         ` Jan Kaluza
  0 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluza @ 2013-09-04  6:14 UTC (permalink / raw)
  To: davem
  Cc: LKML, netdev, eparis, rgb, tj, lizefan, containers, cgroups,
	viro, Jan Kaluza

Server-like processes in many cases need credentials and other
metadata of the peer, to decide if the calling process is allowed to
request a specific action, or the server just wants to log away this
type of information for auditing tasks.

The current practice to retrieve such process metadata is to look that
information up in procfs with the $PID received over SCM_CREDENTIALS.
This is sufficient for long-running tasks, but introduces a race which
cannot be worked around for short-living processes; the calling
process and all the information in /proc/$PID/ is gone before the
receiver of the socket message can look it up.

This introduces a new SCM type called SCM_AUDIT to allow the direct
attaching of "loginuid" and "sessionid" to SCM, which is significantly more
efficient and will reliably avoid the race with the round-trip over
procfs.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
---
 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


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH v3 2/3] Send comm and cmdline in SCM_PROCINFO
  2013-09-04  6:14     ` Jan Kaluza
@ 2013-09-04  6:14         ` Jan Kaluza
  -1 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluza @ 2013-09-04  6:14 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: Jan Kaluza, rgb-H+wXaHxf7aLQT0dZR+AlfA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, tj-DgEjT+Ai2ygdnm+yROfE0A,
	cgroups-u79uwXL29TY76Z2rM5mHXA

Server-like processes in many cases need credentials and other
metadata of the peer, to decide if the calling process is allowed to
request a specific action, or the server just wants to log away this
type of information for auditing tasks.

The current practice to retrieve such process metadata is to look that
information up in procfs with the $PID received over SCM_CREDENTIALS.
This is sufficient for long-running tasks, but introduces a race which
cannot be worked around for short-living processes; the calling
process and all the information in /proc/$PID/ is gone before the
receiver of the socket message can look it up.

This introduces a new SCM type called SCM_PROCINFO to allow the direct
attaching of "comm" and "cmdline" to SCM, which is significantly more
efficient and will reliably avoid the race with the round-trip over
procfs.

To achieve that, new struct called unix_skb_parms_scm had to be created,
because otherwise unix_skb_parms would be too big.

scm_get_current_procinfo is inspired by ./fs/proc/base.c.

Signed-off-by: Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 include/linux/socket.h |  2 ++
 include/net/af_unix.h  | 11 +++++++--
 include/net/scm.h      | 24 +++++++++++++++++++
 net/core/scm.c         | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++
 net/unix/af_unix.c     | 57 +++++++++++++++++++++++++++++++++++++------
 5 files changed, 150 insertions(+), 9 deletions(-)

diff --git a/include/linux/socket.h b/include/linux/socket.h
index 505047a..6c7ace0 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -131,6 +131,8 @@ static inline struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr
 #define SCM_CREDENTIALS 0x02		/* rw: struct ucred		*/
 #define SCM_SECURITY	0x03		/* rw: security label		*/
 #define SCM_AUDIT	0x04		/* rw: struct uaudit		*/
+#define SCM_PROCINFO	0x05	/* rw: comm + cmdline (NULL terminated
+					   array of char *) */
 
 struct ucred {
 	__u32	pid;
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index 3b9d22a..05c7678 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -27,6 +27,13 @@ struct unix_address {
 	struct sockaddr_un name[0];
 };
 
+struct unix_skb_parms_scm {
+	kuid_t loginuid;
+	unsigned int sessionid;
+	char *procinfo;
+	int procinfo_len;
+};
+
 struct unix_skb_parms {
 	struct pid		*pid;		/* Skb credentials	*/
 	kuid_t			uid;
@@ -36,12 +43,12 @@ struct unix_skb_parms {
 	u32			secid;		/* Security ID		*/
 #endif
 	u32			consumed;
-	kuid_t			loginuid;
-	unsigned int		sessionid;
+	struct unix_skb_parms_scm *scm;
 };
 
 #define UNIXCB(skb) 	(*(struct unix_skb_parms *)&((skb)->cb))
 #define UNIXSID(skb)	(&UNIXCB((skb)).secid)
+#define UNIXSCM(skb)	(*(UNIXCB((skb)).scm))
 
 #define unix_state_lock(s)	spin_lock(&unix_sk(s)->lock)
 #define unix_state_unlock(s)	spin_unlock(&unix_sk(s)->lock)
diff --git a/include/net/scm.h b/include/net/scm.h
index e349a25..3346030 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -30,11 +30,17 @@ struct scm_fp_list {
 	struct file		*fp[SCM_MAX_FD];
 };
 
+struct scm_procinfo {
+	char *procinfo;
+	int len;
+};
+
 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	*/
+	struct scm_procinfo	procinfo;	/* Skb procinfo */
 #ifdef CONFIG_SECURITY_NETWORK
 	u32			secid;		/* Passed security ID 	*/
 #endif
@@ -45,6 +51,7 @@ extern void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm);
 extern int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm);
 extern void __scm_destroy(struct scm_cookie *scm);
 extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl);
+extern int scm_get_current_procinfo(char **procinfo);
 
 #ifdef CONFIG_SECURITY_NETWORK
 static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
@@ -72,10 +79,20 @@ static inline void scm_set_audit(struct scm_cookie *scm,
 	scm->audit.sessionid = sessionid;
 }
 
+static inline void scm_set_procinfo(struct scm_cookie *scm,
+				    char *procinfo, int len)
+{
+	scm->procinfo.procinfo = procinfo;
+	scm->procinfo.len = len;
+}
+
 static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
 {
 	put_pid(scm->pid);
 	scm->pid  = NULL;
+	kfree(scm->procinfo.procinfo);
+	scm->procinfo.procinfo = NULL;
+	scm->procinfo.len = 0;
 }
 
 static __inline__ void scm_destroy(struct scm_cookie *scm)
@@ -88,6 +105,8 @@ static __inline__ void scm_destroy(struct scm_cookie *scm)
 static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
 			       struct scm_cookie *scm, bool forcecreds)
 {
+	char *procinfo;
+	int len;
 	memset(scm, 0, sizeof(*scm));
 	scm->creds.uid = INVALID_UID;
 	scm->creds.gid = INVALID_GID;
@@ -96,6 +115,9 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
 			     current_gid());
 		scm_set_audit(scm, audit_get_loginuid(current),
 			      audit_get_sessionid(current));
+		len = scm_get_current_procinfo(&procinfo);
+		if (len > 0)
+			scm_set_procinfo(scm, procinfo, len);
 	}
 	unix_get_peersec_dgram(sock, scm);
 	if (msg->msg_controllen <= 0)
@@ -148,6 +170,8 @@ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
 		};
 		put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(ucreds), &ucreds);
 		put_cmsg(msg, SOL_SOCKET, SCM_AUDIT, sizeof(uaudits), &uaudits);
+		put_cmsg(msg, SOL_SOCKET, SCM_PROCINFO, scm->procinfo.len,
+				 scm->procinfo.procinfo);
 	}
 
 	scm_destroy_cred(scm);
diff --git a/net/core/scm.c b/net/core/scm.c
index 03795d0..09ec044 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -339,3 +339,68 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)
 	return new_fpl;
 }
 EXPORT_SYMBOL(scm_fp_dup);
+
+int scm_get_current_procinfo(char **procinfo)
+{
+	int res = 0;
+	unsigned int len;
+	char *buffer = NULL;
+	struct mm_struct *mm;
+	int comm_len = strlen(current->comm);
+
+	*procinfo = NULL;
+
+	buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	mm = get_task_mm(current);
+	if (!mm)
+		goto out;
+	if (!mm->arg_end)
+		goto out_mm;    /* Shh! No looking before we're done */
+
+	len = mm->arg_end - mm->arg_start;
+
+	if (len > PAGE_SIZE)
+		len = PAGE_SIZE;
+
+	res = access_process_vm(current, mm->arg_start, buffer, len, 0);
+
+	/* If the nul at the end of args has been overwritten, then
+	 * assume application is using setproctitle(3).
+	 */
+	if (res > 0 && buffer[res-1] != '\0' && len < PAGE_SIZE) {
+		len = strnlen(buffer, res);
+		if (len < res) {
+			res = len;
+		} else {
+			len = mm->env_end - mm->env_start;
+			if (len > PAGE_SIZE - res)
+				len = PAGE_SIZE - res;
+			res += access_process_vm(current, mm->env_start,
+						 buffer+res, len, 0);
+			res = strnlen(buffer, res);
+		}
+	}
+
+	/* strlen(comm) + \0 + len of cmdline */
+	len = comm_len + 1 + res;
+	*procinfo = kmalloc(len, GFP_KERNEL);
+	if (!*procinfo) {
+		res = -ENOMEM;
+		goto out_mm;
+	}
+
+	memcpy(*procinfo, current->comm, comm_len + 1); /* include \0 */
+	if (res > 0)
+		memcpy(*procinfo + comm_len + 1, buffer, res);
+	res = len;
+
+out_mm:
+	mmput(mm);
+out:
+	kfree(buffer);
+	return res;
+}
+EXPORT_SYMBOL(scm_get_current_procinfo);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index c410f76..ab0be13 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1341,9 +1341,14 @@ static void unix_destruct_scm(struct sk_buff *skb)
 	struct scm_cookie scm;
 	memset(&scm, 0, sizeof(scm));
 	scm.pid  = UNIXCB(skb).pid;
+	if (UNIXCB(skb).scm) {
+		scm.procinfo.procinfo = UNIXSCM(skb).procinfo;
+		scm.procinfo.len = UNIXSCM(skb).procinfo_len;
+	}
 	if (UNIXCB(skb).fp)
 		unix_detach_fds(&scm, skb);
 
+	kfree(UNIXCB(skb).scm);
 	/* Alas, it calls VFS */
 	/* So fscking what? fput() had been SMP-safe since the last Summer */
 	scm_destroy(&scm);
@@ -1390,15 +1395,31 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen
 {
 	int err = 0;
 
+	if (!UNIXCB(skb).scm) {
+		UNIXCB(skb).scm = kmalloc(sizeof(struct unix_skb_parms_scm),
+					  GFP_KERNEL);
+		if (!UNIXCB(skb).scm)
+			return -ENOMEM;
+	}
+
 	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;
+	UNIXSCM(skb).loginuid = scm->audit.loginuid;
+	UNIXSCM(skb).sessionid = scm->audit.sessionid;
 	UNIXCB(skb).fp = NULL;
 	if (scm->fp && send_fds)
 		err = unix_attach_fds(scm, skb);
 
+	UNIXSCM(skb).procinfo = NULL;
+	if (scm->procinfo.procinfo) {
+		UNIXSCM(skb).procinfo_len = scm->procinfo.len;
+		UNIXSCM(skb).procinfo = kmemdup(scm->procinfo.procinfo,
+					scm->procinfo.len, GFP_KERNEL);
+		if (!UNIXSCM(skb).procinfo)
+			return -ENOMEM;
+	}
+
 	skb->destructor = unix_destruct_scm;
 	return err;
 }
@@ -1418,8 +1439,10 @@ 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);
+		UNIXSCM(skb).loginuid = audit_get_loginuid(current);
+		UNIXSCM(skb).sessionid = audit_get_sessionid(current);
+		UNIXSCM(skb).procinfo_len = scm_get_current_procinfo(
+			&UNIXSCM(skb).procinfo);
 	}
 }
 
@@ -1816,7 +1839,17 @@ 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);
+	if (UNIXCB(skb).scm) {
+		scm_set_audit(siocb->scm, UNIXSCM(skb).loginuid,
+			      UNIXSCM(skb).sessionid);
+		if (UNIXSCM(skb).procinfo) {
+			scm_set_procinfo(siocb->scm,
+					 kmemdup(UNIXSCM(skb).procinfo,
+						 UNIXSCM(skb).procinfo_len,
+						 GFP_KERNEL),
+					 UNIXSCM(skb).procinfo_len);
+		}
+	}
 	unix_set_secdata(siocb->scm, skb);
 
 	if (!(flags & MSG_PEEK)) {
@@ -1998,8 +2031,18 @@ 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);
+			if (UNIXCB(skb).scm) {
+				scm_set_audit(siocb->scm,
+					      UNIXSCM(skb).loginuid,
+					      UNIXSCM(skb).sessionid);
+				if (UNIXSCM(skb).procinfo) {
+					scm_set_procinfo(siocb->scm,
+						kmemdup(UNIXSCM(skb).procinfo,
+						UNIXSCM(skb).procinfo_len,
+						GFP_KERNEL),
+						UNIXSCM(skb).procinfo_len);
+				}
+			}
 			check_creds = 1;
 		}
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH v3 2/3] Send comm and cmdline in SCM_PROCINFO
@ 2013-09-04  6:14         ` Jan Kaluza
  0 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluza @ 2013-09-04  6:14 UTC (permalink / raw)
  To: davem
  Cc: LKML, netdev, eparis, rgb, tj, lizefan, containers, cgroups,
	viro, Jan Kaluza

Server-like processes in many cases need credentials and other
metadata of the peer, to decide if the calling process is allowed to
request a specific action, or the server just wants to log away this
type of information for auditing tasks.

The current practice to retrieve such process metadata is to look that
information up in procfs with the $PID received over SCM_CREDENTIALS.
This is sufficient for long-running tasks, but introduces a race which
cannot be worked around for short-living processes; the calling
process and all the information in /proc/$PID/ is gone before the
receiver of the socket message can look it up.

This introduces a new SCM type called SCM_PROCINFO to allow the direct
attaching of "comm" and "cmdline" to SCM, which is significantly more
efficient and will reliably avoid the race with the round-trip over
procfs.

To achieve that, new struct called unix_skb_parms_scm had to be created,
because otherwise unix_skb_parms would be too big.

scm_get_current_procinfo is inspired by ./fs/proc/base.c.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
---
 include/linux/socket.h |  2 ++
 include/net/af_unix.h  | 11 +++++++--
 include/net/scm.h      | 24 +++++++++++++++++++
 net/core/scm.c         | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++
 net/unix/af_unix.c     | 57 +++++++++++++++++++++++++++++++++++++------
 5 files changed, 150 insertions(+), 9 deletions(-)

diff --git a/include/linux/socket.h b/include/linux/socket.h
index 505047a..6c7ace0 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -131,6 +131,8 @@ static inline struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr
 #define SCM_CREDENTIALS 0x02		/* rw: struct ucred		*/
 #define SCM_SECURITY	0x03		/* rw: security label		*/
 #define SCM_AUDIT	0x04		/* rw: struct uaudit		*/
+#define SCM_PROCINFO	0x05	/* rw: comm + cmdline (NULL terminated
+					   array of char *) */
 
 struct ucred {
 	__u32	pid;
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index 3b9d22a..05c7678 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -27,6 +27,13 @@ struct unix_address {
 	struct sockaddr_un name[0];
 };
 
+struct unix_skb_parms_scm {
+	kuid_t loginuid;
+	unsigned int sessionid;
+	char *procinfo;
+	int procinfo_len;
+};
+
 struct unix_skb_parms {
 	struct pid		*pid;		/* Skb credentials	*/
 	kuid_t			uid;
@@ -36,12 +43,12 @@ struct unix_skb_parms {
 	u32			secid;		/* Security ID		*/
 #endif
 	u32			consumed;
-	kuid_t			loginuid;
-	unsigned int		sessionid;
+	struct unix_skb_parms_scm *scm;
 };
 
 #define UNIXCB(skb) 	(*(struct unix_skb_parms *)&((skb)->cb))
 #define UNIXSID(skb)	(&UNIXCB((skb)).secid)
+#define UNIXSCM(skb)	(*(UNIXCB((skb)).scm))
 
 #define unix_state_lock(s)	spin_lock(&unix_sk(s)->lock)
 #define unix_state_unlock(s)	spin_unlock(&unix_sk(s)->lock)
diff --git a/include/net/scm.h b/include/net/scm.h
index e349a25..3346030 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -30,11 +30,17 @@ struct scm_fp_list {
 	struct file		*fp[SCM_MAX_FD];
 };
 
+struct scm_procinfo {
+	char *procinfo;
+	int len;
+};
+
 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	*/
+	struct scm_procinfo	procinfo;	/* Skb procinfo */
 #ifdef CONFIG_SECURITY_NETWORK
 	u32			secid;		/* Passed security ID 	*/
 #endif
@@ -45,6 +51,7 @@ extern void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm);
 extern int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm);
 extern void __scm_destroy(struct scm_cookie *scm);
 extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl);
+extern int scm_get_current_procinfo(char **procinfo);
 
 #ifdef CONFIG_SECURITY_NETWORK
 static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
@@ -72,10 +79,20 @@ static inline void scm_set_audit(struct scm_cookie *scm,
 	scm->audit.sessionid = sessionid;
 }
 
+static inline void scm_set_procinfo(struct scm_cookie *scm,
+				    char *procinfo, int len)
+{
+	scm->procinfo.procinfo = procinfo;
+	scm->procinfo.len = len;
+}
+
 static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
 {
 	put_pid(scm->pid);
 	scm->pid  = NULL;
+	kfree(scm->procinfo.procinfo);
+	scm->procinfo.procinfo = NULL;
+	scm->procinfo.len = 0;
 }
 
 static __inline__ void scm_destroy(struct scm_cookie *scm)
@@ -88,6 +105,8 @@ static __inline__ void scm_destroy(struct scm_cookie *scm)
 static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
 			       struct scm_cookie *scm, bool forcecreds)
 {
+	char *procinfo;
+	int len;
 	memset(scm, 0, sizeof(*scm));
 	scm->creds.uid = INVALID_UID;
 	scm->creds.gid = INVALID_GID;
@@ -96,6 +115,9 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
 			     current_gid());
 		scm_set_audit(scm, audit_get_loginuid(current),
 			      audit_get_sessionid(current));
+		len = scm_get_current_procinfo(&procinfo);
+		if (len > 0)
+			scm_set_procinfo(scm, procinfo, len);
 	}
 	unix_get_peersec_dgram(sock, scm);
 	if (msg->msg_controllen <= 0)
@@ -148,6 +170,8 @@ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
 		};
 		put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(ucreds), &ucreds);
 		put_cmsg(msg, SOL_SOCKET, SCM_AUDIT, sizeof(uaudits), &uaudits);
+		put_cmsg(msg, SOL_SOCKET, SCM_PROCINFO, scm->procinfo.len,
+				 scm->procinfo.procinfo);
 	}
 
 	scm_destroy_cred(scm);
diff --git a/net/core/scm.c b/net/core/scm.c
index 03795d0..09ec044 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -339,3 +339,68 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)
 	return new_fpl;
 }
 EXPORT_SYMBOL(scm_fp_dup);
+
+int scm_get_current_procinfo(char **procinfo)
+{
+	int res = 0;
+	unsigned int len;
+	char *buffer = NULL;
+	struct mm_struct *mm;
+	int comm_len = strlen(current->comm);
+
+	*procinfo = NULL;
+
+	buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	mm = get_task_mm(current);
+	if (!mm)
+		goto out;
+	if (!mm->arg_end)
+		goto out_mm;    /* Shh! No looking before we're done */
+
+	len = mm->arg_end - mm->arg_start;
+
+	if (len > PAGE_SIZE)
+		len = PAGE_SIZE;
+
+	res = access_process_vm(current, mm->arg_start, buffer, len, 0);
+
+	/* If the nul at the end of args has been overwritten, then
+	 * assume application is using setproctitle(3).
+	 */
+	if (res > 0 && buffer[res-1] != '\0' && len < PAGE_SIZE) {
+		len = strnlen(buffer, res);
+		if (len < res) {
+			res = len;
+		} else {
+			len = mm->env_end - mm->env_start;
+			if (len > PAGE_SIZE - res)
+				len = PAGE_SIZE - res;
+			res += access_process_vm(current, mm->env_start,
+						 buffer+res, len, 0);
+			res = strnlen(buffer, res);
+		}
+	}
+
+	/* strlen(comm) + \0 + len of cmdline */
+	len = comm_len + 1 + res;
+	*procinfo = kmalloc(len, GFP_KERNEL);
+	if (!*procinfo) {
+		res = -ENOMEM;
+		goto out_mm;
+	}
+
+	memcpy(*procinfo, current->comm, comm_len + 1); /* include \0 */
+	if (res > 0)
+		memcpy(*procinfo + comm_len + 1, buffer, res);
+	res = len;
+
+out_mm:
+	mmput(mm);
+out:
+	kfree(buffer);
+	return res;
+}
+EXPORT_SYMBOL(scm_get_current_procinfo);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index c410f76..ab0be13 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1341,9 +1341,14 @@ static void unix_destruct_scm(struct sk_buff *skb)
 	struct scm_cookie scm;
 	memset(&scm, 0, sizeof(scm));
 	scm.pid  = UNIXCB(skb).pid;
+	if (UNIXCB(skb).scm) {
+		scm.procinfo.procinfo = UNIXSCM(skb).procinfo;
+		scm.procinfo.len = UNIXSCM(skb).procinfo_len;
+	}
 	if (UNIXCB(skb).fp)
 		unix_detach_fds(&scm, skb);
 
+	kfree(UNIXCB(skb).scm);
 	/* Alas, it calls VFS */
 	/* So fscking what? fput() had been SMP-safe since the last Summer */
 	scm_destroy(&scm);
@@ -1390,15 +1395,31 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen
 {
 	int err = 0;
 
+	if (!UNIXCB(skb).scm) {
+		UNIXCB(skb).scm = kmalloc(sizeof(struct unix_skb_parms_scm),
+					  GFP_KERNEL);
+		if (!UNIXCB(skb).scm)
+			return -ENOMEM;
+	}
+
 	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;
+	UNIXSCM(skb).loginuid = scm->audit.loginuid;
+	UNIXSCM(skb).sessionid = scm->audit.sessionid;
 	UNIXCB(skb).fp = NULL;
 	if (scm->fp && send_fds)
 		err = unix_attach_fds(scm, skb);
 
+	UNIXSCM(skb).procinfo = NULL;
+	if (scm->procinfo.procinfo) {
+		UNIXSCM(skb).procinfo_len = scm->procinfo.len;
+		UNIXSCM(skb).procinfo = kmemdup(scm->procinfo.procinfo,
+					scm->procinfo.len, GFP_KERNEL);
+		if (!UNIXSCM(skb).procinfo)
+			return -ENOMEM;
+	}
+
 	skb->destructor = unix_destruct_scm;
 	return err;
 }
@@ -1418,8 +1439,10 @@ 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);
+		UNIXSCM(skb).loginuid = audit_get_loginuid(current);
+		UNIXSCM(skb).sessionid = audit_get_sessionid(current);
+		UNIXSCM(skb).procinfo_len = scm_get_current_procinfo(
+			&UNIXSCM(skb).procinfo);
 	}
 }
 
@@ -1816,7 +1839,17 @@ 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);
+	if (UNIXCB(skb).scm) {
+		scm_set_audit(siocb->scm, UNIXSCM(skb).loginuid,
+			      UNIXSCM(skb).sessionid);
+		if (UNIXSCM(skb).procinfo) {
+			scm_set_procinfo(siocb->scm,
+					 kmemdup(UNIXSCM(skb).procinfo,
+						 UNIXSCM(skb).procinfo_len,
+						 GFP_KERNEL),
+					 UNIXSCM(skb).procinfo_len);
+		}
+	}
 	unix_set_secdata(siocb->scm, skb);
 
 	if (!(flags & MSG_PEEK)) {
@@ -1998,8 +2031,18 @@ 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);
+			if (UNIXCB(skb).scm) {
+				scm_set_audit(siocb->scm,
+					      UNIXSCM(skb).loginuid,
+					      UNIXSCM(skb).sessionid);
+				if (UNIXSCM(skb).procinfo) {
+					scm_set_procinfo(siocb->scm,
+						kmemdup(UNIXSCM(skb).procinfo,
+						UNIXSCM(skb).procinfo_len,
+						GFP_KERNEL),
+						UNIXSCM(skb).procinfo_len);
+				}
+			}
 			check_creds = 1;
 		}
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH v3 3/3] Send cgroup_path in SCM_CGROUP
       [not found]     ` <1378275261-4553-1-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
  2013-09-04  6:14         ` Jan Kaluza
  2013-09-04  6:14         ` Jan Kaluza
@ 2013-09-04  6:14       ` Jan Kaluza
  2013-09-04  7:42       ` [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message Eric W. Biederman
  3 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluza @ 2013-09-04  6:14 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: Jan Kaluza, rgb-H+wXaHxf7aLQT0dZR+AlfA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, tj-DgEjT+Ai2ygdnm+yROfE0A,
	cgroups-u79uwXL29TY76Z2rM5mHXA

Server-like processes in many cases need credentials and other
metadata of the peer, to decide if the calling process is allowed to
request a specific action, or the server just wants to log away this
type of information for auditing tasks.

The current practice to retrieve such process metadata is to look that
information up in procfs with the $PID received over SCM_CREDENTIALS.
This is sufficient for long-running tasks, but introduces a race which
cannot be worked around for short-living processes; the calling
process and all the information in /proc/$PID/ is gone before the
receiver of the socket message can look it up.

This introduces a new SCM type called SCM_CGROUP to allow the direct
attaching of "cgroup_path" to SCM, which is significantly more
efficient and will reliably avoid the race with the round-trip over
procfs.

Signed-off-by: Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 include/linux/socket.h |  1 +
 include/net/af_unix.h  |  1 +
 include/net/scm.h      | 15 +++++++++++++++
 net/core/scm.c         | 18 ++++++++++++++++++
 net/unix/af_unix.c     | 20 ++++++++++++++++++++
 5 files changed, 55 insertions(+)

diff --git a/include/linux/socket.h b/include/linux/socket.h
index 6c7ace0..621fff1 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -133,6 +133,7 @@ static inline struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr
 #define SCM_AUDIT	0x04		/* rw: struct uaudit		*/
 #define SCM_PROCINFO	0x05	/* rw: comm + cmdline (NULL terminated
 					   array of char *) */
+#define SCM_CGROUP	0x06		/* rw: cgroup path */
 
 struct ucred {
 	__u32	pid;
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index 05c7678..c49bf35 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -32,6 +32,7 @@ struct unix_skb_parms_scm {
 	unsigned int sessionid;
 	char *procinfo;
 	int procinfo_len;
+	char *cgroup_path;
 };
 
 struct unix_skb_parms {
diff --git a/include/net/scm.h b/include/net/scm.h
index 3346030..5398826 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -41,6 +41,7 @@ struct scm_cookie {
 	struct scm_creds	creds;		/* Skb credentials	*/
 	struct scm_audit	audit;		/* Skb audit	*/
 	struct scm_procinfo	procinfo;	/* Skb procinfo */
+	char *cgroup_path;
 #ifdef CONFIG_SECURITY_NETWORK
 	u32			secid;		/* Passed security ID 	*/
 #endif
@@ -52,6 +53,7 @@ extern int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie
 extern void __scm_destroy(struct scm_cookie *scm);
 extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl);
 extern int scm_get_current_procinfo(char **procinfo);
+extern int scm_get_current_cgroup_path(char **cgroup_path);
 
 #ifdef CONFIG_SECURITY_NETWORK
 static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
@@ -86,6 +88,12 @@ static inline void scm_set_procinfo(struct scm_cookie *scm,
 	scm->procinfo.len = len;
 }
 
+static inline void scm_set_cgroup_path(struct scm_cookie *scm,
+				    char *cgroup_path)
+{
+	scm->cgroup_path = cgroup_path;
+}
+
 static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
 {
 	put_pid(scm->pid);
@@ -140,6 +148,9 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc
 			security_release_secctx(secdata, seclen);
 		}
 	}
+
+	kfree(scm->cgroup_path);
+	scm->cgroup_path = NULL;
 }
 #else
 static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
@@ -172,6 +183,10 @@ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
 		put_cmsg(msg, SOL_SOCKET, SCM_AUDIT, sizeof(uaudits), &uaudits);
 		put_cmsg(msg, SOL_SOCKET, SCM_PROCINFO, scm->procinfo.len,
 				 scm->procinfo.procinfo);
+		if (scm->cgroup_path) {
+			put_cmsg(msg, SOL_SOCKET, SCM_CGROUP,
+				 strlen(scm->cgroup_path), scm->cgroup_path);
+		}
 	}
 
 	scm_destroy_cred(scm);
diff --git a/net/core/scm.c b/net/core/scm.c
index 09ec044..2d408b9 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -404,3 +404,21 @@ out:
 	return res;
 }
 EXPORT_SYMBOL(scm_get_current_procinfo);
+
+int scm_get_current_cgroup_path(char **cgroup_path)
+{
+	int ret = 0;
+
+	*cgroup_path = kmalloc(PATH_MAX, GFP_KERNEL);
+	if (!(*cgroup_path))
+		return -ENOMEM;
+
+	ret = task_cgroup_path(current, *cgroup_path, PATH_MAX);
+	if (ret < 0) {
+		kfree(*cgroup_path);
+		*cgroup_path = NULL;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(scm_get_current_cgroup_path);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index ab0be13..b638083 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1344,6 +1344,7 @@ static void unix_destruct_scm(struct sk_buff *skb)
 	if (UNIXCB(skb).scm) {
 		scm.procinfo.procinfo = UNIXSCM(skb).procinfo;
 		scm.procinfo.len = UNIXSCM(skb).procinfo_len;
+		scm.cgroup_path = UNIXSCM(skb).cgroup_path;
 	}
 	if (UNIXCB(skb).fp)
 		unix_detach_fds(&scm, skb);
@@ -1420,6 +1421,14 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen
 			return -ENOMEM;
 	}
 
+	UNIXSCM(skb).cgroup_path = NULL;
+	if (scm->cgroup_path) {
+		UNIXSCM(skb).cgroup_path = kstrdup(scm->cgroup_path,
+						   GFP_KERNEL);
+		if (!UNIXSCM(skb).cgroup_path)
+			return -ENOMEM;
+	}
+
 	skb->destructor = unix_destruct_scm;
 	return err;
 }
@@ -1443,6 +1452,7 @@ static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
 		UNIXSCM(skb).sessionid = audit_get_sessionid(current);
 		UNIXSCM(skb).procinfo_len = scm_get_current_procinfo(
 			&UNIXSCM(skb).procinfo);
+		scm_get_current_cgroup_path(&UNIXSCM(skb).cgroup_path);
 	}
 }
 
@@ -1849,6 +1859,11 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
 						 GFP_KERNEL),
 					 UNIXSCM(skb).procinfo_len);
 		}
+		if (UNIXSCM(skb).cgroup_path) {
+			scm_set_cgroup_path(siocb->scm,
+					    kstrdup(UNIXSCM(skb).cgroup_path,
+						    GFP_KERNEL));
+		}
 	}
 	unix_set_secdata(siocb->scm, skb);
 
@@ -2042,6 +2057,11 @@ again:
 						GFP_KERNEL),
 						UNIXSCM(skb).procinfo_len);
 				}
+				if (UNIXSCM(skb).cgroup_path) {
+					scm_set_cgroup_path(siocb->scm,
+							    kstrdup(UNIXSCM(skb).cgroup_path,
+							    GFP_KERNEL));
+				}
 			}
 			check_creds = 1;
 		}
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH v3 3/3] Send cgroup_path in SCM_CGROUP
  2013-09-04  6:14     ` Jan Kaluza
  (?)
  (?)
@ 2013-09-04  6:14     ` Jan Kaluza
  -1 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluza @ 2013-09-04  6:14 UTC (permalink / raw)
  To: davem
  Cc: LKML, netdev, eparis, rgb, tj, lizefan, containers, cgroups,
	viro, Jan Kaluza

Server-like processes in many cases need credentials and other
metadata of the peer, to decide if the calling process is allowed to
request a specific action, or the server just wants to log away this
type of information for auditing tasks.

The current practice to retrieve such process metadata is to look that
information up in procfs with the $PID received over SCM_CREDENTIALS.
This is sufficient for long-running tasks, but introduces a race which
cannot be worked around for short-living processes; the calling
process and all the information in /proc/$PID/ is gone before the
receiver of the socket message can look it up.

This introduces a new SCM type called SCM_CGROUP to allow the direct
attaching of "cgroup_path" to SCM, which is significantly more
efficient and will reliably avoid the race with the round-trip over
procfs.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
---
 include/linux/socket.h |  1 +
 include/net/af_unix.h  |  1 +
 include/net/scm.h      | 15 +++++++++++++++
 net/core/scm.c         | 18 ++++++++++++++++++
 net/unix/af_unix.c     | 20 ++++++++++++++++++++
 5 files changed, 55 insertions(+)

diff --git a/include/linux/socket.h b/include/linux/socket.h
index 6c7ace0..621fff1 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -133,6 +133,7 @@ static inline struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr
 #define SCM_AUDIT	0x04		/* rw: struct uaudit		*/
 #define SCM_PROCINFO	0x05	/* rw: comm + cmdline (NULL terminated
 					   array of char *) */
+#define SCM_CGROUP	0x06		/* rw: cgroup path */
 
 struct ucred {
 	__u32	pid;
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index 05c7678..c49bf35 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -32,6 +32,7 @@ struct unix_skb_parms_scm {
 	unsigned int sessionid;
 	char *procinfo;
 	int procinfo_len;
+	char *cgroup_path;
 };
 
 struct unix_skb_parms {
diff --git a/include/net/scm.h b/include/net/scm.h
index 3346030..5398826 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -41,6 +41,7 @@ struct scm_cookie {
 	struct scm_creds	creds;		/* Skb credentials	*/
 	struct scm_audit	audit;		/* Skb audit	*/
 	struct scm_procinfo	procinfo;	/* Skb procinfo */
+	char *cgroup_path;
 #ifdef CONFIG_SECURITY_NETWORK
 	u32			secid;		/* Passed security ID 	*/
 #endif
@@ -52,6 +53,7 @@ extern int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie
 extern void __scm_destroy(struct scm_cookie *scm);
 extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl);
 extern int scm_get_current_procinfo(char **procinfo);
+extern int scm_get_current_cgroup_path(char **cgroup_path);
 
 #ifdef CONFIG_SECURITY_NETWORK
 static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
@@ -86,6 +88,12 @@ static inline void scm_set_procinfo(struct scm_cookie *scm,
 	scm->procinfo.len = len;
 }
 
+static inline void scm_set_cgroup_path(struct scm_cookie *scm,
+				    char *cgroup_path)
+{
+	scm->cgroup_path = cgroup_path;
+}
+
 static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
 {
 	put_pid(scm->pid);
@@ -140,6 +148,9 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc
 			security_release_secctx(secdata, seclen);
 		}
 	}
+
+	kfree(scm->cgroup_path);
+	scm->cgroup_path = NULL;
 }
 #else
 static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
@@ -172,6 +183,10 @@ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
 		put_cmsg(msg, SOL_SOCKET, SCM_AUDIT, sizeof(uaudits), &uaudits);
 		put_cmsg(msg, SOL_SOCKET, SCM_PROCINFO, scm->procinfo.len,
 				 scm->procinfo.procinfo);
+		if (scm->cgroup_path) {
+			put_cmsg(msg, SOL_SOCKET, SCM_CGROUP,
+				 strlen(scm->cgroup_path), scm->cgroup_path);
+		}
 	}
 
 	scm_destroy_cred(scm);
diff --git a/net/core/scm.c b/net/core/scm.c
index 09ec044..2d408b9 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -404,3 +404,21 @@ out:
 	return res;
 }
 EXPORT_SYMBOL(scm_get_current_procinfo);
+
+int scm_get_current_cgroup_path(char **cgroup_path)
+{
+	int ret = 0;
+
+	*cgroup_path = kmalloc(PATH_MAX, GFP_KERNEL);
+	if (!(*cgroup_path))
+		return -ENOMEM;
+
+	ret = task_cgroup_path(current, *cgroup_path, PATH_MAX);
+	if (ret < 0) {
+		kfree(*cgroup_path);
+		*cgroup_path = NULL;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(scm_get_current_cgroup_path);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index ab0be13..b638083 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1344,6 +1344,7 @@ static void unix_destruct_scm(struct sk_buff *skb)
 	if (UNIXCB(skb).scm) {
 		scm.procinfo.procinfo = UNIXSCM(skb).procinfo;
 		scm.procinfo.len = UNIXSCM(skb).procinfo_len;
+		scm.cgroup_path = UNIXSCM(skb).cgroup_path;
 	}
 	if (UNIXCB(skb).fp)
 		unix_detach_fds(&scm, skb);
@@ -1420,6 +1421,14 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen
 			return -ENOMEM;
 	}
 
+	UNIXSCM(skb).cgroup_path = NULL;
+	if (scm->cgroup_path) {
+		UNIXSCM(skb).cgroup_path = kstrdup(scm->cgroup_path,
+						   GFP_KERNEL);
+		if (!UNIXSCM(skb).cgroup_path)
+			return -ENOMEM;
+	}
+
 	skb->destructor = unix_destruct_scm;
 	return err;
 }
@@ -1443,6 +1452,7 @@ static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
 		UNIXSCM(skb).sessionid = audit_get_sessionid(current);
 		UNIXSCM(skb).procinfo_len = scm_get_current_procinfo(
 			&UNIXSCM(skb).procinfo);
+		scm_get_current_cgroup_path(&UNIXSCM(skb).cgroup_path);
 	}
 }
 
@@ -1849,6 +1859,11 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
 						 GFP_KERNEL),
 					 UNIXSCM(skb).procinfo_len);
 		}
+		if (UNIXSCM(skb).cgroup_path) {
+			scm_set_cgroup_path(siocb->scm,
+					    kstrdup(UNIXSCM(skb).cgroup_path,
+						    GFP_KERNEL));
+		}
 	}
 	unix_set_secdata(siocb->scm, skb);
 
@@ -2042,6 +2057,11 @@ again:
 						GFP_KERNEL),
 						UNIXSCM(skb).procinfo_len);
 				}
+				if (UNIXSCM(skb).cgroup_path) {
+					scm_set_cgroup_path(siocb->scm,
+							    kstrdup(UNIXSCM(skb).cgroup_path,
+							    GFP_KERNEL));
+				}
 			}
 			check_creds = 1;
 		}
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* Re: [PATCH v3 1/3] Send loginuid and sessionid in SCM_AUDIT
       [not found]         ` <1378275261-4553-2-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
@ 2013-09-04  7:22           ` Eric W. Biederman
  0 siblings, 0 replies; 79+ messages in thread
From: Eric W. Biederman @ 2013-09-04  7:22 UTC (permalink / raw)
  To: Jan Kaluza
  Cc: rgb-H+wXaHxf7aLQT0dZR+AlfA, netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, tj-DgEjT+Ai2ygdnm+yROfE0A,
	cgroups-u79uwXL29TY76Z2rM5mHXA, davem-fT/PcQaiUtIeIZ0/mPfg9Q

Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> writes:

> Server-like processes in many cases need credentials and other
> metadata of the peer, to decide if the calling process is allowed to
> request a specific action, or the server just wants to log away this
> type of information for auditing tasks.
>
> The current practice to retrieve such process metadata is to look that
> information up in procfs with the $PID received over SCM_CREDENTIALS.
> This is sufficient for long-running tasks, but introduces a race which
> cannot be worked around for short-living processes; the calling
> process and all the information in /proc/$PID/ is gone before the
> receiver of the socket message can look it up.
>
> This introduces a new SCM type called SCM_AUDIT to allow the direct
> attaching of "loginuid" and "sessionid" to SCM, which is significantly more
> efficient and will reliably avoid the race with the round-trip over
> procfs.

Unless I am misreading something this patch will break the build if
CONFIG_AUDITSYSCALL is not defined.

Eric


> Signed-off-by: Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---
>  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;
>  		}

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v3 1/3] Send loginuid and sessionid in SCM_AUDIT
       [not found]         ` <1378275261-4553-2-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
@ 2013-09-04  7:22           ` Eric W. Biederman
  0 siblings, 0 replies; 79+ messages in thread
From: Eric W. Biederman @ 2013-09-04  7:22 UTC (permalink / raw)
  To: Jan Kaluza
  Cc: davem, LKML, netdev, eparis, rgb, tj, lizefan, containers, cgroups, viro

Jan Kaluza <jkaluza@redhat.com> writes:

> Server-like processes in many cases need credentials and other
> metadata of the peer, to decide if the calling process is allowed to
> request a specific action, or the server just wants to log away this
> type of information for auditing tasks.
>
> The current practice to retrieve such process metadata is to look that
> information up in procfs with the $PID received over SCM_CREDENTIALS.
> This is sufficient for long-running tasks, but introduces a race which
> cannot be worked around for short-living processes; the calling
> process and all the information in /proc/$PID/ is gone before the
> receiver of the socket message can look it up.
>
> This introduces a new SCM type called SCM_AUDIT to allow the direct
> attaching of "loginuid" and "sessionid" to SCM, which is significantly more
> efficient and will reliably avoid the race with the round-trip over
> procfs.

Unless I am misreading something this patch will break the build if
CONFIG_AUDITSYSCALL is not defined.

Eric


> Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
> ---
>  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;
>  		}

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v3 1/3] Send loginuid and sessionid in SCM_AUDIT
@ 2013-09-04  7:22           ` Eric W. Biederman
  0 siblings, 0 replies; 79+ messages in thread
From: Eric W. Biederman @ 2013-09-04  7:22 UTC (permalink / raw)
  To: Jan Kaluza
  Cc: davem-fT/PcQaiUtIeIZ0/mPfg9Q, LKML,
	netdev-u79uwXL29TY76Z2rM5mHXA, eparis-H+wXaHxf7aLQT0dZR+AlfA,
	rgb-H+wXaHxf7aLQT0dZR+AlfA, tj-DgEjT+Ai2ygdnm+yROfE0A,
	lizefan-hv44wF8Li93QT0dZR+AlfA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	cgroups-u79uwXL29TY76Z2rM5mHXA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn

Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> writes:

> Server-like processes in many cases need credentials and other
> metadata of the peer, to decide if the calling process is allowed to
> request a specific action, or the server just wants to log away this
> type of information for auditing tasks.
>
> The current practice to retrieve such process metadata is to look that
> information up in procfs with the $PID received over SCM_CREDENTIALS.
> This is sufficient for long-running tasks, but introduces a race which
> cannot be worked around for short-living processes; the calling
> process and all the information in /proc/$PID/ is gone before the
> receiver of the socket message can look it up.
>
> This introduces a new SCM type called SCM_AUDIT to allow the direct
> attaching of "loginuid" and "sessionid" to SCM, which is significantly more
> efficient and will reliably avoid the race with the round-trip over
> procfs.

Unless I am misreading something this patch will break the build if
CONFIG_AUDITSYSCALL is not defined.

Eric


> Signed-off-by: Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---
>  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;
>  		}

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message
       [not found]     ` <1378275261-4553-1-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                         ` (2 preceding siblings ...)
  2013-09-04  6:14       ` [PATCH v3 3/3] Send cgroup_path in SCM_CGROUP Jan Kaluza
@ 2013-09-04  7:42       ` Eric W. Biederman
  3 siblings, 0 replies; 79+ messages in thread
From: Eric W. Biederman @ 2013-09-04  7:42 UTC (permalink / raw)
  To: Jan Kaluza
  Cc: rgb-H+wXaHxf7aLQT0dZR+AlfA, netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, tj-DgEjT+Ai2ygdnm+yROfE0A,
	cgroups-u79uwXL29TY76Z2rM5mHXA, davem-fT/PcQaiUtIeIZ0/mPfg9Q

Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> writes:

> Hi,
>
> this patchset against net-next (applies also to linux-next) adds 3 new types
> of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).
>
> Server-like processes in many cases need credentials and other
> metadata of the peer, to decide if the calling process is allowed to
> request a specific action, or the server just wants to log away this
> type of information for auditing tasks.
>
> The current practice to retrieve such process metadata is to look that
> information up in procfs with the $PID received over SCM_CREDENTIALS.
> This is sufficient for long-running tasks, but introduces a race which
> cannot be worked around for short-living processes; the calling
> process and all the information in /proc/$PID/ is gone before the
> receiver of the socket message can look it up.

> Changes introduced in this patchset can also increase performance
> of such server-like processes, because current way of opening and
> parsing /proc/$PID/* files is much more expensive than receiving these
> metadata using SCM.

Can I just say ick, blech, barf, gag.

You don't require this information to be passed.  You are asking people
to suport a lot of new code for the forseeable future.  The only advantage
appears to be for short lived racy processes that don't even bother to
make certain their message was acknowleged before exiting.

You sent this during the merge window which is the time for code
integration and testing not new code.

By my count you have overflowed cb in struct sk_buff and are stomping on
_skb_refdest.

If you are going to go crazy and pass things is there a reason you do
not add a patch to pass the bsd SCM_CREDS?  That information seems more
relevant in a security context and for making security decisions than
about half the information you are passing.

Eric

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message
       [not found]     ` <1378275261-4553-1-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
@ 2013-09-04  7:42       ` Eric W. Biederman
  2013-09-04  6:14         ` Jan Kaluza
                         ` (2 subsequent siblings)
  3 siblings, 0 replies; 79+ messages in thread
From: Eric W. Biederman @ 2013-09-04  7:42 UTC (permalink / raw)
  To: Jan Kaluza
  Cc: davem, LKML, netdev, eparis, rgb, tj, lizefan, containers, cgroups, viro

Jan Kaluza <jkaluza@redhat.com> writes:

> Hi,
>
> this patchset against net-next (applies also to linux-next) adds 3 new types
> of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).
>
> Server-like processes in many cases need credentials and other
> metadata of the peer, to decide if the calling process is allowed to
> request a specific action, or the server just wants to log away this
> type of information for auditing tasks.
>
> The current practice to retrieve such process metadata is to look that
> information up in procfs with the $PID received over SCM_CREDENTIALS.
> This is sufficient for long-running tasks, but introduces a race which
> cannot be worked around for short-living processes; the calling
> process and all the information in /proc/$PID/ is gone before the
> receiver of the socket message can look it up.

> Changes introduced in this patchset can also increase performance
> of such server-like processes, because current way of opening and
> parsing /proc/$PID/* files is much more expensive than receiving these
> metadata using SCM.

Can I just say ick, blech, barf, gag.

You don't require this information to be passed.  You are asking people
to suport a lot of new code for the forseeable future.  The only advantage
appears to be for short lived racy processes that don't even bother to
make certain their message was acknowleged before exiting.

You sent this during the merge window which is the time for code
integration and testing not new code.

By my count you have overflowed cb in struct sk_buff and are stomping on
_skb_refdest.

If you are going to go crazy and pass things is there a reason you do
not add a patch to pass the bsd SCM_CREDS?  That information seems more
relevant in a security context and for making security decisions than
about half the information you are passing.

Eric

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message
@ 2013-09-04  7:42       ` Eric W. Biederman
  0 siblings, 0 replies; 79+ messages in thread
From: Eric W. Biederman @ 2013-09-04  7:42 UTC (permalink / raw)
  To: Jan Kaluza
  Cc: davem-fT/PcQaiUtIeIZ0/mPfg9Q, LKML,
	netdev-u79uwXL29TY76Z2rM5mHXA, eparis-H+wXaHxf7aLQT0dZR+AlfA,
	rgb-H+wXaHxf7aLQT0dZR+AlfA, tj-DgEjT+Ai2ygdnm+yROfE0A,
	lizefan-hv44wF8Li93QT0dZR+AlfA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	cgroups-u79uwXL29TY76Z2rM5mHXA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn

Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> writes:

> Hi,
>
> this patchset against net-next (applies also to linux-next) adds 3 new types
> of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).
>
> Server-like processes in many cases need credentials and other
> metadata of the peer, to decide if the calling process is allowed to
> request a specific action, or the server just wants to log away this
> type of information for auditing tasks.
>
> The current practice to retrieve such process metadata is to look that
> information up in procfs with the $PID received over SCM_CREDENTIALS.
> This is sufficient for long-running tasks, but introduces a race which
> cannot be worked around for short-living processes; the calling
> process and all the information in /proc/$PID/ is gone before the
> receiver of the socket message can look it up.

> Changes introduced in this patchset can also increase performance
> of such server-like processes, because current way of opening and
> parsing /proc/$PID/* files is much more expensive than receiving these
> metadata using SCM.

Can I just say ick, blech, barf, gag.

You don't require this information to be passed.  You are asking people
to suport a lot of new code for the forseeable future.  The only advantage
appears to be for short lived racy processes that don't even bother to
make certain their message was acknowleged before exiting.

You sent this during the merge window which is the time for code
integration and testing not new code.

By my count you have overflowed cb in struct sk_buff and are stomping on
_skb_refdest.

If you are going to go crazy and pass things is there a reason you do
not add a patch to pass the bsd SCM_CREDS?  That information seems more
relevant in a security context and for making security decisions than
about half the information you are passing.

Eric

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v3 1/3] Send loginuid and sessionid in SCM_AUDIT
  2013-09-04  7:22           ` Eric W. Biederman
@ 2013-09-04  9:07               ` Jan Kaluža
  -1 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluža @ 2013-09-04  9:07 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: rgb-H+wXaHxf7aLQT0dZR+AlfA, netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, tj-DgEjT+Ai2ygdnm+yROfE0A,
	cgroups-u79uwXL29TY76Z2rM5mHXA, davem-fT/PcQaiUtIeIZ0/mPfg9Q

On 09/04/2013 09:22 AM, Eric W. Biederman wrote:
> Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> writes:
>
>> Server-like processes in many cases need credentials and other
>> metadata of the peer, to decide if the calling process is allowed to
>> request a specific action, or the server just wants to log away this
>> type of information for auditing tasks.
>>
>> The current practice to retrieve such process metadata is to look that
>> information up in procfs with the $PID received over SCM_CREDENTIALS.
>> This is sufficient for long-running tasks, but introduces a race which
>> cannot be worked around for short-living processes; the calling
>> process and all the information in /proc/$PID/ is gone before the
>> receiver of the socket message can look it up.
>>
>> This introduces a new SCM type called SCM_AUDIT to allow the direct
>> attaching of "loginuid" and "sessionid" to SCM, which is significantly more
>> efficient and will reliably avoid the race with the round-trip over
>> procfs.
>
> Unless I am misreading something this patch will break the build if
> CONFIG_AUDITSYSCALL is not defined.

It does build. In this case, audit_get_loginuid returns INVALID_UID and 
audit_get_sessionid returns -1.

Jan Kaluza

> Eric
>
>
>> Signed-off-by: Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>> ---
>>   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;
>>   		}

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v3 1/3] Send loginuid and sessionid in SCM_AUDIT
@ 2013-09-04  9:07               ` Jan Kaluža
  0 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluža @ 2013-09-04  9:07 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: davem, LKML, netdev, eparis, rgb, tj, lizefan, containers, cgroups, viro

On 09/04/2013 09:22 AM, Eric W. Biederman wrote:
> Jan Kaluza <jkaluza@redhat.com> writes:
>
>> Server-like processes in many cases need credentials and other
>> metadata of the peer, to decide if the calling process is allowed to
>> request a specific action, or the server just wants to log away this
>> type of information for auditing tasks.
>>
>> The current practice to retrieve such process metadata is to look that
>> information up in procfs with the $PID received over SCM_CREDENTIALS.
>> This is sufficient for long-running tasks, but introduces a race which
>> cannot be worked around for short-living processes; the calling
>> process and all the information in /proc/$PID/ is gone before the
>> receiver of the socket message can look it up.
>>
>> This introduces a new SCM type called SCM_AUDIT to allow the direct
>> attaching of "loginuid" and "sessionid" to SCM, which is significantly more
>> efficient and will reliably avoid the race with the round-trip over
>> procfs.
>
> Unless I am misreading something this patch will break the build if
> CONFIG_AUDITSYSCALL is not defined.

It does build. In this case, audit_get_loginuid returns INVALID_UID and 
audit_get_sessionid returns -1.

Jan Kaluza

> Eric
>
>
>> Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
>> ---
>>   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;
>>   		}


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message
  2013-09-04  7:42       ` Eric W. Biederman
@ 2013-09-04 14:45           ` Tejun Heo
  -1 siblings, 0 replies; 79+ messages in thread
From: Tejun Heo @ 2013-09-04 14:45 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: Jan Kaluza, rgb-H+wXaHxf7aLQT0dZR+AlfA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
	cgroups-u79uwXL29TY76Z2rM5mHXA, davem-fT/PcQaiUtIeIZ0/mPfg9Q

Hello, Eric.

On Wed, Sep 04, 2013 at 12:42:26AM -0700, Eric W. Biederman wrote:
> Can I just say ick, blech, barf, gag.

Gees, an awesome way to start the conversation.  If your gag response
is hyper-sensitive, go see a frigging doctor.  It's annoying because
you tend to go over the top while getting things wrong often enough.
Even if you don't agree, you don't have to start things this way.

> You don't require this information to be passed.  You are asking people
> to suport a lot of new code for the forseeable future.  The only advantage
> appears to be for short lived racy processes that don't even bother to
> make certain their message was acknowleged before exiting.

While I'm not sure whether this is *the* right appraoch, how is "we
have some pretty visible race conditions but it's probably okay" an
answer?  This affects auditing and logging directly and you're saying
"ah well, the program wasn't running long enough"?

> You sent this during the merge window which is the time for code
> integration and testing not new code.

What are you talking about?  It is *okay* to send new patches during
merge window even if it's headed for the next merge window.  Sending
patches to maintainers doesn't mean "this should go in right now".
Maintainers are of course free to delay response or ask for
pinging/resending later but it's just stupid to accuse patch
submitters for sending patches.  What the hell is that?

> By my count you have overflowed cb in struct sk_buff and are stomping on
> _skb_refdest.
> 
> If you are going to go crazy and pass things is there a reason you do
> not add a patch to pass the bsd SCM_CREDS?  That information seems more
> relevant in a security context and for making security decisions than
> about half the information you are passing.

You could have lost all the other paragraphs and just responded with
the above.  I don't think we can extend an existing struct but maybe
how information is packed can be adjusted.  That said, the proposed
split makes sense to me.

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message
@ 2013-09-04 14:45           ` Tejun Heo
  0 siblings, 0 replies; 79+ messages in thread
From: Tejun Heo @ 2013-09-04 14:45 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: Jan Kaluza, davem, LKML, netdev, eparis, rgb, lizefan,
	containers, cgroups, viro

Hello, Eric.

On Wed, Sep 04, 2013 at 12:42:26AM -0700, Eric W. Biederman wrote:
> Can I just say ick, blech, barf, gag.

Gees, an awesome way to start the conversation.  If your gag response
is hyper-sensitive, go see a frigging doctor.  It's annoying because
you tend to go over the top while getting things wrong often enough.
Even if you don't agree, you don't have to start things this way.

> You don't require this information to be passed.  You are asking people
> to suport a lot of new code for the forseeable future.  The only advantage
> appears to be for short lived racy processes that don't even bother to
> make certain their message was acknowleged before exiting.

While I'm not sure whether this is *the* right appraoch, how is "we
have some pretty visible race conditions but it's probably okay" an
answer?  This affects auditing and logging directly and you're saying
"ah well, the program wasn't running long enough"?

> You sent this during the merge window which is the time for code
> integration and testing not new code.

What are you talking about?  It is *okay* to send new patches during
merge window even if it's headed for the next merge window.  Sending
patches to maintainers doesn't mean "this should go in right now".
Maintainers are of course free to delay response or ask for
pinging/resending later but it's just stupid to accuse patch
submitters for sending patches.  What the hell is that?

> By my count you have overflowed cb in struct sk_buff and are stomping on
> _skb_refdest.
> 
> If you are going to go crazy and pass things is there a reason you do
> not add a patch to pass the bsd SCM_CREDS?  That information seems more
> relevant in a security context and for making security decisions than
> about half the information you are passing.

You could have lost all the other paragraphs and just responded with
the above.  I don't think we can extend an existing struct but maybe
how information is packed can be adjusted.  That said, the proposed
split makes sense to me.

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message
  2013-09-04  7:42       ` Eric W. Biederman
@ 2013-09-04 14:58           ` Richard Guy Briggs
  -1 siblings, 0 replies; 79+ messages in thread
From: Richard Guy Briggs @ 2013-09-04 14:58 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: Jan Kaluza, netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, tj-DgEjT+Ai2ygdnm+yROfE0A,
	cgroups-u79uwXL29TY76Z2rM5mHXA, davem-fT/PcQaiUtIeIZ0/mPfg9Q

On Wed, Sep 04, 2013 at 12:42:26AM -0700, Eric W. Biederman wrote:
> Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> writes:
> > Hi,
> >
> > this patchset against net-next (applies also to linux-next) adds 3 new types
> > of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).
> >
> > Server-like processes in many cases need credentials and other
> > metadata of the peer, to decide if the calling process is allowed to
> > request a specific action, or the server just wants to log away this
> > type of information for auditing tasks.
> >
> > The current practice to retrieve such process metadata is to look that
> > information up in procfs with the $PID received over SCM_CREDENTIALS.
> > This is sufficient for long-running tasks, but introduces a race which
> > cannot be worked around for short-living processes; the calling
> > process and all the information in /proc/$PID/ is gone before the
> > receiver of the socket message can look it up.
> 
> > Changes introduced in this patchset can also increase performance
> > of such server-like processes, because current way of opening and
> > parsing /proc/$PID/* files is much more expensive than receiving these
> > metadata using SCM.
> 
> Can I just say ick, blech, barf, gag.

/me hands ebiederman an air sickness bag.

> You don't require this information to be passed.  You are asking people
> to suport a lot of new code for the forseeable future.  The only advantage
> appears to be for short lived racy processes that don't even bother to
> make certain their message was acknowleged before exiting.
> 
> You sent this during the merge window which is the time for code
> integration and testing not new code.

This is an RFC.  How is this important?

> By my count you have overflowed cb in struct sk_buff and are stomping on
> _skb_refdest.

For patch1/3 I count 56/48, then for patch3 I get 48/48.  Jan, you might
do the conversion to a pointer in patch1/3 to avoid bisect breakage.

> If you are going to go crazy and pass things is there a reason you do
> not add a patch to pass the bsd SCM_CREDS?  That information seems more
> relevant in a security context and for making security decisions than
> about half the information you are passing.
> 
> Eric

- RGB

--
Richard Guy Briggs <rbriggs-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Senior Software Engineer
Kernel Security
AMER ENG Base Operating Systems
Remote, Ottawa, Canada
Voice: +1.647.777.2635
Internal: (81) 32635
Alt: +1.613.693.0684x3545

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message
@ 2013-09-04 14:58           ` Richard Guy Briggs
  0 siblings, 0 replies; 79+ messages in thread
From: Richard Guy Briggs @ 2013-09-04 14:58 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: Jan Kaluza, davem, LKML, netdev, eparis, tj, lizefan, containers,
	cgroups, viro

On Wed, Sep 04, 2013 at 12:42:26AM -0700, Eric W. Biederman wrote:
> Jan Kaluza <jkaluza@redhat.com> writes:
> > Hi,
> >
> > this patchset against net-next (applies also to linux-next) adds 3 new types
> > of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).
> >
> > Server-like processes in many cases need credentials and other
> > metadata of the peer, to decide if the calling process is allowed to
> > request a specific action, or the server just wants to log away this
> > type of information for auditing tasks.
> >
> > The current practice to retrieve such process metadata is to look that
> > information up in procfs with the $PID received over SCM_CREDENTIALS.
> > This is sufficient for long-running tasks, but introduces a race which
> > cannot be worked around for short-living processes; the calling
> > process and all the information in /proc/$PID/ is gone before the
> > receiver of the socket message can look it up.
> 
> > Changes introduced in this patchset can also increase performance
> > of such server-like processes, because current way of opening and
> > parsing /proc/$PID/* files is much more expensive than receiving these
> > metadata using SCM.
> 
> Can I just say ick, blech, barf, gag.

/me hands ebiederman an air sickness bag.

> You don't require this information to be passed.  You are asking people
> to suport a lot of new code for the forseeable future.  The only advantage
> appears to be for short lived racy processes that don't even bother to
> make certain their message was acknowleged before exiting.
> 
> You sent this during the merge window which is the time for code
> integration and testing not new code.

This is an RFC.  How is this important?

> By my count you have overflowed cb in struct sk_buff and are stomping on
> _skb_refdest.

For patch1/3 I count 56/48, then for patch3 I get 48/48.  Jan, you might
do the conversion to a pointer in patch1/3 to avoid bisect breakage.

> If you are going to go crazy and pass things is there a reason you do
> not add a patch to pass the bsd SCM_CREDS?  That information seems more
> relevant in a security context and for making security decisions than
> about half the information you are passing.
> 
> Eric

- RGB

--
Richard Guy Briggs <rbriggs@redhat.com>
Senior Software Engineer
Kernel Security
AMER ENG Base Operating Systems
Remote, Ottawa, Canada
Voice: +1.647.777.2635
Internal: (81) 32635
Alt: +1.613.693.0684x3545

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message
       [not found]           ` <20130904145830.GC28517-bcJWsdo4jJjeVoXN4CMphl7TgLCtbB0G@public.gmane.org>
@ 2013-09-04 15:04             ` Jan Kaluža
  2013-09-04 15:20             ` Richard Guy Briggs
  1 sibling, 0 replies; 79+ messages in thread
From: Jan Kaluža @ 2013-09-04 15:04 UTC (permalink / raw)
  To: Richard Guy Briggs
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA, Eric W. Biederman,
	tj-DgEjT+Ai2ygdnm+yROfE0A, cgroups-u79uwXL29TY76Z2rM5mHXA,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn

On 09/04/2013 04:58 PM, Richard Guy Briggs wrote:
> On Wed, Sep 04, 2013 at 12:42:26AM -0700, Eric W. Biederman wrote:
>> Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> writes:
>>> Hi,
>>>
>>> this patchset against net-next (applies also to linux-next) adds 3 new types
>>> of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).
>>>
>>> Server-like processes in many cases need credentials and other
>>> metadata of the peer, to decide if the calling process is allowed to
>>> request a specific action, or the server just wants to log away this
>>> type of information for auditing tasks.
>>>
>>> The current practice to retrieve such process metadata is to look that
>>> information up in procfs with the $PID received over SCM_CREDENTIALS.
>>> This is sufficient for long-running tasks, but introduces a race which
>>> cannot be worked around for short-living processes; the calling
>>> process and all the information in /proc/$PID/ is gone before the
>>> receiver of the socket message can look it up.
>>
>>> Changes introduced in this patchset can also increase performance
>>> of such server-like processes, because current way of opening and
>>> parsing /proc/$PID/* files is much more expensive than receiving these
>>> metadata using SCM.
>>
>> Can I just say ick, blech, barf, gag.
>
> /me hands ebiederman an air sickness bag.
>
>> You don't require this information to be passed.  You are asking people
>> to suport a lot of new code for the forseeable future.  The only advantage
>> appears to be for short lived racy processes that don't even bother to
>> make certain their message was acknowleged before exiting.
>>
>> You sent this during the merge window which is the time for code
>> integration and testing not new code.
>
> This is an RFC.  How is this important?
>
>> By my count you have overflowed cb in struct sk_buff and are stomping on
>> _skb_refdest.
>
> For patch1/3 I count 56/48, then for patch3 I get 48/48.  Jan, you might
> do the conversion to a pointer in patch1/3 to avoid bisect breakage.

Yes, this is valid point. I will do the conversion in patch1. Thanks all 
for reviewing and pointing that out.

Jan Kaluza

>> If you are going to go crazy and pass things is there a reason you do
>> not add a patch to pass the bsd SCM_CREDS?  That information seems more
>> relevant in a security context and for making security decisions than
>> about half the information you are passing.
>>
>> Eric
>
> - RGB
>
> --
> Richard Guy Briggs <rbriggs-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> Senior Software Engineer
> Kernel Security
> AMER ENG Base Operating Systems
> Remote, Ottawa, Canada
> Voice: +1.647.777.2635
> Internal: (81) 32635
> Alt: +1.613.693.0684x3545
>

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message
       [not found]           ` <20130904145830.GC28517-bcJWsdo4jJjeVoXN4CMphl7TgLCtbB0G@public.gmane.org>
@ 2013-09-04 15:04             ` Jan Kaluža
  2013-09-04 15:20             ` Richard Guy Briggs
  1 sibling, 0 replies; 79+ messages in thread
From: Jan Kaluža @ 2013-09-04 15:04 UTC (permalink / raw)
  To: Richard Guy Briggs
  Cc: Eric W. Biederman, davem, LKML, netdev, eparis, tj, lizefan,
	containers, cgroups, viro

On 09/04/2013 04:58 PM, Richard Guy Briggs wrote:
> On Wed, Sep 04, 2013 at 12:42:26AM -0700, Eric W. Biederman wrote:
>> Jan Kaluza <jkaluza@redhat.com> writes:
>>> Hi,
>>>
>>> this patchset against net-next (applies also to linux-next) adds 3 new types
>>> of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).
>>>
>>> Server-like processes in many cases need credentials and other
>>> metadata of the peer, to decide if the calling process is allowed to
>>> request a specific action, or the server just wants to log away this
>>> type of information for auditing tasks.
>>>
>>> The current practice to retrieve such process metadata is to look that
>>> information up in procfs with the $PID received over SCM_CREDENTIALS.
>>> This is sufficient for long-running tasks, but introduces a race which
>>> cannot be worked around for short-living processes; the calling
>>> process and all the information in /proc/$PID/ is gone before the
>>> receiver of the socket message can look it up.
>>
>>> Changes introduced in this patchset can also increase performance
>>> of such server-like processes, because current way of opening and
>>> parsing /proc/$PID/* files is much more expensive than receiving these
>>> metadata using SCM.
>>
>> Can I just say ick, blech, barf, gag.
>
> /me hands ebiederman an air sickness bag.
>
>> You don't require this information to be passed.  You are asking people
>> to suport a lot of new code for the forseeable future.  The only advantage
>> appears to be for short lived racy processes that don't even bother to
>> make certain their message was acknowleged before exiting.
>>
>> You sent this during the merge window which is the time for code
>> integration and testing not new code.
>
> This is an RFC.  How is this important?
>
>> By my count you have overflowed cb in struct sk_buff and are stomping on
>> _skb_refdest.
>
> For patch1/3 I count 56/48, then for patch3 I get 48/48.  Jan, you might
> do the conversion to a pointer in patch1/3 to avoid bisect breakage.

Yes, this is valid point. I will do the conversion in patch1. Thanks all 
for reviewing and pointing that out.

Jan Kaluza

>> If you are going to go crazy and pass things is there a reason you do
>> not add a patch to pass the bsd SCM_CREDS?  That information seems more
>> relevant in a security context and for making security decisions than
>> about half the information you are passing.
>>
>> Eric
>
> - RGB
>
> --
> Richard Guy Briggs <rbriggs@redhat.com>
> Senior Software Engineer
> Kernel Security
> AMER ENG Base Operating Systems
> Remote, Ottawa, Canada
> Voice: +1.647.777.2635
> Internal: (81) 32635
> Alt: +1.613.693.0684x3545
>


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message
@ 2013-09-04 15:04             ` Jan Kaluža
  0 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluža @ 2013-09-04 15:04 UTC (permalink / raw)
  To: Richard Guy Briggs
  Cc: Eric W. Biederman, davem-fT/PcQaiUtIeIZ0/mPfg9Q, LKML,
	netdev-u79uwXL29TY76Z2rM5mHXA, eparis-H+wXaHxf7aLQT0dZR+AlfA,
	tj-DgEjT+Ai2ygdnm+yROfE0A, lizefan-hv44wF8Li93QT0dZR+AlfA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	cgroups-u79uwXL29TY76Z2rM5mHXA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn

On 09/04/2013 04:58 PM, Richard Guy Briggs wrote:
> On Wed, Sep 04, 2013 at 12:42:26AM -0700, Eric W. Biederman wrote:
>> Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> writes:
>>> Hi,
>>>
>>> this patchset against net-next (applies also to linux-next) adds 3 new types
>>> of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).
>>>
>>> Server-like processes in many cases need credentials and other
>>> metadata of the peer, to decide if the calling process is allowed to
>>> request a specific action, or the server just wants to log away this
>>> type of information for auditing tasks.
>>>
>>> The current practice to retrieve such process metadata is to look that
>>> information up in procfs with the $PID received over SCM_CREDENTIALS.
>>> This is sufficient for long-running tasks, but introduces a race which
>>> cannot be worked around for short-living processes; the calling
>>> process and all the information in /proc/$PID/ is gone before the
>>> receiver of the socket message can look it up.
>>
>>> Changes introduced in this patchset can also increase performance
>>> of such server-like processes, because current way of opening and
>>> parsing /proc/$PID/* files is much more expensive than receiving these
>>> metadata using SCM.
>>
>> Can I just say ick, blech, barf, gag.
>
> /me hands ebiederman an air sickness bag.
>
>> You don't require this information to be passed.  You are asking people
>> to suport a lot of new code for the forseeable future.  The only advantage
>> appears to be for short lived racy processes that don't even bother to
>> make certain their message was acknowleged before exiting.
>>
>> You sent this during the merge window which is the time for code
>> integration and testing not new code.
>
> This is an RFC.  How is this important?
>
>> By my count you have overflowed cb in struct sk_buff and are stomping on
>> _skb_refdest.
>
> For patch1/3 I count 56/48, then for patch3 I get 48/48.  Jan, you might
> do the conversion to a pointer in patch1/3 to avoid bisect breakage.

Yes, this is valid point. I will do the conversion in patch1. Thanks all 
for reviewing and pointing that out.

Jan Kaluza

>> If you are going to go crazy and pass things is there a reason you do
>> not add a patch to pass the bsd SCM_CREDS?  That information seems more
>> relevant in a security context and for making security decisions than
>> about half the information you are passing.
>>
>> Eric
>
> - RGB
>
> --
> Richard Guy Briggs <rbriggs-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> Senior Software Engineer
> Kernel Security
> AMER ENG Base Operating Systems
> Remote, Ottawa, Canada
> Voice: +1.647.777.2635
> Internal: (81) 32635
> Alt: +1.613.693.0684x3545
>

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message
       [not found]           ` <20130904145830.GC28517-bcJWsdo4jJjeVoXN4CMphl7TgLCtbB0G@public.gmane.org>
  2013-09-04 15:04             ` Jan Kaluža
@ 2013-09-04 15:20             ` Richard Guy Briggs
  1 sibling, 0 replies; 79+ messages in thread
From: Richard Guy Briggs @ 2013-09-04 15:20 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: Jan Kaluza, netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, tj-DgEjT+Ai2ygdnm+yROfE0A,
	cgroups-u79uwXL29TY76Z2rM5mHXA, davem-fT/PcQaiUtIeIZ0/mPfg9Q

On Wed, Sep 04, 2013 at 10:58:30AM -0400, Richard Guy Briggs wrote:
> On Wed, Sep 04, 2013 at 12:42:26AM -0700, Eric W. Biederman wrote:
> > Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> writes:
> > > this patchset against net-next (applies also to linux-next) adds 3 new types
> > > of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).
> 
> > By my count you have overflowed cb in struct sk_buff and are stomping on
> > _skb_refdest.
> 
> For patch1/3 I count 56/48, then for patch3 I get 48/48.  Jan, you might
> do the conversion to a pointer in patch1/3 to avoid bisect breakage.

Wait, that __aligned(8) is for cb[48], not for the contents.

For patch1/3 I count 28/48 on 32-bit, 36/48 on 64-bit (or would that be
56 by default on 64-bit arches without aligned specified?), then for
patch3 I get 24/48 on 32 and 40/48 on 64 (or again 48/48 by default?).

> > Eric
> 
> - RGB

- RGB

--
Richard Guy Briggs <rbriggs-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Senior Software Engineer
Kernel Security
AMER ENG Base Operating Systems
Remote, Ottawa, Canada
Voice: +1.647.777.2635
Internal: (81) 32635
Alt: +1.613.693.0684x3545

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message
       [not found]           ` <20130904145830.GC28517-bcJWsdo4jJjeVoXN4CMphl7TgLCtbB0G@public.gmane.org>
@ 2013-09-04 15:20             ` Richard Guy Briggs
  2013-09-04 15:20             ` Richard Guy Briggs
  1 sibling, 0 replies; 79+ messages in thread
From: Richard Guy Briggs @ 2013-09-04 15:20 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: Jan Kaluza, davem, LKML, netdev, eparis, tj, lizefan, containers,
	cgroups, viro

On Wed, Sep 04, 2013 at 10:58:30AM -0400, Richard Guy Briggs wrote:
> On Wed, Sep 04, 2013 at 12:42:26AM -0700, Eric W. Biederman wrote:
> > Jan Kaluza <jkaluza@redhat.com> writes:
> > > this patchset against net-next (applies also to linux-next) adds 3 new types
> > > of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).
> 
> > By my count you have overflowed cb in struct sk_buff and are stomping on
> > _skb_refdest.
> 
> For patch1/3 I count 56/48, then for patch3 I get 48/48.  Jan, you might
> do the conversion to a pointer in patch1/3 to avoid bisect breakage.

Wait, that __aligned(8) is for cb[48], not for the contents.

For patch1/3 I count 28/48 on 32-bit, 36/48 on 64-bit (or would that be
56 by default on 64-bit arches without aligned specified?), then for
patch3 I get 24/48 on 32 and 40/48 on 64 (or again 48/48 by default?).

> > Eric
> 
> - RGB

- RGB

--
Richard Guy Briggs <rbriggs@redhat.com>
Senior Software Engineer
Kernel Security
AMER ENG Base Operating Systems
Remote, Ottawa, Canada
Voice: +1.647.777.2635
Internal: (81) 32635
Alt: +1.613.693.0684x3545

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message
@ 2013-09-04 15:20             ` Richard Guy Briggs
  0 siblings, 0 replies; 79+ messages in thread
From: Richard Guy Briggs @ 2013-09-04 15:20 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: Jan Kaluza, davem-fT/PcQaiUtIeIZ0/mPfg9Q, LKML,
	netdev-u79uwXL29TY76Z2rM5mHXA, eparis-H+wXaHxf7aLQT0dZR+AlfA,
	tj-DgEjT+Ai2ygdnm+yROfE0A, lizefan-hv44wF8Li93QT0dZR+AlfA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	cgroups-u79uwXL29TY76Z2rM5mHXA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn

On Wed, Sep 04, 2013 at 10:58:30AM -0400, Richard Guy Briggs wrote:
> On Wed, Sep 04, 2013 at 12:42:26AM -0700, Eric W. Biederman wrote:
> > Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> writes:
> > > this patchset against net-next (applies also to linux-next) adds 3 new types
> > > of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).
> 
> > By my count you have overflowed cb in struct sk_buff and are stomping on
> > _skb_refdest.
> 
> For patch1/3 I count 56/48, then for patch3 I get 48/48.  Jan, you might
> do the conversion to a pointer in patch1/3 to avoid bisect breakage.

Wait, that __aligned(8) is for cb[48], not for the contents.

For patch1/3 I count 28/48 on 32-bit, 36/48 on 64-bit (or would that be
56 by default on 64-bit arches without aligned specified?), then for
patch3 I get 24/48 on 32 and 40/48 on 64 (or again 48/48 by default?).

> > Eric
> 
> - RGB

- RGB

--
Richard Guy Briggs <rbriggs-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Senior Software Engineer
Kernel Security
AMER ENG Base Operating Systems
Remote, Ottawa, Canada
Voice: +1.647.777.2635
Internal: (81) 32635
Alt: +1.613.693.0684x3545

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message
  2013-09-04 15:20             ` Richard Guy Briggs
@ 2013-09-04 15:30                 ` Eric Dumazet
  -1 siblings, 0 replies; 79+ messages in thread
From: Eric Dumazet @ 2013-09-04 15:30 UTC (permalink / raw)
  To: Richard Guy Briggs
  Cc: Jan Kaluza, netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA, Eric W. Biederman,
	tj-DgEjT+Ai2ygdnm+yROfE0A, cgroups-u79uwXL29TY76Z2rM5mHXA,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn

On Wed, 2013-09-04 at 11:20 -0400, Richard Guy Briggs wrote:
> On Wed, Sep 04, 2013 at 10:58:30AM -0400, Richard Guy Briggs wrote:
> > On Wed, Sep 04, 2013 at 12:42:26AM -0700, Eric W. Biederman wrote:
> > > Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> writes:
> > > > this patchset against net-next (applies also to linux-next) adds 3 new types
> > > > of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).
> > 
> > > By my count you have overflowed cb in struct sk_buff and are stomping on
> > > _skb_refdest.
> > 
> > For patch1/3 I count 56/48, then for patch3 I get 48/48.  Jan, you might
> > do the conversion to a pointer in patch1/3 to avoid bisect breakage.
> 
> Wait, that __aligned(8) is for cb[48], not for the contents.
> 
> For patch1/3 I count 28/48 on 32-bit, 36/48 on 64-bit (or would that be
> 56 by default on 64-bit arches without aligned specified?), then for
> patch3 I get 24/48 on 32 and 40/48 on 64 (or again 48/48 by default?).

Do not count, just add this :

diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 86de99a..5b61320 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1329,6 +1329,7 @@ static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb)
 {
 	int i;
 
+	BUILD_BUG_ON(sizeof(struct unix_skb_parms) > sizeof(skb->cb));
 	scm->fp = UNIXCB(skb).fp;
 	UNIXCB(skb).fp = NULL;

^ permalink raw reply related	[flat|nested] 79+ messages in thread

* Re: [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message
@ 2013-09-04 15:30                 ` Eric Dumazet
  0 siblings, 0 replies; 79+ messages in thread
From: Eric Dumazet @ 2013-09-04 15:30 UTC (permalink / raw)
  To: Richard Guy Briggs
  Cc: Eric W. Biederman, Jan Kaluza, davem, LKML, netdev, eparis, tj,
	lizefan, containers, cgroups, viro

On Wed, 2013-09-04 at 11:20 -0400, Richard Guy Briggs wrote:
> On Wed, Sep 04, 2013 at 10:58:30AM -0400, Richard Guy Briggs wrote:
> > On Wed, Sep 04, 2013 at 12:42:26AM -0700, Eric W. Biederman wrote:
> > > Jan Kaluza <jkaluza@redhat.com> writes:
> > > > this patchset against net-next (applies also to linux-next) adds 3 new types
> > > > of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).
> > 
> > > By my count you have overflowed cb in struct sk_buff and are stomping on
> > > _skb_refdest.
> > 
> > For patch1/3 I count 56/48, then for patch3 I get 48/48.  Jan, you might
> > do the conversion to a pointer in patch1/3 to avoid bisect breakage.
> 
> Wait, that __aligned(8) is for cb[48], not for the contents.
> 
> For patch1/3 I count 28/48 on 32-bit, 36/48 on 64-bit (or would that be
> 56 by default on 64-bit arches without aligned specified?), then for
> patch3 I get 24/48 on 32 and 40/48 on 64 (or again 48/48 by default?).

Do not count, just add this :

diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 86de99a..5b61320 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1329,6 +1329,7 @@ static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb)
 {
 	int i;
 
+	BUILD_BUG_ON(sizeof(struct unix_skb_parms) > sizeof(skb->cb));
 	scm->fp = UNIXCB(skb).fp;
 	UNIXCB(skb).fp = NULL;
 



^ permalink raw reply related	[flat|nested] 79+ messages in thread

* Re: [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message
  2013-09-04 15:30                 ` Eric Dumazet
  (?)
  (?)
@ 2013-09-04 15:40                 ` Jan Kaluža
  -1 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluža @ 2013-09-04 15:40 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Richard Guy Briggs, netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA, Eric W. Biederman,
	tj-DgEjT+Ai2ygdnm+yROfE0A, cgroups-u79uwXL29TY76Z2rM5mHXA,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn

On 09/04/2013 05:30 PM, Eric Dumazet wrote:
> On Wed, 2013-09-04 at 11:20 -0400, Richard Guy Briggs wrote:
>> On Wed, Sep 04, 2013 at 10:58:30AM -0400, Richard Guy Briggs wrote:
>>> On Wed, Sep 04, 2013 at 12:42:26AM -0700, Eric W. Biederman wrote:
>>>> Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> writes:
>>>>> this patchset against net-next (applies also to linux-next) adds 3 new types
>>>>> of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).
>>>
>>>> By my count you have overflowed cb in struct sk_buff and are stomping on
>>>> _skb_refdest.
>>>
>>> For patch1/3 I count 56/48, then for patch3 I get 48/48.  Jan, you might
>>> do the conversion to a pointer in patch1/3 to avoid bisect breakage.
>>
>> Wait, that __aligned(8) is for cb[48], not for the contents.
>>
>> For patch1/3 I count 28/48 on 32-bit, 36/48 on 64-bit (or would that be
>> 56 by default on 64-bit arches without aligned specified?), then for
>> patch3 I get 24/48 on 32 and 40/48 on 64 (or again 48/48 by default?).
>
> Do not count, just add this :
>
> diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
> index 86de99a..5b61320 100644
> --- a/net/unix/af_unix.c
> +++ b/net/unix/af_unix.c
> @@ -1329,6 +1329,7 @@ static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb)
>   {
>   	int i;
>
> +	BUILD_BUG_ON(sizeof(struct unix_skb_parms) > sizeof(skb->cb));
>   	scm->fp = UNIXCB(skb).fp;
>   	UNIXCB(skb).fp = NULL;
>

That's already in af_unix.c:

BUILD_BUG_ON(sizeof(struct unix_skb_parms) > FIELD_SIZEOF(struct 
sk_buff, cb));

This test is passing for me even with only patch1/3 applied when 
building 64bit kernel.

Jan Kaluza

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message
  2013-09-04 15:30                 ` Eric Dumazet
@ 2013-09-04 15:40                   ` Jan Kaluža
  -1 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluža @ 2013-09-04 15:40 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Richard Guy Briggs, Eric W. Biederman, davem, LKML, netdev,
	eparis, tj, lizefan, containers, cgroups, viro

On 09/04/2013 05:30 PM, Eric Dumazet wrote:
> On Wed, 2013-09-04 at 11:20 -0400, Richard Guy Briggs wrote:
>> On Wed, Sep 04, 2013 at 10:58:30AM -0400, Richard Guy Briggs wrote:
>>> On Wed, Sep 04, 2013 at 12:42:26AM -0700, Eric W. Biederman wrote:
>>>> Jan Kaluza <jkaluza@redhat.com> writes:
>>>>> this patchset against net-next (applies also to linux-next) adds 3 new types
>>>>> of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).
>>>
>>>> By my count you have overflowed cb in struct sk_buff and are stomping on
>>>> _skb_refdest.
>>>
>>> For patch1/3 I count 56/48, then for patch3 I get 48/48.  Jan, you might
>>> do the conversion to a pointer in patch1/3 to avoid bisect breakage.
>>
>> Wait, that __aligned(8) is for cb[48], not for the contents.
>>
>> For patch1/3 I count 28/48 on 32-bit, 36/48 on 64-bit (or would that be
>> 56 by default on 64-bit arches without aligned specified?), then for
>> patch3 I get 24/48 on 32 and 40/48 on 64 (or again 48/48 by default?).
>
> Do not count, just add this :
>
> diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
> index 86de99a..5b61320 100644
> --- a/net/unix/af_unix.c
> +++ b/net/unix/af_unix.c
> @@ -1329,6 +1329,7 @@ static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb)
>   {
>   	int i;
>
> +	BUILD_BUG_ON(sizeof(struct unix_skb_parms) > sizeof(skb->cb));
>   	scm->fp = UNIXCB(skb).fp;
>   	UNIXCB(skb).fp = NULL;
>

That's already in af_unix.c:

BUILD_BUG_ON(sizeof(struct unix_skb_parms) > FIELD_SIZEOF(struct 
sk_buff, cb));

This test is passing for me even with only patch1/3 applied when 
building 64bit kernel.

Jan Kaluza


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message
@ 2013-09-04 15:40                   ` Jan Kaluža
  0 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluža @ 2013-09-04 15:40 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Richard Guy Briggs, Eric W. Biederman,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q, LKML,
	netdev-u79uwXL29TY76Z2rM5mHXA, eparis-H+wXaHxf7aLQT0dZR+AlfA,
	tj-DgEjT+Ai2ygdnm+yROfE0A, lizefan-hv44wF8Li93QT0dZR+AlfA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	cgroups-u79uwXL29TY76Z2rM5mHXA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn

On 09/04/2013 05:30 PM, Eric Dumazet wrote:
> On Wed, 2013-09-04 at 11:20 -0400, Richard Guy Briggs wrote:
>> On Wed, Sep 04, 2013 at 10:58:30AM -0400, Richard Guy Briggs wrote:
>>> On Wed, Sep 04, 2013 at 12:42:26AM -0700, Eric W. Biederman wrote:
>>>> Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> writes:
>>>>> this patchset against net-next (applies also to linux-next) adds 3 new types
>>>>> of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).
>>>
>>>> By my count you have overflowed cb in struct sk_buff and are stomping on
>>>> _skb_refdest.
>>>
>>> For patch1/3 I count 56/48, then for patch3 I get 48/48.  Jan, you might
>>> do the conversion to a pointer in patch1/3 to avoid bisect breakage.
>>
>> Wait, that __aligned(8) is for cb[48], not for the contents.
>>
>> For patch1/3 I count 28/48 on 32-bit, 36/48 on 64-bit (or would that be
>> 56 by default on 64-bit arches without aligned specified?), then for
>> patch3 I get 24/48 on 32 and 40/48 on 64 (or again 48/48 by default?).
>
> Do not count, just add this :
>
> diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
> index 86de99a..5b61320 100644
> --- a/net/unix/af_unix.c
> +++ b/net/unix/af_unix.c
> @@ -1329,6 +1329,7 @@ static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb)
>   {
>   	int i;
>
> +	BUILD_BUG_ON(sizeof(struct unix_skb_parms) > sizeof(skb->cb));
>   	scm->fp = UNIXCB(skb).fp;
>   	UNIXCB(skb).fp = NULL;
>

That's already in af_unix.c:

BUILD_BUG_ON(sizeof(struct unix_skb_parms) > FIELD_SIZEOF(struct 
sk_buff, cb));

This test is passing for me even with only patch1/3 applied when 
building 64bit kernel.

Jan Kaluza

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH 2/3] Send comm and cmdline in SCM_PROCINFO
  2013-08-27 14:39 ` [PATCH 2/3] Send comm and cmdline in SCM_PROCINFO Jan Kaluza
@ 2013-09-09  6:52   ` Eric W. Biederman
  0 siblings, 0 replies; 79+ messages in thread
From: Eric W. Biederman @ 2013-09-09  6:52 UTC (permalink / raw)
  To: Jan Kaluza; +Cc: davem, LKML, netdev, eparis, rgb

Jan Kaluza <jkaluza@redhat.com> writes:

Nacked-by: "Eric W. Biederman" <ebiederm@xmission.com>

Whatever the benefits of the other pieces of information sending the
process command line is absolutely wrong.  It is a just a random string
from user space and there is absolutely no benefit in sending it in a
kernel verified way.  The process can just as easily pass the
information in userspace directly.

Furthermore the implementation of scm_get_current_procinfo is so far
from idiomatic for reading information about the current process that I
think it is fair to call it broken.

Eric

^ permalink raw reply	[flat|nested] 79+ messages in thread

* [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message
  2013-08-27 14:39 [PATCH 0/3] Send audit/procinfo/cgroup data in socket-level control message Jan Kaluza
@ 2014-01-13  8:01     ` Jan Kaluza
  2013-08-27 14:39 ` [PATCH 2/3] Send comm and cmdline in SCM_PROCINFO Jan Kaluza
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluza @ 2014-01-13  8:01 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: Jan Kaluza, rgb-H+wXaHxf7aLQT0dZR+AlfA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, tj-DgEjT+Ai2ygdnm+yROfE0A,
	cgroups-u79uwXL29TY76Z2rM5mHXA

Hi,

this patchset against net-next (applies also to linux-next) adds 3 new types
of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).

Server-like processes in many cases need credentials and other
metadata of the peer, to decide if the calling process is allowed to
request a specific action, or the server just wants to log away this
type of information for auditing tasks.

The current practice to retrieve such process metadata is to look that
information up in procfs with the $PID received over SCM_CREDENTIALS.
This is sufficient for long-running tasks, but introduces a race which
cannot be worked around for short-living processes; the calling
process and all the information in /proc/$PID/ is gone before the
receiver of the socket message can look it up.

Changes introduced in this patchset can also increase performance
of such server-like processes, because current way of opening and
parsing /proc/$PID/* files is much more expensive than receiving these
metadata using SCM.

Changes in v4:
- Rebased to work with the latest net-next tree

Changes in v3:
- Better description of patches (Thanks to Kay Sievers)

Changes in v2:
- use PATH_MAX instead of PAGE_SIZE in SCM_CGROUP patch
- describe each patch individually

Jan Kaluza (3):
  Send loginuid and sessionid in SCM_AUDIT
  Send comm and cmdline in SCM_PROCINFO
  Send cgroup_path in SCM_CGROUP

 include/linux/socket.h |  9 ++++++
 include/net/af_unix.h  | 10 ++++++
 include/net/scm.h      | 67 ++++++++++++++++++++++++++++++++++++++--
 net/core/scm.c         | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++
 net/unix/af_unix.c     | 70 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 237 insertions(+), 2 deletions(-)

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 79+ messages in thread

* [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message
@ 2014-01-13  8:01     ` Jan Kaluza
  0 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluza @ 2014-01-13  8:01 UTC (permalink / raw)
  To: davem
  Cc: LKML, netdev, eparis, rgb, tj, lizefan, containers, cgroups,
	viro, Jan Kaluza

Hi,

this patchset against net-next (applies also to linux-next) adds 3 new types
of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).

Server-like processes in many cases need credentials and other
metadata of the peer, to decide if the calling process is allowed to
request a specific action, or the server just wants to log away this
type of information for auditing tasks.

The current practice to retrieve such process metadata is to look that
information up in procfs with the $PID received over SCM_CREDENTIALS.
This is sufficient for long-running tasks, but introduces a race which
cannot be worked around for short-living processes; the calling
process and all the information in /proc/$PID/ is gone before the
receiver of the socket message can look it up.

Changes introduced in this patchset can also increase performance
of such server-like processes, because current way of opening and
parsing /proc/$PID/* files is much more expensive than receiving these
metadata using SCM.

Changes in v4:
- Rebased to work with the latest net-next tree

Changes in v3:
- Better description of patches (Thanks to Kay Sievers)

Changes in v2:
- use PATH_MAX instead of PAGE_SIZE in SCM_CGROUP patch
- describe each patch individually

Jan Kaluza (3):
  Send loginuid and sessionid in SCM_AUDIT
  Send comm and cmdline in SCM_PROCINFO
  Send cgroup_path in SCM_CGROUP

 include/linux/socket.h |  9 ++++++
 include/net/af_unix.h  | 10 ++++++
 include/net/scm.h      | 67 ++++++++++++++++++++++++++++++++++++++--
 net/core/scm.c         | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++
 net/unix/af_unix.c     | 70 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 237 insertions(+), 2 deletions(-)

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 79+ messages in thread

* [PATCH v4 1/3] Send loginuid and sessionid in SCM_AUDIT
  2014-01-13  8:01     ` Jan Kaluza
@ 2014-01-13  8:01         ` Jan Kaluza
  -1 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluza @ 2014-01-13  8:01 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: Jan Kaluza, rgb-H+wXaHxf7aLQT0dZR+AlfA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, tj-DgEjT+Ai2ygdnm+yROfE0A,
	cgroups-u79uwXL29TY76Z2rM5mHXA

Server-like processes in many cases need credentials and other
metadata of the peer, to decide if the calling process is allowed to
request a specific action, or the server just wants to log away this
type of information for auditing tasks.

The current practice to retrieve such process metadata is to look that
information up in procfs with the $PID received over SCM_CREDENTIALS.
This is sufficient for long-running tasks, but introduces a race which
cannot be worked around for short-living processes; the calling
process and all the information in /proc/$PID/ is gone before the
receiver of the socket message can look it up.

This introduces a new SCM type called SCM_AUDIT to allow the direct
attaching of "loginuid" and "sessionid" to SCM, which is significantly more
efficient and will reliably avoid the race with the round-trip over
procfs.

Signed-off-by: Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 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 5d488a6..eeac565 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 262532d..67de64f 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 800ca61..bc02a25 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1413,6 +1413,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);
@@ -1436,6 +1438,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);
 	}
 }
 
@@ -1829,6 +1833,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)) {
@@ -2008,6 +2013,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

^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH v4 1/3] Send loginuid and sessionid in SCM_AUDIT
@ 2014-01-13  8:01         ` Jan Kaluza
  0 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluza @ 2014-01-13  8:01 UTC (permalink / raw)
  To: davem
  Cc: LKML, netdev, eparis, rgb, tj, lizefan, containers, cgroups,
	viro, Jan Kaluza

Server-like processes in many cases need credentials and other
metadata of the peer, to decide if the calling process is allowed to
request a specific action, or the server just wants to log away this
type of information for auditing tasks.

The current practice to retrieve such process metadata is to look that
information up in procfs with the $PID received over SCM_CREDENTIALS.
This is sufficient for long-running tasks, but introduces a race which
cannot be worked around for short-living processes; the calling
process and all the information in /proc/$PID/ is gone before the
receiver of the socket message can look it up.

This introduces a new SCM type called SCM_AUDIT to allow the direct
attaching of "loginuid" and "sessionid" to SCM, which is significantly more
efficient and will reliably avoid the race with the round-trip over
procfs.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
---
 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 5d488a6..eeac565 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 262532d..67de64f 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 800ca61..bc02a25 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1413,6 +1413,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);
@@ -1436,6 +1438,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);
 	}
 }
 
@@ -1829,6 +1833,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)) {
@@ -2008,6 +2013,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


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH v4 2/3] Send comm and cmdline in SCM_PROCINFO
  2014-01-13  8:01     ` Jan Kaluza
@ 2014-01-13  8:01         ` Jan Kaluza
  -1 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluza @ 2014-01-13  8:01 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: Jan Kaluza, rgb-H+wXaHxf7aLQT0dZR+AlfA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, tj-DgEjT+Ai2ygdnm+yROfE0A,
	cgroups-u79uwXL29TY76Z2rM5mHXA

Server-like processes in many cases need credentials and other
metadata of the peer, to decide if the calling process is allowed to
request a specific action, or the server just wants to log away this
type of information for auditing tasks.

The current practice to retrieve such process metadata is to look that
information up in procfs with the $PID received over SCM_CREDENTIALS.
This is sufficient for long-running tasks, but introduces a race which
cannot be worked around for short-living processes; the calling
process and all the information in /proc/$PID/ is gone before the
receiver of the socket message can look it up.

This introduces a new SCM type called SCM_PROCINFO to allow the direct
attaching of "comm" and "cmdline" to SCM, which is significantly more
efficient and will reliably avoid the race with the round-trip over
procfs.

To achieve that, new struct called unix_skb_parms_scm had to be created,
because otherwise unix_skb_parms would be too big.

scm_get_current_procinfo is inspired by ./fs/proc/base.c.

Signed-off-by: Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 include/linux/socket.h |  2 ++
 include/net/af_unix.h  | 11 +++++++--
 include/net/scm.h      | 24 +++++++++++++++++++
 net/core/scm.c         | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++
 net/unix/af_unix.c     | 57 +++++++++++++++++++++++++++++++++++++------
 5 files changed, 150 insertions(+), 9 deletions(-)

diff --git a/include/linux/socket.h b/include/linux/socket.h
index eeac565..5a41f35 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -131,6 +131,8 @@ static inline struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr
 #define SCM_CREDENTIALS 0x02		/* rw: struct ucred		*/
 #define SCM_SECURITY	0x03		/* rw: security label		*/
 #define SCM_AUDIT	0x04		/* rw: struct uaudit		*/
+#define SCM_PROCINFO	0x05	/* rw: comm + cmdline (NULL terminated
+					   array of char *) */
 
 struct ucred {
 	__u32	pid;
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index 3b9d22a..05c7678 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -27,6 +27,13 @@ struct unix_address {
 	struct sockaddr_un name[0];
 };
 
+struct unix_skb_parms_scm {
+	kuid_t loginuid;
+	unsigned int sessionid;
+	char *procinfo;
+	int procinfo_len;
+};
+
 struct unix_skb_parms {
 	struct pid		*pid;		/* Skb credentials	*/
 	kuid_t			uid;
@@ -36,12 +43,12 @@ struct unix_skb_parms {
 	u32			secid;		/* Security ID		*/
 #endif
 	u32			consumed;
-	kuid_t			loginuid;
-	unsigned int		sessionid;
+	struct unix_skb_parms_scm *scm;
 };
 
 #define UNIXCB(skb) 	(*(struct unix_skb_parms *)&((skb)->cb))
 #define UNIXSID(skb)	(&UNIXCB((skb)).secid)
+#define UNIXSCM(skb)	(*(UNIXCB((skb)).scm))
 
 #define unix_state_lock(s)	spin_lock(&unix_sk(s)->lock)
 #define unix_state_unlock(s)	spin_unlock(&unix_sk(s)->lock)
diff --git a/include/net/scm.h b/include/net/scm.h
index 67de64f..f084e19 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -30,11 +30,17 @@ struct scm_fp_list {
 	struct file		*fp[SCM_MAX_FD];
 };
 
+struct scm_procinfo {
+	char *procinfo;
+	int len;
+};
+
 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	*/
+	struct scm_procinfo	procinfo;	/* Skb procinfo */
 #ifdef CONFIG_SECURITY_NETWORK
 	u32			secid;		/* Passed security ID 	*/
 #endif
@@ -45,6 +51,7 @@ void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm);
 int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm);
 void __scm_destroy(struct scm_cookie *scm);
 struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl);
+int scm_get_current_procinfo(char **procinfo);
 
 #ifdef CONFIG_SECURITY_NETWORK
 static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
@@ -72,10 +79,20 @@ static inline void scm_set_audit(struct scm_cookie *scm,
 	scm->audit.sessionid = sessionid;
 }
 
+static inline void scm_set_procinfo(struct scm_cookie *scm,
+				    char *procinfo, int len)
+{
+	scm->procinfo.procinfo = procinfo;
+	scm->procinfo.len = len;
+}
+
 static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
 {
 	put_pid(scm->pid);
 	scm->pid  = NULL;
+	kfree(scm->procinfo.procinfo);
+	scm->procinfo.procinfo = NULL;
+	scm->procinfo.len = 0;
 }
 
 static __inline__ void scm_destroy(struct scm_cookie *scm)
@@ -88,6 +105,8 @@ static __inline__ void scm_destroy(struct scm_cookie *scm)
 static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
 			       struct scm_cookie *scm, bool forcecreds)
 {
+	char *procinfo;
+	int len;
 	memset(scm, 0, sizeof(*scm));
 	scm->creds.uid = INVALID_UID;
 	scm->creds.gid = INVALID_GID;
@@ -96,6 +115,9 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
 			     current_gid());
 		scm_set_audit(scm, audit_get_loginuid(current),
 			      audit_get_sessionid(current));
+		len = scm_get_current_procinfo(&procinfo);
+		if (len > 0)
+			scm_set_procinfo(scm, procinfo, len);
 	}
 	unix_get_peersec_dgram(sock, scm);
 	if (msg->msg_controllen <= 0)
@@ -148,6 +170,8 @@ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
 		};
 		put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(ucreds), &ucreds);
 		put_cmsg(msg, SOL_SOCKET, SCM_AUDIT, sizeof(uaudits), &uaudits);
+		put_cmsg(msg, SOL_SOCKET, SCM_PROCINFO, scm->procinfo.len,
+				 scm->procinfo.procinfo);
 	}
 
 	scm_destroy_cred(scm);
diff --git a/net/core/scm.c b/net/core/scm.c
index b442e7e..4accb07 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -339,3 +339,68 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)
 	return new_fpl;
 }
 EXPORT_SYMBOL(scm_fp_dup);
+
+int scm_get_current_procinfo(char **procinfo)
+{
+	int res = 0;
+	unsigned int len;
+	char *buffer = NULL;
+	struct mm_struct *mm;
+	int comm_len = strlen(current->comm);
+
+	*procinfo = NULL;
+
+	buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	mm = get_task_mm(current);
+	if (!mm)
+		goto out;
+	if (!mm->arg_end)
+		goto out_mm;    /* Shh! No looking before we're done */
+
+	len = mm->arg_end - mm->arg_start;
+
+	if (len > PAGE_SIZE)
+		len = PAGE_SIZE;
+
+	res = access_process_vm(current, mm->arg_start, buffer, len, 0);
+
+	/* If the nul at the end of args has been overwritten, then
+	 * assume application is using setproctitle(3).
+	 */
+	if (res > 0 && buffer[res-1] != '\0' && len < PAGE_SIZE) {
+		len = strnlen(buffer, res);
+		if (len < res) {
+			res = len;
+		} else {
+			len = mm->env_end - mm->env_start;
+			if (len > PAGE_SIZE - res)
+				len = PAGE_SIZE - res;
+			res += access_process_vm(current, mm->env_start,
+						 buffer+res, len, 0);
+			res = strnlen(buffer, res);
+		}
+	}
+
+	/* strlen(comm) + \0 + len of cmdline */
+	len = comm_len + 1 + res;
+	*procinfo = kmalloc(len, GFP_KERNEL);
+	if (!*procinfo) {
+		res = -ENOMEM;
+		goto out_mm;
+	}
+
+	memcpy(*procinfo, current->comm, comm_len + 1); /* include \0 */
+	if (res > 0)
+		memcpy(*procinfo + comm_len + 1, buffer, res);
+	res = len;
+
+out_mm:
+	mmput(mm);
+out:
+	kfree(buffer);
+	return res;
+}
+EXPORT_SYMBOL(scm_get_current_procinfo);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index bc02a25..35ab97f0 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1361,9 +1361,14 @@ static void unix_destruct_scm(struct sk_buff *skb)
 	struct scm_cookie scm;
 	memset(&scm, 0, sizeof(scm));
 	scm.pid  = UNIXCB(skb).pid;
+	if (UNIXCB(skb).scm) {
+		scm.procinfo.procinfo = UNIXSCM(skb).procinfo;
+		scm.procinfo.len = UNIXSCM(skb).procinfo_len;
+	}
 	if (UNIXCB(skb).fp)
 		unix_detach_fds(&scm, skb);
 
+	kfree(UNIXCB(skb).scm);
 	/* Alas, it calls VFS */
 	/* So fscking what? fput() had been SMP-safe since the last Summer */
 	scm_destroy(&scm);
@@ -1410,15 +1415,31 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen
 {
 	int err = 0;
 
+	if (!UNIXCB(skb).scm) {
+		UNIXCB(skb).scm = kmalloc(sizeof(struct unix_skb_parms_scm),
+					  GFP_KERNEL);
+		if (!UNIXCB(skb).scm)
+			return -ENOMEM;
+	}
+
 	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;
+	UNIXSCM(skb).loginuid = scm->audit.loginuid;
+	UNIXSCM(skb).sessionid = scm->audit.sessionid;
 	UNIXCB(skb).fp = NULL;
 	if (scm->fp && send_fds)
 		err = unix_attach_fds(scm, skb);
 
+	UNIXSCM(skb).procinfo = NULL;
+	if (scm->procinfo.procinfo) {
+		UNIXSCM(skb).procinfo_len = scm->procinfo.len;
+		UNIXSCM(skb).procinfo = kmemdup(scm->procinfo.procinfo,
+					scm->procinfo.len, GFP_KERNEL);
+		if (!UNIXSCM(skb).procinfo)
+			return -ENOMEM;
+	}
+
 	skb->destructor = unix_destruct_scm;
 	return err;
 }
@@ -1438,8 +1459,10 @@ 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);
+		UNIXSCM(skb).loginuid = audit_get_loginuid(current);
+		UNIXSCM(skb).sessionid = audit_get_sessionid(current);
+		UNIXSCM(skb).procinfo_len = scm_get_current_procinfo(
+			&UNIXSCM(skb).procinfo);
 	}
 }
 
@@ -1833,7 +1856,17 @@ 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);
+	if (UNIXCB(skb).scm) {
+		scm_set_audit(siocb->scm, UNIXSCM(skb).loginuid,
+			      UNIXSCM(skb).sessionid);
+		if (UNIXSCM(skb).procinfo) {
+			scm_set_procinfo(siocb->scm,
+					 kmemdup(UNIXSCM(skb).procinfo,
+						 UNIXSCM(skb).procinfo_len,
+						 GFP_KERNEL),
+					 UNIXSCM(skb).procinfo_len);
+		}
+	}
 	unix_set_secdata(siocb->scm, skb);
 
 	if (!(flags & MSG_PEEK)) {
@@ -2013,8 +2046,18 @@ 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);
+			if (UNIXCB(skb).scm) {
+				scm_set_audit(siocb->scm,
+					      UNIXSCM(skb).loginuid,
+					      UNIXSCM(skb).sessionid);
+				if (UNIXSCM(skb).procinfo) {
+					scm_set_procinfo(siocb->scm,
+						kmemdup(UNIXSCM(skb).procinfo,
+						UNIXSCM(skb).procinfo_len,
+						GFP_KERNEL),
+						UNIXSCM(skb).procinfo_len);
+				}
+			}
 			check_creds = 1;
 		}
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH v4 2/3] Send comm and cmdline in SCM_PROCINFO
@ 2014-01-13  8:01         ` Jan Kaluza
  0 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluza @ 2014-01-13  8:01 UTC (permalink / raw)
  To: davem
  Cc: LKML, netdev, eparis, rgb, tj, lizefan, containers, cgroups,
	viro, Jan Kaluza

Server-like processes in many cases need credentials and other
metadata of the peer, to decide if the calling process is allowed to
request a specific action, or the server just wants to log away this
type of information for auditing tasks.

The current practice to retrieve such process metadata is to look that
information up in procfs with the $PID received over SCM_CREDENTIALS.
This is sufficient for long-running tasks, but introduces a race which
cannot be worked around for short-living processes; the calling
process and all the information in /proc/$PID/ is gone before the
receiver of the socket message can look it up.

This introduces a new SCM type called SCM_PROCINFO to allow the direct
attaching of "comm" and "cmdline" to SCM, which is significantly more
efficient and will reliably avoid the race with the round-trip over
procfs.

To achieve that, new struct called unix_skb_parms_scm had to be created,
because otherwise unix_skb_parms would be too big.

scm_get_current_procinfo is inspired by ./fs/proc/base.c.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
---
 include/linux/socket.h |  2 ++
 include/net/af_unix.h  | 11 +++++++--
 include/net/scm.h      | 24 +++++++++++++++++++
 net/core/scm.c         | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++
 net/unix/af_unix.c     | 57 +++++++++++++++++++++++++++++++++++++------
 5 files changed, 150 insertions(+), 9 deletions(-)

diff --git a/include/linux/socket.h b/include/linux/socket.h
index eeac565..5a41f35 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -131,6 +131,8 @@ static inline struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr
 #define SCM_CREDENTIALS 0x02		/* rw: struct ucred		*/
 #define SCM_SECURITY	0x03		/* rw: security label		*/
 #define SCM_AUDIT	0x04		/* rw: struct uaudit		*/
+#define SCM_PROCINFO	0x05	/* rw: comm + cmdline (NULL terminated
+					   array of char *) */
 
 struct ucred {
 	__u32	pid;
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index 3b9d22a..05c7678 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -27,6 +27,13 @@ struct unix_address {
 	struct sockaddr_un name[0];
 };
 
+struct unix_skb_parms_scm {
+	kuid_t loginuid;
+	unsigned int sessionid;
+	char *procinfo;
+	int procinfo_len;
+};
+
 struct unix_skb_parms {
 	struct pid		*pid;		/* Skb credentials	*/
 	kuid_t			uid;
@@ -36,12 +43,12 @@ struct unix_skb_parms {
 	u32			secid;		/* Security ID		*/
 #endif
 	u32			consumed;
-	kuid_t			loginuid;
-	unsigned int		sessionid;
+	struct unix_skb_parms_scm *scm;
 };
 
 #define UNIXCB(skb) 	(*(struct unix_skb_parms *)&((skb)->cb))
 #define UNIXSID(skb)	(&UNIXCB((skb)).secid)
+#define UNIXSCM(skb)	(*(UNIXCB((skb)).scm))
 
 #define unix_state_lock(s)	spin_lock(&unix_sk(s)->lock)
 #define unix_state_unlock(s)	spin_unlock(&unix_sk(s)->lock)
diff --git a/include/net/scm.h b/include/net/scm.h
index 67de64f..f084e19 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -30,11 +30,17 @@ struct scm_fp_list {
 	struct file		*fp[SCM_MAX_FD];
 };
 
+struct scm_procinfo {
+	char *procinfo;
+	int len;
+};
+
 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	*/
+	struct scm_procinfo	procinfo;	/* Skb procinfo */
 #ifdef CONFIG_SECURITY_NETWORK
 	u32			secid;		/* Passed security ID 	*/
 #endif
@@ -45,6 +51,7 @@ void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm);
 int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm);
 void __scm_destroy(struct scm_cookie *scm);
 struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl);
+int scm_get_current_procinfo(char **procinfo);
 
 #ifdef CONFIG_SECURITY_NETWORK
 static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
@@ -72,10 +79,20 @@ static inline void scm_set_audit(struct scm_cookie *scm,
 	scm->audit.sessionid = sessionid;
 }
 
+static inline void scm_set_procinfo(struct scm_cookie *scm,
+				    char *procinfo, int len)
+{
+	scm->procinfo.procinfo = procinfo;
+	scm->procinfo.len = len;
+}
+
 static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
 {
 	put_pid(scm->pid);
 	scm->pid  = NULL;
+	kfree(scm->procinfo.procinfo);
+	scm->procinfo.procinfo = NULL;
+	scm->procinfo.len = 0;
 }
 
 static __inline__ void scm_destroy(struct scm_cookie *scm)
@@ -88,6 +105,8 @@ static __inline__ void scm_destroy(struct scm_cookie *scm)
 static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
 			       struct scm_cookie *scm, bool forcecreds)
 {
+	char *procinfo;
+	int len;
 	memset(scm, 0, sizeof(*scm));
 	scm->creds.uid = INVALID_UID;
 	scm->creds.gid = INVALID_GID;
@@ -96,6 +115,9 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
 			     current_gid());
 		scm_set_audit(scm, audit_get_loginuid(current),
 			      audit_get_sessionid(current));
+		len = scm_get_current_procinfo(&procinfo);
+		if (len > 0)
+			scm_set_procinfo(scm, procinfo, len);
 	}
 	unix_get_peersec_dgram(sock, scm);
 	if (msg->msg_controllen <= 0)
@@ -148,6 +170,8 @@ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
 		};
 		put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(ucreds), &ucreds);
 		put_cmsg(msg, SOL_SOCKET, SCM_AUDIT, sizeof(uaudits), &uaudits);
+		put_cmsg(msg, SOL_SOCKET, SCM_PROCINFO, scm->procinfo.len,
+				 scm->procinfo.procinfo);
 	}
 
 	scm_destroy_cred(scm);
diff --git a/net/core/scm.c b/net/core/scm.c
index b442e7e..4accb07 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -339,3 +339,68 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)
 	return new_fpl;
 }
 EXPORT_SYMBOL(scm_fp_dup);
+
+int scm_get_current_procinfo(char **procinfo)
+{
+	int res = 0;
+	unsigned int len;
+	char *buffer = NULL;
+	struct mm_struct *mm;
+	int comm_len = strlen(current->comm);
+
+	*procinfo = NULL;
+
+	buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	mm = get_task_mm(current);
+	if (!mm)
+		goto out;
+	if (!mm->arg_end)
+		goto out_mm;    /* Shh! No looking before we're done */
+
+	len = mm->arg_end - mm->arg_start;
+
+	if (len > PAGE_SIZE)
+		len = PAGE_SIZE;
+
+	res = access_process_vm(current, mm->arg_start, buffer, len, 0);
+
+	/* If the nul at the end of args has been overwritten, then
+	 * assume application is using setproctitle(3).
+	 */
+	if (res > 0 && buffer[res-1] != '\0' && len < PAGE_SIZE) {
+		len = strnlen(buffer, res);
+		if (len < res) {
+			res = len;
+		} else {
+			len = mm->env_end - mm->env_start;
+			if (len > PAGE_SIZE - res)
+				len = PAGE_SIZE - res;
+			res += access_process_vm(current, mm->env_start,
+						 buffer+res, len, 0);
+			res = strnlen(buffer, res);
+		}
+	}
+
+	/* strlen(comm) + \0 + len of cmdline */
+	len = comm_len + 1 + res;
+	*procinfo = kmalloc(len, GFP_KERNEL);
+	if (!*procinfo) {
+		res = -ENOMEM;
+		goto out_mm;
+	}
+
+	memcpy(*procinfo, current->comm, comm_len + 1); /* include \0 */
+	if (res > 0)
+		memcpy(*procinfo + comm_len + 1, buffer, res);
+	res = len;
+
+out_mm:
+	mmput(mm);
+out:
+	kfree(buffer);
+	return res;
+}
+EXPORT_SYMBOL(scm_get_current_procinfo);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index bc02a25..35ab97f0 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1361,9 +1361,14 @@ static void unix_destruct_scm(struct sk_buff *skb)
 	struct scm_cookie scm;
 	memset(&scm, 0, sizeof(scm));
 	scm.pid  = UNIXCB(skb).pid;
+	if (UNIXCB(skb).scm) {
+		scm.procinfo.procinfo = UNIXSCM(skb).procinfo;
+		scm.procinfo.len = UNIXSCM(skb).procinfo_len;
+	}
 	if (UNIXCB(skb).fp)
 		unix_detach_fds(&scm, skb);
 
+	kfree(UNIXCB(skb).scm);
 	/* Alas, it calls VFS */
 	/* So fscking what? fput() had been SMP-safe since the last Summer */
 	scm_destroy(&scm);
@@ -1410,15 +1415,31 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen
 {
 	int err = 0;
 
+	if (!UNIXCB(skb).scm) {
+		UNIXCB(skb).scm = kmalloc(sizeof(struct unix_skb_parms_scm),
+					  GFP_KERNEL);
+		if (!UNIXCB(skb).scm)
+			return -ENOMEM;
+	}
+
 	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;
+	UNIXSCM(skb).loginuid = scm->audit.loginuid;
+	UNIXSCM(skb).sessionid = scm->audit.sessionid;
 	UNIXCB(skb).fp = NULL;
 	if (scm->fp && send_fds)
 		err = unix_attach_fds(scm, skb);
 
+	UNIXSCM(skb).procinfo = NULL;
+	if (scm->procinfo.procinfo) {
+		UNIXSCM(skb).procinfo_len = scm->procinfo.len;
+		UNIXSCM(skb).procinfo = kmemdup(scm->procinfo.procinfo,
+					scm->procinfo.len, GFP_KERNEL);
+		if (!UNIXSCM(skb).procinfo)
+			return -ENOMEM;
+	}
+
 	skb->destructor = unix_destruct_scm;
 	return err;
 }
@@ -1438,8 +1459,10 @@ 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);
+		UNIXSCM(skb).loginuid = audit_get_loginuid(current);
+		UNIXSCM(skb).sessionid = audit_get_sessionid(current);
+		UNIXSCM(skb).procinfo_len = scm_get_current_procinfo(
+			&UNIXSCM(skb).procinfo);
 	}
 }
 
@@ -1833,7 +1856,17 @@ 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);
+	if (UNIXCB(skb).scm) {
+		scm_set_audit(siocb->scm, UNIXSCM(skb).loginuid,
+			      UNIXSCM(skb).sessionid);
+		if (UNIXSCM(skb).procinfo) {
+			scm_set_procinfo(siocb->scm,
+					 kmemdup(UNIXSCM(skb).procinfo,
+						 UNIXSCM(skb).procinfo_len,
+						 GFP_KERNEL),
+					 UNIXSCM(skb).procinfo_len);
+		}
+	}
 	unix_set_secdata(siocb->scm, skb);
 
 	if (!(flags & MSG_PEEK)) {
@@ -2013,8 +2046,18 @@ 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);
+			if (UNIXCB(skb).scm) {
+				scm_set_audit(siocb->scm,
+					      UNIXSCM(skb).loginuid,
+					      UNIXSCM(skb).sessionid);
+				if (UNIXSCM(skb).procinfo) {
+					scm_set_procinfo(siocb->scm,
+						kmemdup(UNIXSCM(skb).procinfo,
+						UNIXSCM(skb).procinfo_len,
+						GFP_KERNEL),
+						UNIXSCM(skb).procinfo_len);
+				}
+			}
 			check_creds = 1;
 		}
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH v4 3/3] Send cgroup_path in SCM_CGROUP
  2014-01-13  8:01     ` Jan Kaluza
@ 2014-01-13  8:01         ` Jan Kaluza
  -1 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluza @ 2014-01-13  8:01 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: Jan Kaluza, rgb-H+wXaHxf7aLQT0dZR+AlfA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, tj-DgEjT+Ai2ygdnm+yROfE0A,
	cgroups-u79uwXL29TY76Z2rM5mHXA

Server-like processes in many cases need credentials and other
metadata of the peer, to decide if the calling process is allowed to
request a specific action, or the server just wants to log away this
type of information for auditing tasks.

The current practice to retrieve such process metadata is to look that
information up in procfs with the $PID received over SCM_CREDENTIALS.
This is sufficient for long-running tasks, but introduces a race which
cannot be worked around for short-living processes; the calling
process and all the information in /proc/$PID/ is gone before the
receiver of the socket message can look it up.

This introduces a new SCM type called SCM_CGROUP to allow the direct
attaching of "cgroup_path" to SCM, which is significantly more
efficient and will reliably avoid the race with the round-trip over
procfs.

Signed-off-by: Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 include/linux/socket.h |  1 +
 include/net/af_unix.h  |  1 +
 include/net/scm.h      | 15 +++++++++++++++
 net/core/scm.c         | 18 ++++++++++++++++++
 net/unix/af_unix.c     | 20 ++++++++++++++++++++
 5 files changed, 55 insertions(+)

diff --git a/include/linux/socket.h b/include/linux/socket.h
index 5a41f35..b015ed4 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -133,6 +133,7 @@ static inline struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr
 #define SCM_AUDIT	0x04		/* rw: struct uaudit		*/
 #define SCM_PROCINFO	0x05	/* rw: comm + cmdline (NULL terminated
 					   array of char *) */
+#define SCM_CGROUP	0x06		/* rw: cgroup path */
 
 struct ucred {
 	__u32	pid;
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index 05c7678..c49bf35 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -32,6 +32,7 @@ struct unix_skb_parms_scm {
 	unsigned int sessionid;
 	char *procinfo;
 	int procinfo_len;
+	char *cgroup_path;
 };
 
 struct unix_skb_parms {
diff --git a/include/net/scm.h b/include/net/scm.h
index f084e19..359048d 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -41,6 +41,7 @@ struct scm_cookie {
 	struct scm_creds	creds;		/* Skb credentials	*/
 	struct scm_audit	audit;		/* Skb audit	*/
 	struct scm_procinfo	procinfo;	/* Skb procinfo */
+	char *cgroup_path;
 #ifdef CONFIG_SECURITY_NETWORK
 	u32			secid;		/* Passed security ID 	*/
 #endif
@@ -52,6 +53,7 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm);
 void __scm_destroy(struct scm_cookie *scm);
 struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl);
 int scm_get_current_procinfo(char **procinfo);
+int scm_get_current_cgroup_path(char **cgroup_path);
 
 #ifdef CONFIG_SECURITY_NETWORK
 static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
@@ -86,6 +88,12 @@ static inline void scm_set_procinfo(struct scm_cookie *scm,
 	scm->procinfo.len = len;
 }
 
+static inline void scm_set_cgroup_path(struct scm_cookie *scm,
+				    char *cgroup_path)
+{
+	scm->cgroup_path = cgroup_path;
+}
+
 static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
 {
 	put_pid(scm->pid);
@@ -140,6 +148,9 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc
 			security_release_secctx(secdata, seclen);
 		}
 	}
+
+	kfree(scm->cgroup_path);
+	scm->cgroup_path = NULL;
 }
 #else
 static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
@@ -172,6 +183,10 @@ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
 		put_cmsg(msg, SOL_SOCKET, SCM_AUDIT, sizeof(uaudits), &uaudits);
 		put_cmsg(msg, SOL_SOCKET, SCM_PROCINFO, scm->procinfo.len,
 				 scm->procinfo.procinfo);
+		if (scm->cgroup_path) {
+			put_cmsg(msg, SOL_SOCKET, SCM_CGROUP,
+				 strlen(scm->cgroup_path), scm->cgroup_path);
+		}
 	}
 
 	scm_destroy_cred(scm);
diff --git a/net/core/scm.c b/net/core/scm.c
index 4accb07..78e206a 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -404,3 +404,21 @@ out:
 	return res;
 }
 EXPORT_SYMBOL(scm_get_current_procinfo);
+
+int scm_get_current_cgroup_path(char **cgroup_path)
+{
+	int ret = 0;
+
+	*cgroup_path = kmalloc(PATH_MAX, GFP_KERNEL);
+	if (!(*cgroup_path))
+		return -ENOMEM;
+
+	ret = task_cgroup_path(current, *cgroup_path, PATH_MAX);
+	if (ret < 0) {
+		kfree(*cgroup_path);
+		*cgroup_path = NULL;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(scm_get_current_cgroup_path);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 35ab97f0..b04f55e 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1364,6 +1364,7 @@ static void unix_destruct_scm(struct sk_buff *skb)
 	if (UNIXCB(skb).scm) {
 		scm.procinfo.procinfo = UNIXSCM(skb).procinfo;
 		scm.procinfo.len = UNIXSCM(skb).procinfo_len;
+		scm.cgroup_path = UNIXSCM(skb).cgroup_path;
 	}
 	if (UNIXCB(skb).fp)
 		unix_detach_fds(&scm, skb);
@@ -1440,6 +1441,14 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen
 			return -ENOMEM;
 	}
 
+	UNIXSCM(skb).cgroup_path = NULL;
+	if (scm->cgroup_path) {
+		UNIXSCM(skb).cgroup_path = kstrdup(scm->cgroup_path,
+						   GFP_KERNEL);
+		if (!UNIXSCM(skb).cgroup_path)
+			return -ENOMEM;
+	}
+
 	skb->destructor = unix_destruct_scm;
 	return err;
 }
@@ -1463,6 +1472,7 @@ static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
 		UNIXSCM(skb).sessionid = audit_get_sessionid(current);
 		UNIXSCM(skb).procinfo_len = scm_get_current_procinfo(
 			&UNIXSCM(skb).procinfo);
+		scm_get_current_cgroup_path(&UNIXSCM(skb).cgroup_path);
 	}
 }
 
@@ -1866,6 +1876,11 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
 						 GFP_KERNEL),
 					 UNIXSCM(skb).procinfo_len);
 		}
+		if (UNIXSCM(skb).cgroup_path) {
+			scm_set_cgroup_path(siocb->scm,
+					    kstrdup(UNIXSCM(skb).cgroup_path,
+						    GFP_KERNEL));
+		}
 	}
 	unix_set_secdata(siocb->scm, skb);
 
@@ -2057,6 +2072,11 @@ again:
 						GFP_KERNEL),
 						UNIXSCM(skb).procinfo_len);
 				}
+				if (UNIXSCM(skb).cgroup_path) {
+					scm_set_cgroup_path(siocb->scm,
+							    kstrdup(UNIXSCM(skb).cgroup_path,
+							    GFP_KERNEL));
+				}
 			}
 			check_creds = 1;
 		}
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 79+ messages in thread

* [PATCH v4 3/3] Send cgroup_path in SCM_CGROUP
@ 2014-01-13  8:01         ` Jan Kaluza
  0 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluza @ 2014-01-13  8:01 UTC (permalink / raw)
  To: davem
  Cc: LKML, netdev, eparis, rgb, tj, lizefan, containers, cgroups,
	viro, Jan Kaluza

Server-like processes in many cases need credentials and other
metadata of the peer, to decide if the calling process is allowed to
request a specific action, or the server just wants to log away this
type of information for auditing tasks.

The current practice to retrieve such process metadata is to look that
information up in procfs with the $PID received over SCM_CREDENTIALS.
This is sufficient for long-running tasks, but introduces a race which
cannot be worked around for short-living processes; the calling
process and all the information in /proc/$PID/ is gone before the
receiver of the socket message can look it up.

This introduces a new SCM type called SCM_CGROUP to allow the direct
attaching of "cgroup_path" to SCM, which is significantly more
efficient and will reliably avoid the race with the round-trip over
procfs.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
---
 include/linux/socket.h |  1 +
 include/net/af_unix.h  |  1 +
 include/net/scm.h      | 15 +++++++++++++++
 net/core/scm.c         | 18 ++++++++++++++++++
 net/unix/af_unix.c     | 20 ++++++++++++++++++++
 5 files changed, 55 insertions(+)

diff --git a/include/linux/socket.h b/include/linux/socket.h
index 5a41f35..b015ed4 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -133,6 +133,7 @@ static inline struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr
 #define SCM_AUDIT	0x04		/* rw: struct uaudit		*/
 #define SCM_PROCINFO	0x05	/* rw: comm + cmdline (NULL terminated
 					   array of char *) */
+#define SCM_CGROUP	0x06		/* rw: cgroup path */
 
 struct ucred {
 	__u32	pid;
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index 05c7678..c49bf35 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -32,6 +32,7 @@ struct unix_skb_parms_scm {
 	unsigned int sessionid;
 	char *procinfo;
 	int procinfo_len;
+	char *cgroup_path;
 };
 
 struct unix_skb_parms {
diff --git a/include/net/scm.h b/include/net/scm.h
index f084e19..359048d 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -41,6 +41,7 @@ struct scm_cookie {
 	struct scm_creds	creds;		/* Skb credentials	*/
 	struct scm_audit	audit;		/* Skb audit	*/
 	struct scm_procinfo	procinfo;	/* Skb procinfo */
+	char *cgroup_path;
 #ifdef CONFIG_SECURITY_NETWORK
 	u32			secid;		/* Passed security ID 	*/
 #endif
@@ -52,6 +53,7 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm);
 void __scm_destroy(struct scm_cookie *scm);
 struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl);
 int scm_get_current_procinfo(char **procinfo);
+int scm_get_current_cgroup_path(char **cgroup_path);
 
 #ifdef CONFIG_SECURITY_NETWORK
 static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
@@ -86,6 +88,12 @@ static inline void scm_set_procinfo(struct scm_cookie *scm,
 	scm->procinfo.len = len;
 }
 
+static inline void scm_set_cgroup_path(struct scm_cookie *scm,
+				    char *cgroup_path)
+{
+	scm->cgroup_path = cgroup_path;
+}
+
 static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
 {
 	put_pid(scm->pid);
@@ -140,6 +148,9 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc
 			security_release_secctx(secdata, seclen);
 		}
 	}
+
+	kfree(scm->cgroup_path);
+	scm->cgroup_path = NULL;
 }
 #else
 static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
@@ -172,6 +183,10 @@ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
 		put_cmsg(msg, SOL_SOCKET, SCM_AUDIT, sizeof(uaudits), &uaudits);
 		put_cmsg(msg, SOL_SOCKET, SCM_PROCINFO, scm->procinfo.len,
 				 scm->procinfo.procinfo);
+		if (scm->cgroup_path) {
+			put_cmsg(msg, SOL_SOCKET, SCM_CGROUP,
+				 strlen(scm->cgroup_path), scm->cgroup_path);
+		}
 	}
 
 	scm_destroy_cred(scm);
diff --git a/net/core/scm.c b/net/core/scm.c
index 4accb07..78e206a 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -404,3 +404,21 @@ out:
 	return res;
 }
 EXPORT_SYMBOL(scm_get_current_procinfo);
+
+int scm_get_current_cgroup_path(char **cgroup_path)
+{
+	int ret = 0;
+
+	*cgroup_path = kmalloc(PATH_MAX, GFP_KERNEL);
+	if (!(*cgroup_path))
+		return -ENOMEM;
+
+	ret = task_cgroup_path(current, *cgroup_path, PATH_MAX);
+	if (ret < 0) {
+		kfree(*cgroup_path);
+		*cgroup_path = NULL;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(scm_get_current_cgroup_path);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 35ab97f0..b04f55e 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1364,6 +1364,7 @@ static void unix_destruct_scm(struct sk_buff *skb)
 	if (UNIXCB(skb).scm) {
 		scm.procinfo.procinfo = UNIXSCM(skb).procinfo;
 		scm.procinfo.len = UNIXSCM(skb).procinfo_len;
+		scm.cgroup_path = UNIXSCM(skb).cgroup_path;
 	}
 	if (UNIXCB(skb).fp)
 		unix_detach_fds(&scm, skb);
@@ -1440,6 +1441,14 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen
 			return -ENOMEM;
 	}
 
+	UNIXSCM(skb).cgroup_path = NULL;
+	if (scm->cgroup_path) {
+		UNIXSCM(skb).cgroup_path = kstrdup(scm->cgroup_path,
+						   GFP_KERNEL);
+		if (!UNIXSCM(skb).cgroup_path)
+			return -ENOMEM;
+	}
+
 	skb->destructor = unix_destruct_scm;
 	return err;
 }
@@ -1463,6 +1472,7 @@ static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
 		UNIXSCM(skb).sessionid = audit_get_sessionid(current);
 		UNIXSCM(skb).procinfo_len = scm_get_current_procinfo(
 			&UNIXSCM(skb).procinfo);
+		scm_get_current_cgroup_path(&UNIXSCM(skb).cgroup_path);
 	}
 }
 
@@ -1866,6 +1876,11 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
 						 GFP_KERNEL),
 					 UNIXSCM(skb).procinfo_len);
 		}
+		if (UNIXSCM(skb).cgroup_path) {
+			scm_set_cgroup_path(siocb->scm,
+					    kstrdup(UNIXSCM(skb).cgroup_path,
+						    GFP_KERNEL));
+		}
 	}
 	unix_set_secdata(siocb->scm, skb);
 
@@ -2057,6 +2072,11 @@ again:
 						GFP_KERNEL),
 						UNIXSCM(skb).procinfo_len);
 				}
+				if (UNIXSCM(skb).cgroup_path) {
+					scm_set_cgroup_path(siocb->scm,
+							    kstrdup(UNIXSCM(skb).cgroup_path,
+							    GFP_KERNEL));
+				}
 			}
 			check_creds = 1;
 		}
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 79+ messages in thread

* Re: [PATCH v4 3/3] Send cgroup_path in SCM_CGROUP
  2014-01-13  8:01         ` Jan Kaluza
@ 2014-01-13 16:52             ` Tejun Heo
  -1 siblings, 0 replies; 79+ messages in thread
From: Tejun Heo @ 2014-01-13 16:52 UTC (permalink / raw)
  To: Jan Kaluza
  Cc: rgb-H+wXaHxf7aLQT0dZR+AlfA, netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
	cgroups-u79uwXL29TY76Z2rM5mHXA, davem-fT/PcQaiUtIeIZ0/mPfg9Q

On Mon, Jan 13, 2014 at 09:01:49AM +0100, Jan Kaluza wrote:
> Server-like processes in many cases need credentials and other
> metadata of the peer, to decide if the calling process is allowed to
> request a specific action, or the server just wants to log away this
> type of information for auditing tasks.
> 
> The current practice to retrieve such process metadata is to look that
> information up in procfs with the $PID received over SCM_CREDENTIALS.
> This is sufficient for long-running tasks, but introduces a race which
> cannot be worked around for short-living processes; the calling
> process and all the information in /proc/$PID/ is gone before the
> receiver of the socket message can look it up.
> 
> This introduces a new SCM type called SCM_CGROUP to allow the direct
> attaching of "cgroup_path" to SCM, which is significantly more
> efficient and will reliably avoid the race with the round-trip over
> procfs.
> 
> Signed-off-by: Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

For cgroup related part:

 Acked-by: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v4 3/3] Send cgroup_path in SCM_CGROUP
@ 2014-01-13 16:52             ` Tejun Heo
  0 siblings, 0 replies; 79+ messages in thread
From: Tejun Heo @ 2014-01-13 16:52 UTC (permalink / raw)
  To: Jan Kaluza
  Cc: davem, LKML, netdev, eparis, rgb, lizefan, containers, cgroups, viro

On Mon, Jan 13, 2014 at 09:01:49AM +0100, Jan Kaluza wrote:
> Server-like processes in many cases need credentials and other
> metadata of the peer, to decide if the calling process is allowed to
> request a specific action, or the server just wants to log away this
> type of information for auditing tasks.
> 
> The current practice to retrieve such process metadata is to look that
> information up in procfs with the $PID received over SCM_CREDENTIALS.
> This is sufficient for long-running tasks, but introduces a race which
> cannot be worked around for short-living processes; the calling
> process and all the information in /proc/$PID/ is gone before the
> receiver of the socket message can look it up.
> 
> This introduces a new SCM type called SCM_CGROUP to allow the direct
> attaching of "cgroup_path" to SCM, which is significantly more
> efficient and will reliably avoid the race with the round-trip over
> procfs.
> 
> Signed-off-by: Jan Kaluza <jkaluza@redhat.com>

For cgroup related part:

 Acked-by: Tejun Heo <tj@kernel.org>

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message
  2014-01-13  8:01     ` Jan Kaluza
@ 2014-01-13 16:55         ` Tejun Heo
  -1 siblings, 0 replies; 79+ messages in thread
From: Tejun Heo @ 2014-01-13 16:55 UTC (permalink / raw)
  To: Jan Kaluza
  Cc: rgb-H+wXaHxf7aLQT0dZR+AlfA, netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
	cgroups-u79uwXL29TY76Z2rM5mHXA, davem-fT/PcQaiUtIeIZ0/mPfg9Q

Hello,

On Mon, Jan 13, 2014 at 09:01:46AM +0100, Jan Kaluza wrote:
> this patchset against net-next (applies also to linux-next) adds 3 new types
> of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).
> 
> Server-like processes in many cases need credentials and other
> metadata of the peer, to decide if the calling process is allowed to
> request a specific action, or the server just wants to log away this
> type of information for auditing tasks.
> 
> The current practice to retrieve such process metadata is to look that
> information up in procfs with the $PID received over SCM_CREDENTIALS.
> This is sufficient for long-running tasks, but introduces a race which
> cannot be worked around for short-living processes; the calling
> process and all the information in /proc/$PID/ is gone before the
> receiver of the socket message can look it up.
> 
> Changes introduced in this patchset can also increase performance
> of such server-like processes, because current way of opening and
> parsing /proc/$PID/* files is much more expensive than receiving these
> metadata using SCM.

Closing the race sounds like a good idea to me.  What do net people
think?

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message
@ 2014-01-13 16:55         ` Tejun Heo
  0 siblings, 0 replies; 79+ messages in thread
From: Tejun Heo @ 2014-01-13 16:55 UTC (permalink / raw)
  To: Jan Kaluza
  Cc: davem, LKML, netdev, eparis, rgb, lizefan, containers, cgroups, viro

Hello,

On Mon, Jan 13, 2014 at 09:01:46AM +0100, Jan Kaluza wrote:
> this patchset against net-next (applies also to linux-next) adds 3 new types
> of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).
> 
> Server-like processes in many cases need credentials and other
> metadata of the peer, to decide if the calling process is allowed to
> request a specific action, or the server just wants to log away this
> type of information for auditing tasks.
> 
> The current practice to retrieve such process metadata is to look that
> information up in procfs with the $PID received over SCM_CREDENTIALS.
> This is sufficient for long-running tasks, but introduces a race which
> cannot be worked around for short-living processes; the calling
> process and all the information in /proc/$PID/ is gone before the
> receiver of the socket message can look it up.
> 
> Changes introduced in this patchset can also increase performance
> of such server-like processes, because current way of opening and
> parsing /proc/$PID/* files is much more expensive than receiving these
> metadata using SCM.

Closing the race sounds like a good idea to me.  What do net people
think?

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message
       [not found]     ` <1389600109-30739-1-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
                         ` (3 preceding siblings ...)
  2014-01-13 16:55         ` Tejun Heo
@ 2014-01-13 19:44       ` Casey Schaufler
  2014-01-15 20:17         ` David Miller
  5 siblings, 0 replies; 79+ messages in thread
From: Casey Schaufler @ 2014-01-13 19:44 UTC (permalink / raw)
  To: Jan Kaluza, davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: rgb-H+wXaHxf7aLQT0dZR+AlfA, netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, tj-DgEjT+Ai2ygdnm+yROfE0A,
	cgroups-u79uwXL29TY76Z2rM5mHXA

On 1/13/2014 12:01 AM, Jan Kaluza wrote:
> Hi,
>
> this patchset against net-next (applies also to linux-next) adds 3 new types
> of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).

How about the group list, while you're at it?

>
> Server-like processes in many cases need credentials and other
> metadata of the peer, to decide if the calling process is allowed to
> request a specific action, or the server just wants to log away this
> type of information for auditing tasks.
>
> The current practice to retrieve such process metadata is to look that
> information up in procfs with the $PID received over SCM_CREDENTIALS.
> This is sufficient for long-running tasks, but introduces a race which
> cannot be worked around for short-living processes; the calling
> process and all the information in /proc/$PID/ is gone before the
> receiver of the socket message can look it up.
>
> Changes introduced in this patchset can also increase performance
> of such server-like processes, because current way of opening and
> parsing /proc/$PID/* files is much more expensive than receiving these
> metadata using SCM.
>
> Changes in v4:
> - Rebased to work with the latest net-next tree
>
> Changes in v3:
> - Better description of patches (Thanks to Kay Sievers)
>
> Changes in v2:
> - use PATH_MAX instead of PAGE_SIZE in SCM_CGROUP patch
> - describe each patch individually
>
> Jan Kaluza (3):
>   Send loginuid and sessionid in SCM_AUDIT
>   Send comm and cmdline in SCM_PROCINFO
>   Send cgroup_path in SCM_CGROUP
>
>  include/linux/socket.h |  9 ++++++
>  include/net/af_unix.h  | 10 ++++++
>  include/net/scm.h      | 67 ++++++++++++++++++++++++++++++++++++++--
>  net/core/scm.c         | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  net/unix/af_unix.c     | 70 ++++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 237 insertions(+), 2 deletions(-)
>

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message
  2014-01-13  8:01     ` Jan Kaluza
  (?)
  (?)
@ 2014-01-13 19:44     ` Casey Schaufler
       [not found]       ` <52D44206.2000906-iSGtlc1asvQWG2LlvL+J4A@public.gmane.org>
  -1 siblings, 1 reply; 79+ messages in thread
From: Casey Schaufler @ 2014-01-13 19:44 UTC (permalink / raw)
  To: Jan Kaluza, davem
  Cc: LKML, netdev, eparis, rgb, tj, lizefan, containers, cgroups, viro

On 1/13/2014 12:01 AM, Jan Kaluza wrote:
> Hi,
>
> this patchset against net-next (applies also to linux-next) adds 3 new types
> of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).

How about the group list, while you're at it?

>
> Server-like processes in many cases need credentials and other
> metadata of the peer, to decide if the calling process is allowed to
> request a specific action, or the server just wants to log away this
> type of information for auditing tasks.
>
> The current practice to retrieve such process metadata is to look that
> information up in procfs with the $PID received over SCM_CREDENTIALS.
> This is sufficient for long-running tasks, but introduces a race which
> cannot be worked around for short-living processes; the calling
> process and all the information in /proc/$PID/ is gone before the
> receiver of the socket message can look it up.
>
> Changes introduced in this patchset can also increase performance
> of such server-like processes, because current way of opening and
> parsing /proc/$PID/* files is much more expensive than receiving these
> metadata using SCM.
>
> Changes in v4:
> - Rebased to work with the latest net-next tree
>
> Changes in v3:
> - Better description of patches (Thanks to Kay Sievers)
>
> Changes in v2:
> - use PATH_MAX instead of PAGE_SIZE in SCM_CGROUP patch
> - describe each patch individually
>
> Jan Kaluza (3):
>   Send loginuid and sessionid in SCM_AUDIT
>   Send comm and cmdline in SCM_PROCINFO
>   Send cgroup_path in SCM_CGROUP
>
>  include/linux/socket.h |  9 ++++++
>  include/net/af_unix.h  | 10 ++++++
>  include/net/scm.h      | 67 ++++++++++++++++++++++++++++++++++++++--
>  net/core/scm.c         | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  net/unix/af_unix.c     | 70 ++++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 237 insertions(+), 2 deletions(-)
>


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message
  2014-01-13 19:44     ` Casey Schaufler
@ 2014-01-14  8:25           ` Jan Kaluža
  0 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluža @ 2014-01-14  8:25 UTC (permalink / raw)
  To: Casey Schaufler, davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: rgb-H+wXaHxf7aLQT0dZR+AlfA, netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, tj-DgEjT+Ai2ygdnm+yROfE0A,
	cgroups-u79uwXL29TY76Z2rM5mHXA

On 01/13/2014 08:44 PM, Casey Schaufler wrote:
> On 1/13/2014 12:01 AM, Jan Kaluza wrote:
>> Hi,
>>
>> this patchset against net-next (applies also to linux-next) adds 3 new types
>> of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).
>
> How about the group list, while you're at it?

That would be of course possible, but I would rather start with these 
three patches at the beginning before adding more features, because I'm 
not sure if there is consensus on accepting them. But I have no problem 
with introducing group list later.

>>
>> Server-like processes in many cases need credentials and other
>> metadata of the peer, to decide if the calling process is allowed to
>> request a specific action, or the server just wants to log away this
>> type of information for auditing tasks.
>>
>> The current practice to retrieve such process metadata is to look that
>> information up in procfs with the $PID received over SCM_CREDENTIALS.
>> This is sufficient for long-running tasks, but introduces a race which
>> cannot be worked around for short-living processes; the calling
>> process and all the information in /proc/$PID/ is gone before the
>> receiver of the socket message can look it up.
>>
>> Changes introduced in this patchset can also increase performance
>> of such server-like processes, because current way of opening and
>> parsing /proc/$PID/* files is much more expensive than receiving these
>> metadata using SCM.
>>
>> Changes in v4:
>> - Rebased to work with the latest net-next tree
>>
>> Changes in v3:
>> - Better description of patches (Thanks to Kay Sievers)
>>
>> Changes in v2:
>> - use PATH_MAX instead of PAGE_SIZE in SCM_CGROUP patch
>> - describe each patch individually
>>
>> Jan Kaluza (3):
>>    Send loginuid and sessionid in SCM_AUDIT
>>    Send comm and cmdline in SCM_PROCINFO
>>    Send cgroup_path in SCM_CGROUP
>>
>>   include/linux/socket.h |  9 ++++++
>>   include/net/af_unix.h  | 10 ++++++
>>   include/net/scm.h      | 67 ++++++++++++++++++++++++++++++++++++++--
>>   net/core/scm.c         | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++
>>   net/unix/af_unix.c     | 70 ++++++++++++++++++++++++++++++++++++++++++
>>   5 files changed, 237 insertions(+), 2 deletions(-)
>>
>

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message
@ 2014-01-14  8:25           ` Jan Kaluža
  0 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluža @ 2014-01-14  8:25 UTC (permalink / raw)
  To: Casey Schaufler, davem
  Cc: LKML, netdev, eparis, rgb, tj, lizefan, containers, cgroups, viro

On 01/13/2014 08:44 PM, Casey Schaufler wrote:
> On 1/13/2014 12:01 AM, Jan Kaluza wrote:
>> Hi,
>>
>> this patchset against net-next (applies also to linux-next) adds 3 new types
>> of "Socket"-level control message (SCM_AUDIT, SCM_PROCINFO and SCM_CGROUP).
>
> How about the group list, while you're at it?

That would be of course possible, but I would rather start with these 
three patches at the beginning before adding more features, because I'm 
not sure if there is consensus on accepting them. But I have no problem 
with introducing group list later.

>>
>> Server-like processes in many cases need credentials and other
>> metadata of the peer, to decide if the calling process is allowed to
>> request a specific action, or the server just wants to log away this
>> type of information for auditing tasks.
>>
>> The current practice to retrieve such process metadata is to look that
>> information up in procfs with the $PID received over SCM_CREDENTIALS.
>> This is sufficient for long-running tasks, but introduces a race which
>> cannot be worked around for short-living processes; the calling
>> process and all the information in /proc/$PID/ is gone before the
>> receiver of the socket message can look it up.
>>
>> Changes introduced in this patchset can also increase performance
>> of such server-like processes, because current way of opening and
>> parsing /proc/$PID/* files is much more expensive than receiving these
>> metadata using SCM.
>>
>> Changes in v4:
>> - Rebased to work with the latest net-next tree
>>
>> Changes in v3:
>> - Better description of patches (Thanks to Kay Sievers)
>>
>> Changes in v2:
>> - use PATH_MAX instead of PAGE_SIZE in SCM_CGROUP patch
>> - describe each patch individually
>>
>> Jan Kaluza (3):
>>    Send loginuid and sessionid in SCM_AUDIT
>>    Send comm and cmdline in SCM_PROCINFO
>>    Send cgroup_path in SCM_CGROUP
>>
>>   include/linux/socket.h |  9 ++++++
>>   include/net/af_unix.h  | 10 ++++++
>>   include/net/scm.h      | 67 ++++++++++++++++++++++++++++++++++++++--
>>   net/core/scm.c         | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++
>>   net/unix/af_unix.c     | 70 ++++++++++++++++++++++++++++++++++++++++++
>>   5 files changed, 237 insertions(+), 2 deletions(-)
>>
>


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v4 1/3] Send loginuid and sessionid in SCM_AUDIT
  2014-01-13  8:01         ` Jan Kaluza
@ 2014-01-15  4:02             ` Richard Guy Briggs
  -1 siblings, 0 replies; 79+ messages in thread
From: Richard Guy Briggs @ 2014-01-15  4:02 UTC (permalink / raw)
  To: Jan Kaluza
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, tj-DgEjT+Ai2ygdnm+yROfE0A,
	cgroups-u79uwXL29TY76Z2rM5mHXA, davem-fT/PcQaiUtIeIZ0/mPfg9Q

On 14/01/13, Jan Kaluza wrote:
> Server-like processes in many cases need credentials and other
> metadata of the peer, to decide if the calling process is allowed to
> request a specific action, or the server just wants to log away this
> type of information for auditing tasks.
> 
> The current practice to retrieve such process metadata is to look that
> information up in procfs with the $PID received over SCM_CREDENTIALS.
> This is sufficient for long-running tasks, but introduces a race which
> cannot be worked around for short-living processes; the calling
> process and all the information in /proc/$PID/ is gone before the
> receiver of the socket message can look it up.
> 
> This introduces a new SCM type called SCM_AUDIT to allow the direct
> attaching of "loginuid" and "sessionid" to SCM, which is significantly more
> efficient and will reliably avoid the race with the round-trip over
> procfs.
> 
> Signed-off-by: Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

Acked-by: Richard Guy Briggs <rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

> ---
>  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 5d488a6..eeac565 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 262532d..67de64f 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 800ca61..bc02a25 100644
> --- a/net/unix/af_unix.c
> +++ b/net/unix/af_unix.c
> @@ -1413,6 +1413,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);
> @@ -1436,6 +1438,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);
>  	}
>  }
>  
> @@ -1829,6 +1833,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)) {
> @@ -2008,6 +2013,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
> 

- RGB

--
Richard Guy Briggs <rbriggs-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Senior Software Engineer, Kernel Security, AMER ENG Base Operating Systems, Red Hat
Remote, Ottawa, Canada
Voice: +1.647.777.2635, Internal: (81) 32635, Alt: +1.613.693.0684x3545

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v4 1/3] Send loginuid and sessionid in SCM_AUDIT
@ 2014-01-15  4:02             ` Richard Guy Briggs
  0 siblings, 0 replies; 79+ messages in thread
From: Richard Guy Briggs @ 2014-01-15  4:02 UTC (permalink / raw)
  To: Jan Kaluza
  Cc: davem, LKML, netdev, eparis, tj, lizefan, containers, cgroups, viro

On 14/01/13, Jan Kaluza wrote:
> Server-like processes in many cases need credentials and other
> metadata of the peer, to decide if the calling process is allowed to
> request a specific action, or the server just wants to log away this
> type of information for auditing tasks.
> 
> The current practice to retrieve such process metadata is to look that
> information up in procfs with the $PID received over SCM_CREDENTIALS.
> This is sufficient for long-running tasks, but introduces a race which
> cannot be worked around for short-living processes; the calling
> process and all the information in /proc/$PID/ is gone before the
> receiver of the socket message can look it up.
> 
> This introduces a new SCM type called SCM_AUDIT to allow the direct
> attaching of "loginuid" and "sessionid" to SCM, which is significantly more
> efficient and will reliably avoid the race with the round-trip over
> procfs.
> 
> Signed-off-by: Jan Kaluza <jkaluza@redhat.com>

Acked-by: Richard Guy Briggs <rgb@redhat.com>

> ---
>  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 5d488a6..eeac565 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 262532d..67de64f 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 800ca61..bc02a25 100644
> --- a/net/unix/af_unix.c
> +++ b/net/unix/af_unix.c
> @@ -1413,6 +1413,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);
> @@ -1436,6 +1438,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);
>  	}
>  }
>  
> @@ -1829,6 +1833,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)) {
> @@ -2008,6 +2013,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
> 

- RGB

--
Richard Guy Briggs <rbriggs@redhat.com>
Senior Software Engineer, Kernel Security, AMER ENG Base Operating Systems, Red Hat
Remote, Ottawa, Canada
Voice: +1.647.777.2635, Internal: (81) 32635, Alt: +1.613.693.0684x3545

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v4 2/3] Send comm and cmdline in SCM_PROCINFO
  2014-01-13  8:01         ` Jan Kaluza
@ 2014-01-15  4:03             ` Richard Guy Briggs
  -1 siblings, 0 replies; 79+ messages in thread
From: Richard Guy Briggs @ 2014-01-15  4:03 UTC (permalink / raw)
  To: Jan Kaluza
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	eparis-H+wXaHxf7aLQT0dZR+AlfA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, tj-DgEjT+Ai2ygdnm+yROfE0A,
	cgroups-u79uwXL29TY76Z2rM5mHXA, davem-fT/PcQaiUtIeIZ0/mPfg9Q

On 14/01/13, Jan Kaluza wrote:
> Server-like processes in many cases need credentials and other
> metadata of the peer, to decide if the calling process is allowed to
> request a specific action, or the server just wants to log away this
> type of information for auditing tasks.
> 
> The current practice to retrieve such process metadata is to look that
> information up in procfs with the $PID received over SCM_CREDENTIALS.
> This is sufficient for long-running tasks, but introduces a race which
> cannot be worked around for short-living processes; the calling
> process and all the information in /proc/$PID/ is gone before the
> receiver of the socket message can look it up.
> 
> This introduces a new SCM type called SCM_PROCINFO to allow the direct
> attaching of "comm" and "cmdline" to SCM, which is significantly more
> efficient and will reliably avoid the race with the round-trip over
> procfs.
> 
> To achieve that, new struct called unix_skb_parms_scm had to be created,
> because otherwise unix_skb_parms would be too big.
> 
> scm_get_current_procinfo is inspired by ./fs/proc/base.c.
> 
> Signed-off-by: Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

Acked-by: Richard Guy Briggs <rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

> ---
>  include/linux/socket.h |  2 ++
>  include/net/af_unix.h  | 11 +++++++--
>  include/net/scm.h      | 24 +++++++++++++++++++
>  net/core/scm.c         | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  net/unix/af_unix.c     | 57 +++++++++++++++++++++++++++++++++++++------
>  5 files changed, 150 insertions(+), 9 deletions(-)
> 
> diff --git a/include/linux/socket.h b/include/linux/socket.h
> index eeac565..5a41f35 100644
> --- a/include/linux/socket.h
> +++ b/include/linux/socket.h
> @@ -131,6 +131,8 @@ static inline struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr
>  #define SCM_CREDENTIALS 0x02		/* rw: struct ucred		*/
>  #define SCM_SECURITY	0x03		/* rw: security label		*/
>  #define SCM_AUDIT	0x04		/* rw: struct uaudit		*/
> +#define SCM_PROCINFO	0x05	/* rw: comm + cmdline (NULL terminated
> +					   array of char *) */
>  
>  struct ucred {
>  	__u32	pid;
> diff --git a/include/net/af_unix.h b/include/net/af_unix.h
> index 3b9d22a..05c7678 100644
> --- a/include/net/af_unix.h
> +++ b/include/net/af_unix.h
> @@ -27,6 +27,13 @@ struct unix_address {
>  	struct sockaddr_un name[0];
>  };
>  
> +struct unix_skb_parms_scm {
> +	kuid_t loginuid;
> +	unsigned int sessionid;
> +	char *procinfo;
> +	int procinfo_len;
> +};
> +
>  struct unix_skb_parms {
>  	struct pid		*pid;		/* Skb credentials	*/
>  	kuid_t			uid;
> @@ -36,12 +43,12 @@ struct unix_skb_parms {
>  	u32			secid;		/* Security ID		*/
>  #endif
>  	u32			consumed;
> -	kuid_t			loginuid;
> -	unsigned int		sessionid;
> +	struct unix_skb_parms_scm *scm;
>  };
>  
>  #define UNIXCB(skb) 	(*(struct unix_skb_parms *)&((skb)->cb))
>  #define UNIXSID(skb)	(&UNIXCB((skb)).secid)
> +#define UNIXSCM(skb)	(*(UNIXCB((skb)).scm))
>  
>  #define unix_state_lock(s)	spin_lock(&unix_sk(s)->lock)
>  #define unix_state_unlock(s)	spin_unlock(&unix_sk(s)->lock)
> diff --git a/include/net/scm.h b/include/net/scm.h
> index 67de64f..f084e19 100644
> --- a/include/net/scm.h
> +++ b/include/net/scm.h
> @@ -30,11 +30,17 @@ struct scm_fp_list {
>  	struct file		*fp[SCM_MAX_FD];
>  };
>  
> +struct scm_procinfo {
> +	char *procinfo;
> +	int len;
> +};
> +
>  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	*/
> +	struct scm_procinfo	procinfo;	/* Skb procinfo */
>  #ifdef CONFIG_SECURITY_NETWORK
>  	u32			secid;		/* Passed security ID 	*/
>  #endif
> @@ -45,6 +51,7 @@ void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm);
>  int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm);
>  void __scm_destroy(struct scm_cookie *scm);
>  struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl);
> +int scm_get_current_procinfo(char **procinfo);
>  
>  #ifdef CONFIG_SECURITY_NETWORK
>  static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
> @@ -72,10 +79,20 @@ static inline void scm_set_audit(struct scm_cookie *scm,
>  	scm->audit.sessionid = sessionid;
>  }
>  
> +static inline void scm_set_procinfo(struct scm_cookie *scm,
> +				    char *procinfo, int len)
> +{
> +	scm->procinfo.procinfo = procinfo;
> +	scm->procinfo.len = len;
> +}
> +
>  static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
>  {
>  	put_pid(scm->pid);
>  	scm->pid  = NULL;
> +	kfree(scm->procinfo.procinfo);
> +	scm->procinfo.procinfo = NULL;
> +	scm->procinfo.len = 0;
>  }
>  
>  static __inline__ void scm_destroy(struct scm_cookie *scm)
> @@ -88,6 +105,8 @@ static __inline__ void scm_destroy(struct scm_cookie *scm)
>  static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
>  			       struct scm_cookie *scm, bool forcecreds)
>  {
> +	char *procinfo;
> +	int len;
>  	memset(scm, 0, sizeof(*scm));
>  	scm->creds.uid = INVALID_UID;
>  	scm->creds.gid = INVALID_GID;
> @@ -96,6 +115,9 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
>  			     current_gid());
>  		scm_set_audit(scm, audit_get_loginuid(current),
>  			      audit_get_sessionid(current));
> +		len = scm_get_current_procinfo(&procinfo);
> +		if (len > 0)
> +			scm_set_procinfo(scm, procinfo, len);
>  	}
>  	unix_get_peersec_dgram(sock, scm);
>  	if (msg->msg_controllen <= 0)
> @@ -148,6 +170,8 @@ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
>  		};
>  		put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(ucreds), &ucreds);
>  		put_cmsg(msg, SOL_SOCKET, SCM_AUDIT, sizeof(uaudits), &uaudits);
> +		put_cmsg(msg, SOL_SOCKET, SCM_PROCINFO, scm->procinfo.len,
> +				 scm->procinfo.procinfo);
>  	}
>  
>  	scm_destroy_cred(scm);
> diff --git a/net/core/scm.c b/net/core/scm.c
> index b442e7e..4accb07 100644
> --- a/net/core/scm.c
> +++ b/net/core/scm.c
> @@ -339,3 +339,68 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)
>  	return new_fpl;
>  }
>  EXPORT_SYMBOL(scm_fp_dup);
> +
> +int scm_get_current_procinfo(char **procinfo)
> +{
> +	int res = 0;
> +	unsigned int len;
> +	char *buffer = NULL;
> +	struct mm_struct *mm;
> +	int comm_len = strlen(current->comm);
> +
> +	*procinfo = NULL;
> +
> +	buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
> +	if (!buffer)
> +		return -ENOMEM;
> +
> +	mm = get_task_mm(current);
> +	if (!mm)
> +		goto out;
> +	if (!mm->arg_end)
> +		goto out_mm;    /* Shh! No looking before we're done */
> +
> +	len = mm->arg_end - mm->arg_start;
> +
> +	if (len > PAGE_SIZE)
> +		len = PAGE_SIZE;
> +
> +	res = access_process_vm(current, mm->arg_start, buffer, len, 0);
> +
> +	/* If the nul at the end of args has been overwritten, then
> +	 * assume application is using setproctitle(3).
> +	 */
> +	if (res > 0 && buffer[res-1] != '\0' && len < PAGE_SIZE) {
> +		len = strnlen(buffer, res);
> +		if (len < res) {
> +			res = len;
> +		} else {
> +			len = mm->env_end - mm->env_start;
> +			if (len > PAGE_SIZE - res)
> +				len = PAGE_SIZE - res;
> +			res += access_process_vm(current, mm->env_start,
> +						 buffer+res, len, 0);
> +			res = strnlen(buffer, res);
> +		}
> +	}
> +
> +	/* strlen(comm) + \0 + len of cmdline */
> +	len = comm_len + 1 + res;
> +	*procinfo = kmalloc(len, GFP_KERNEL);
> +	if (!*procinfo) {
> +		res = -ENOMEM;
> +		goto out_mm;
> +	}
> +
> +	memcpy(*procinfo, current->comm, comm_len + 1); /* include \0 */
> +	if (res > 0)
> +		memcpy(*procinfo + comm_len + 1, buffer, res);
> +	res = len;
> +
> +out_mm:
> +	mmput(mm);
> +out:
> +	kfree(buffer);
> +	return res;
> +}
> +EXPORT_SYMBOL(scm_get_current_procinfo);
> diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
> index bc02a25..35ab97f0 100644
> --- a/net/unix/af_unix.c
> +++ b/net/unix/af_unix.c
> @@ -1361,9 +1361,14 @@ static void unix_destruct_scm(struct sk_buff *skb)
>  	struct scm_cookie scm;
>  	memset(&scm, 0, sizeof(scm));
>  	scm.pid  = UNIXCB(skb).pid;
> +	if (UNIXCB(skb).scm) {
> +		scm.procinfo.procinfo = UNIXSCM(skb).procinfo;
> +		scm.procinfo.len = UNIXSCM(skb).procinfo_len;
> +	}
>  	if (UNIXCB(skb).fp)
>  		unix_detach_fds(&scm, skb);
>  
> +	kfree(UNIXCB(skb).scm);
>  	/* Alas, it calls VFS */
>  	/* So fscking what? fput() had been SMP-safe since the last Summer */
>  	scm_destroy(&scm);
> @@ -1410,15 +1415,31 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen
>  {
>  	int err = 0;
>  
> +	if (!UNIXCB(skb).scm) {
> +		UNIXCB(skb).scm = kmalloc(sizeof(struct unix_skb_parms_scm),
> +					  GFP_KERNEL);
> +		if (!UNIXCB(skb).scm)
> +			return -ENOMEM;
> +	}
> +
>  	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;
> +	UNIXSCM(skb).loginuid = scm->audit.loginuid;
> +	UNIXSCM(skb).sessionid = scm->audit.sessionid;
>  	UNIXCB(skb).fp = NULL;
>  	if (scm->fp && send_fds)
>  		err = unix_attach_fds(scm, skb);
>  
> +	UNIXSCM(skb).procinfo = NULL;
> +	if (scm->procinfo.procinfo) {
> +		UNIXSCM(skb).procinfo_len = scm->procinfo.len;
> +		UNIXSCM(skb).procinfo = kmemdup(scm->procinfo.procinfo,
> +					scm->procinfo.len, GFP_KERNEL);
> +		if (!UNIXSCM(skb).procinfo)
> +			return -ENOMEM;
> +	}
> +
>  	skb->destructor = unix_destruct_scm;
>  	return err;
>  }
> @@ -1438,8 +1459,10 @@ 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);
> +		UNIXSCM(skb).loginuid = audit_get_loginuid(current);
> +		UNIXSCM(skb).sessionid = audit_get_sessionid(current);
> +		UNIXSCM(skb).procinfo_len = scm_get_current_procinfo(
> +			&UNIXSCM(skb).procinfo);
>  	}
>  }
>  
> @@ -1833,7 +1856,17 @@ 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);
> +	if (UNIXCB(skb).scm) {
> +		scm_set_audit(siocb->scm, UNIXSCM(skb).loginuid,
> +			      UNIXSCM(skb).sessionid);
> +		if (UNIXSCM(skb).procinfo) {
> +			scm_set_procinfo(siocb->scm,
> +					 kmemdup(UNIXSCM(skb).procinfo,
> +						 UNIXSCM(skb).procinfo_len,
> +						 GFP_KERNEL),
> +					 UNIXSCM(skb).procinfo_len);
> +		}
> +	}
>  	unix_set_secdata(siocb->scm, skb);
>  
>  	if (!(flags & MSG_PEEK)) {
> @@ -2013,8 +2046,18 @@ 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);
> +			if (UNIXCB(skb).scm) {
> +				scm_set_audit(siocb->scm,
> +					      UNIXSCM(skb).loginuid,
> +					      UNIXSCM(skb).sessionid);
> +				if (UNIXSCM(skb).procinfo) {
> +					scm_set_procinfo(siocb->scm,
> +						kmemdup(UNIXSCM(skb).procinfo,
> +						UNIXSCM(skb).procinfo_len,
> +						GFP_KERNEL),
> +						UNIXSCM(skb).procinfo_len);
> +				}
> +			}
>  			check_creds = 1;
>  		}
>  
> -- 
> 1.8.3.1
> 

- RGB

--
Richard Guy Briggs <rbriggs-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Senior Software Engineer, Kernel Security, AMER ENG Base Operating Systems, Red Hat
Remote, Ottawa, Canada
Voice: +1.647.777.2635, Internal: (81) 32635, Alt: +1.613.693.0684x3545

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v4 2/3] Send comm and cmdline in SCM_PROCINFO
@ 2014-01-15  4:03             ` Richard Guy Briggs
  0 siblings, 0 replies; 79+ messages in thread
From: Richard Guy Briggs @ 2014-01-15  4:03 UTC (permalink / raw)
  To: Jan Kaluza
  Cc: davem, LKML, netdev, eparis, tj, lizefan, containers, cgroups, viro

On 14/01/13, Jan Kaluza wrote:
> Server-like processes in many cases need credentials and other
> metadata of the peer, to decide if the calling process is allowed to
> request a specific action, or the server just wants to log away this
> type of information for auditing tasks.
> 
> The current practice to retrieve such process metadata is to look that
> information up in procfs with the $PID received over SCM_CREDENTIALS.
> This is sufficient for long-running tasks, but introduces a race which
> cannot be worked around for short-living processes; the calling
> process and all the information in /proc/$PID/ is gone before the
> receiver of the socket message can look it up.
> 
> This introduces a new SCM type called SCM_PROCINFO to allow the direct
> attaching of "comm" and "cmdline" to SCM, which is significantly more
> efficient and will reliably avoid the race with the round-trip over
> procfs.
> 
> To achieve that, new struct called unix_skb_parms_scm had to be created,
> because otherwise unix_skb_parms would be too big.
> 
> scm_get_current_procinfo is inspired by ./fs/proc/base.c.
> 
> Signed-off-by: Jan Kaluza <jkaluza@redhat.com>

Acked-by: Richard Guy Briggs <rgb@redhat.com>

> ---
>  include/linux/socket.h |  2 ++
>  include/net/af_unix.h  | 11 +++++++--
>  include/net/scm.h      | 24 +++++++++++++++++++
>  net/core/scm.c         | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  net/unix/af_unix.c     | 57 +++++++++++++++++++++++++++++++++++++------
>  5 files changed, 150 insertions(+), 9 deletions(-)
> 
> diff --git a/include/linux/socket.h b/include/linux/socket.h
> index eeac565..5a41f35 100644
> --- a/include/linux/socket.h
> +++ b/include/linux/socket.h
> @@ -131,6 +131,8 @@ static inline struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr
>  #define SCM_CREDENTIALS 0x02		/* rw: struct ucred		*/
>  #define SCM_SECURITY	0x03		/* rw: security label		*/
>  #define SCM_AUDIT	0x04		/* rw: struct uaudit		*/
> +#define SCM_PROCINFO	0x05	/* rw: comm + cmdline (NULL terminated
> +					   array of char *) */
>  
>  struct ucred {
>  	__u32	pid;
> diff --git a/include/net/af_unix.h b/include/net/af_unix.h
> index 3b9d22a..05c7678 100644
> --- a/include/net/af_unix.h
> +++ b/include/net/af_unix.h
> @@ -27,6 +27,13 @@ struct unix_address {
>  	struct sockaddr_un name[0];
>  };
>  
> +struct unix_skb_parms_scm {
> +	kuid_t loginuid;
> +	unsigned int sessionid;
> +	char *procinfo;
> +	int procinfo_len;
> +};
> +
>  struct unix_skb_parms {
>  	struct pid		*pid;		/* Skb credentials	*/
>  	kuid_t			uid;
> @@ -36,12 +43,12 @@ struct unix_skb_parms {
>  	u32			secid;		/* Security ID		*/
>  #endif
>  	u32			consumed;
> -	kuid_t			loginuid;
> -	unsigned int		sessionid;
> +	struct unix_skb_parms_scm *scm;
>  };
>  
>  #define UNIXCB(skb) 	(*(struct unix_skb_parms *)&((skb)->cb))
>  #define UNIXSID(skb)	(&UNIXCB((skb)).secid)
> +#define UNIXSCM(skb)	(*(UNIXCB((skb)).scm))
>  
>  #define unix_state_lock(s)	spin_lock(&unix_sk(s)->lock)
>  #define unix_state_unlock(s)	spin_unlock(&unix_sk(s)->lock)
> diff --git a/include/net/scm.h b/include/net/scm.h
> index 67de64f..f084e19 100644
> --- a/include/net/scm.h
> +++ b/include/net/scm.h
> @@ -30,11 +30,17 @@ struct scm_fp_list {
>  	struct file		*fp[SCM_MAX_FD];
>  };
>  
> +struct scm_procinfo {
> +	char *procinfo;
> +	int len;
> +};
> +
>  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	*/
> +	struct scm_procinfo	procinfo;	/* Skb procinfo */
>  #ifdef CONFIG_SECURITY_NETWORK
>  	u32			secid;		/* Passed security ID 	*/
>  #endif
> @@ -45,6 +51,7 @@ void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm);
>  int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm);
>  void __scm_destroy(struct scm_cookie *scm);
>  struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl);
> +int scm_get_current_procinfo(char **procinfo);
>  
>  #ifdef CONFIG_SECURITY_NETWORK
>  static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
> @@ -72,10 +79,20 @@ static inline void scm_set_audit(struct scm_cookie *scm,
>  	scm->audit.sessionid = sessionid;
>  }
>  
> +static inline void scm_set_procinfo(struct scm_cookie *scm,
> +				    char *procinfo, int len)
> +{
> +	scm->procinfo.procinfo = procinfo;
> +	scm->procinfo.len = len;
> +}
> +
>  static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
>  {
>  	put_pid(scm->pid);
>  	scm->pid  = NULL;
> +	kfree(scm->procinfo.procinfo);
> +	scm->procinfo.procinfo = NULL;
> +	scm->procinfo.len = 0;
>  }
>  
>  static __inline__ void scm_destroy(struct scm_cookie *scm)
> @@ -88,6 +105,8 @@ static __inline__ void scm_destroy(struct scm_cookie *scm)
>  static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
>  			       struct scm_cookie *scm, bool forcecreds)
>  {
> +	char *procinfo;
> +	int len;
>  	memset(scm, 0, sizeof(*scm));
>  	scm->creds.uid = INVALID_UID;
>  	scm->creds.gid = INVALID_GID;
> @@ -96,6 +115,9 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
>  			     current_gid());
>  		scm_set_audit(scm, audit_get_loginuid(current),
>  			      audit_get_sessionid(current));
> +		len = scm_get_current_procinfo(&procinfo);
> +		if (len > 0)
> +			scm_set_procinfo(scm, procinfo, len);
>  	}
>  	unix_get_peersec_dgram(sock, scm);
>  	if (msg->msg_controllen <= 0)
> @@ -148,6 +170,8 @@ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
>  		};
>  		put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(ucreds), &ucreds);
>  		put_cmsg(msg, SOL_SOCKET, SCM_AUDIT, sizeof(uaudits), &uaudits);
> +		put_cmsg(msg, SOL_SOCKET, SCM_PROCINFO, scm->procinfo.len,
> +				 scm->procinfo.procinfo);
>  	}
>  
>  	scm_destroy_cred(scm);
> diff --git a/net/core/scm.c b/net/core/scm.c
> index b442e7e..4accb07 100644
> --- a/net/core/scm.c
> +++ b/net/core/scm.c
> @@ -339,3 +339,68 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)
>  	return new_fpl;
>  }
>  EXPORT_SYMBOL(scm_fp_dup);
> +
> +int scm_get_current_procinfo(char **procinfo)
> +{
> +	int res = 0;
> +	unsigned int len;
> +	char *buffer = NULL;
> +	struct mm_struct *mm;
> +	int comm_len = strlen(current->comm);
> +
> +	*procinfo = NULL;
> +
> +	buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
> +	if (!buffer)
> +		return -ENOMEM;
> +
> +	mm = get_task_mm(current);
> +	if (!mm)
> +		goto out;
> +	if (!mm->arg_end)
> +		goto out_mm;    /* Shh! No looking before we're done */
> +
> +	len = mm->arg_end - mm->arg_start;
> +
> +	if (len > PAGE_SIZE)
> +		len = PAGE_SIZE;
> +
> +	res = access_process_vm(current, mm->arg_start, buffer, len, 0);
> +
> +	/* If the nul at the end of args has been overwritten, then
> +	 * assume application is using setproctitle(3).
> +	 */
> +	if (res > 0 && buffer[res-1] != '\0' && len < PAGE_SIZE) {
> +		len = strnlen(buffer, res);
> +		if (len < res) {
> +			res = len;
> +		} else {
> +			len = mm->env_end - mm->env_start;
> +			if (len > PAGE_SIZE - res)
> +				len = PAGE_SIZE - res;
> +			res += access_process_vm(current, mm->env_start,
> +						 buffer+res, len, 0);
> +			res = strnlen(buffer, res);
> +		}
> +	}
> +
> +	/* strlen(comm) + \0 + len of cmdline */
> +	len = comm_len + 1 + res;
> +	*procinfo = kmalloc(len, GFP_KERNEL);
> +	if (!*procinfo) {
> +		res = -ENOMEM;
> +		goto out_mm;
> +	}
> +
> +	memcpy(*procinfo, current->comm, comm_len + 1); /* include \0 */
> +	if (res > 0)
> +		memcpy(*procinfo + comm_len + 1, buffer, res);
> +	res = len;
> +
> +out_mm:
> +	mmput(mm);
> +out:
> +	kfree(buffer);
> +	return res;
> +}
> +EXPORT_SYMBOL(scm_get_current_procinfo);
> diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
> index bc02a25..35ab97f0 100644
> --- a/net/unix/af_unix.c
> +++ b/net/unix/af_unix.c
> @@ -1361,9 +1361,14 @@ static void unix_destruct_scm(struct sk_buff *skb)
>  	struct scm_cookie scm;
>  	memset(&scm, 0, sizeof(scm));
>  	scm.pid  = UNIXCB(skb).pid;
> +	if (UNIXCB(skb).scm) {
> +		scm.procinfo.procinfo = UNIXSCM(skb).procinfo;
> +		scm.procinfo.len = UNIXSCM(skb).procinfo_len;
> +	}
>  	if (UNIXCB(skb).fp)
>  		unix_detach_fds(&scm, skb);
>  
> +	kfree(UNIXCB(skb).scm);
>  	/* Alas, it calls VFS */
>  	/* So fscking what? fput() had been SMP-safe since the last Summer */
>  	scm_destroy(&scm);
> @@ -1410,15 +1415,31 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen
>  {
>  	int err = 0;
>  
> +	if (!UNIXCB(skb).scm) {
> +		UNIXCB(skb).scm = kmalloc(sizeof(struct unix_skb_parms_scm),
> +					  GFP_KERNEL);
> +		if (!UNIXCB(skb).scm)
> +			return -ENOMEM;
> +	}
> +
>  	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;
> +	UNIXSCM(skb).loginuid = scm->audit.loginuid;
> +	UNIXSCM(skb).sessionid = scm->audit.sessionid;
>  	UNIXCB(skb).fp = NULL;
>  	if (scm->fp && send_fds)
>  		err = unix_attach_fds(scm, skb);
>  
> +	UNIXSCM(skb).procinfo = NULL;
> +	if (scm->procinfo.procinfo) {
> +		UNIXSCM(skb).procinfo_len = scm->procinfo.len;
> +		UNIXSCM(skb).procinfo = kmemdup(scm->procinfo.procinfo,
> +					scm->procinfo.len, GFP_KERNEL);
> +		if (!UNIXSCM(skb).procinfo)
> +			return -ENOMEM;
> +	}
> +
>  	skb->destructor = unix_destruct_scm;
>  	return err;
>  }
> @@ -1438,8 +1459,10 @@ 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);
> +		UNIXSCM(skb).loginuid = audit_get_loginuid(current);
> +		UNIXSCM(skb).sessionid = audit_get_sessionid(current);
> +		UNIXSCM(skb).procinfo_len = scm_get_current_procinfo(
> +			&UNIXSCM(skb).procinfo);
>  	}
>  }
>  
> @@ -1833,7 +1856,17 @@ 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);
> +	if (UNIXCB(skb).scm) {
> +		scm_set_audit(siocb->scm, UNIXSCM(skb).loginuid,
> +			      UNIXSCM(skb).sessionid);
> +		if (UNIXSCM(skb).procinfo) {
> +			scm_set_procinfo(siocb->scm,
> +					 kmemdup(UNIXSCM(skb).procinfo,
> +						 UNIXSCM(skb).procinfo_len,
> +						 GFP_KERNEL),
> +					 UNIXSCM(skb).procinfo_len);
> +		}
> +	}
>  	unix_set_secdata(siocb->scm, skb);
>  
>  	if (!(flags & MSG_PEEK)) {
> @@ -2013,8 +2046,18 @@ 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);
> +			if (UNIXCB(skb).scm) {
> +				scm_set_audit(siocb->scm,
> +					      UNIXSCM(skb).loginuid,
> +					      UNIXSCM(skb).sessionid);
> +				if (UNIXSCM(skb).procinfo) {
> +					scm_set_procinfo(siocb->scm,
> +						kmemdup(UNIXSCM(skb).procinfo,
> +						UNIXSCM(skb).procinfo_len,
> +						GFP_KERNEL),
> +						UNIXSCM(skb).procinfo_len);
> +				}
> +			}
>  			check_creds = 1;
>  		}
>  
> -- 
> 1.8.3.1
> 

- RGB

--
Richard Guy Briggs <rbriggs@redhat.com>
Senior Software Engineer, Kernel Security, AMER ENG Base Operating Systems, Red Hat
Remote, Ottawa, Canada
Voice: +1.647.777.2635, Internal: (81) 32635, Alt: +1.613.693.0684x3545

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message
  2014-01-13  8:01     ` Jan Kaluza
@ 2014-01-15 20:17         ` David Miller
  -1 siblings, 0 replies; 79+ messages in thread
From: David Miller @ 2014-01-15 20:17 UTC (permalink / raw)
  To: jkaluza-H+wXaHxf7aLQT0dZR+AlfA
  Cc: rgb-H+wXaHxf7aLQT0dZR+AlfA, netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	eparis-H+wXaHxf7aLQT0dZR+AlfA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, tj-DgEjT+Ai2ygdnm+yROfE0A,
	cgroups-u79uwXL29TY76Z2rM5mHXA

From: Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Date: Mon, 13 Jan 2014 09:01:46 +0100

> Changes introduced in this patchset can also increase performance
> of such server-like processes, because current way of opening and
> parsing /proc/$PID/* files is much more expensive than receiving these
> metadata using SCM.

The problem with this line of reasoning is that these changes will
hurt everyone else, because these new control messages are sent
unconditionally, whether the application is interested in them or not.

I really don't like this cost tradeoff, it's terrible, and therefore
I'm really not inclined to apply these patches, sorry.

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message
@ 2014-01-15 20:17         ` David Miller
  0 siblings, 0 replies; 79+ messages in thread
From: David Miller @ 2014-01-15 20:17 UTC (permalink / raw)
  To: jkaluza
  Cc: linux-kernel, netdev, eparis, rgb, tj, lizefan, containers,
	cgroups, viro

From: Jan Kaluza <jkaluza@redhat.com>
Date: Mon, 13 Jan 2014 09:01:46 +0100

> Changes introduced in this patchset can also increase performance
> of such server-like processes, because current way of opening and
> parsing /proc/$PID/* files is much more expensive than receiving these
> metadata using SCM.

The problem with this line of reasoning is that these changes will
hurt everyone else, because these new control messages are sent
unconditionally, whether the application is interested in them or not.

I really don't like this cost tradeoff, it's terrible, and therefore
I'm really not inclined to apply these patches, sorry.

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message
  2014-01-15 20:17         ` David Miller
@ 2014-01-15 23:21             ` Eric Paris
  -1 siblings, 0 replies; 79+ messages in thread
From: Eric Paris @ 2014-01-15 23:21 UTC (permalink / raw)
  To: David Miller
  Cc: jkaluza-H+wXaHxf7aLQT0dZR+AlfA, rgb-H+wXaHxf7aLQT0dZR+AlfA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, tj-DgEjT+Ai2ygdnm+yROfE0A,
	cgroups-u79uwXL29TY76Z2rM5mHXA

On Wed, 2014-01-15 at 12:17 -0800, David Miller wrote:
> From: Jan Kaluza <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> Date: Mon, 13 Jan 2014 09:01:46 +0100
> 
> > Changes introduced in this patchset can also increase performance
> > of such server-like processes, because current way of opening and
> > parsing /proc/$PID/* files is much more expensive than receiving these
> > metadata using SCM.
> 
> The problem with this line of reasoning is that these changes will
> hurt everyone else, because these new control messages are sent
> unconditionally, whether the application is interested in them or not.
> 
> I really don't like this cost tradeoff, it's terrible, and therefore
> I'm really not inclined to apply these patches, sorry.

Agreed.  Although you seem to be ignoring the part of the logic where is
solves a problem that can not be solved today.

> The current practice to retrieve such process metadata is to look that
> information up in procfs with the $PID received over SCM_CREDENTIALS.
> This is sufficient for long-running tasks, but introduces a race which
> cannot be worked around for short-living processes; the calling
> process and all the information in /proc/$PID/ is gone before the
> receiver of the socket message can look it up.

Reliably being able to audit what process requested an action is
extremely useful.  And I like the audit patch, as it is a couple of ints
we are storing.

procinfo and cgroup can both be up to 4k of data.

Is there an alternative he should consider?  Some way to grab a
reference on task_struct and just attach that to the message?

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message
@ 2014-01-15 23:21             ` Eric Paris
  0 siblings, 0 replies; 79+ messages in thread
From: Eric Paris @ 2014-01-15 23:21 UTC (permalink / raw)
  To: David Miller
  Cc: jkaluza, linux-kernel, netdev, rgb, tj, lizefan, containers,
	cgroups, viro

On Wed, 2014-01-15 at 12:17 -0800, David Miller wrote:
> From: Jan Kaluza <jkaluza@redhat.com>
> Date: Mon, 13 Jan 2014 09:01:46 +0100
> 
> > Changes introduced in this patchset can also increase performance
> > of such server-like processes, because current way of opening and
> > parsing /proc/$PID/* files is much more expensive than receiving these
> > metadata using SCM.
> 
> The problem with this line of reasoning is that these changes will
> hurt everyone else, because these new control messages are sent
> unconditionally, whether the application is interested in them or not.
> 
> I really don't like this cost tradeoff, it's terrible, and therefore
> I'm really not inclined to apply these patches, sorry.

Agreed.  Although you seem to be ignoring the part of the logic where is
solves a problem that can not be solved today.

> The current practice to retrieve such process metadata is to look that
> information up in procfs with the $PID received over SCM_CREDENTIALS.
> This is sufficient for long-running tasks, but introduces a race which
> cannot be worked around for short-living processes; the calling
> process and all the information in /proc/$PID/ is gone before the
> receiver of the socket message can look it up.

Reliably being able to audit what process requested an action is
extremely useful.  And I like the audit patch, as it is a couple of ints
we are storing.

procinfo and cgroup can both be up to 4k of data.

Is there an alternative he should consider?  Some way to grab a
reference on task_struct and just attach that to the message?


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message
  2014-01-15 23:21             ` Eric Paris
@ 2014-01-15 23:23                 ` Tejun Heo
  -1 siblings, 0 replies; 79+ messages in thread
From: Tejun Heo @ 2014-01-15 23:23 UTC (permalink / raw)
  To: Eric Paris
  Cc: jkaluza-H+wXaHxf7aLQT0dZR+AlfA, rgb-H+wXaHxf7aLQT0dZR+AlfA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
	cgroups-u79uwXL29TY76Z2rM5mHXA, David Miller

On Wed, Jan 15, 2014 at 06:21:43PM -0500, Eric Paris wrote:
> Reliably being able to audit what process requested an action is
> extremely useful.  And I like the audit patch, as it is a couple of ints
> we are storing.
> 
> procinfo and cgroup can both be up to 4k of data.
> 
> Is there an alternative he should consider?  Some way to grab a
> reference on task_struct and just attach that to the message?

Or maybe it can be made separately optional instead of tagging along
on an existing option so that it doesn't tax use cases which don't
care about the new stuff?

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message
@ 2014-01-15 23:23                 ` Tejun Heo
  0 siblings, 0 replies; 79+ messages in thread
From: Tejun Heo @ 2014-01-15 23:23 UTC (permalink / raw)
  To: Eric Paris
  Cc: David Miller, jkaluza, linux-kernel, netdev, rgb, lizefan,
	containers, cgroups, viro

On Wed, Jan 15, 2014 at 06:21:43PM -0500, Eric Paris wrote:
> Reliably being able to audit what process requested an action is
> extremely useful.  And I like the audit patch, as it is a couple of ints
> we are storing.
> 
> procinfo and cgroup can both be up to 4k of data.
> 
> Is there an alternative he should consider?  Some way to grab a
> reference on task_struct and just attach that to the message?

Or maybe it can be made separately optional instead of tagging along
on an existing option so that it doesn't tax use cases which don't
care about the new stuff?

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message
  2014-01-15 23:23                 ` Tejun Heo
@ 2014-01-16  9:29                     ` Jan Kaluža
  -1 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluža @ 2014-01-16  9:29 UTC (permalink / raw)
  To: Tejun Heo, Eric Paris
  Cc: rgb-H+wXaHxf7aLQT0dZR+AlfA, netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
	cgroups-u79uwXL29TY76Z2rM5mHXA, David Miller

On 01/16/2014 12:23 AM, Tejun Heo wrote:
> On Wed, Jan 15, 2014 at 06:21:43PM -0500, Eric Paris wrote:
>> Reliably being able to audit what process requested an action is
>> extremely useful.  And I like the audit patch, as it is a couple of ints
>> we are storing.
>>
>> procinfo and cgroup can both be up to 4k of data.
>>
>> Is there an alternative he should consider?  Some way to grab a
>> reference on task_struct and just attach that to the message?
>
> Or maybe it can be made separately optional instead of tagging along
> on an existing option so that it doesn't tax use cases which don't
> care about the new stuff?

Right, I could add new option next to SOCK_PASSCRED which could be used 
to send newly added stuff. Would this be acceptable?

I would still vote for SCM_AUDIT to be part of SOCK_PASSCRED and move 
SCM_CGROUP and SCM_PROCINFO into new option.

> Thanks.
>

Regards,
Jan Kaluza

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message
@ 2014-01-16  9:29                     ` Jan Kaluža
  0 siblings, 0 replies; 79+ messages in thread
From: Jan Kaluža @ 2014-01-16  9:29 UTC (permalink / raw)
  To: Tejun Heo, Eric Paris
  Cc: David Miller, linux-kernel, netdev, rgb, lizefan, containers,
	cgroups, viro

On 01/16/2014 12:23 AM, Tejun Heo wrote:
> On Wed, Jan 15, 2014 at 06:21:43PM -0500, Eric Paris wrote:
>> Reliably being able to audit what process requested an action is
>> extremely useful.  And I like the audit patch, as it is a couple of ints
>> we are storing.
>>
>> procinfo and cgroup can both be up to 4k of data.
>>
>> Is there an alternative he should consider?  Some way to grab a
>> reference on task_struct and just attach that to the message?
>
> Or maybe it can be made separately optional instead of tagging along
> on an existing option so that it doesn't tax use cases which don't
> care about the new stuff?

Right, I could add new option next to SOCK_PASSCRED which could be used 
to send newly added stuff. Would this be acceptable?

I would still vote for SCM_AUDIT to be part of SOCK_PASSCRED and move 
SCM_CGROUP and SCM_PROCINFO into new option.

> Thanks.
>

Regards,
Jan Kaluza


^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message
       [not found]                     ` <52D7A68F.5030700-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
@ 2014-01-23 19:31                       ` Kay Sievers
  0 siblings, 0 replies; 79+ messages in thread
From: Kay Sievers @ 2014-01-23 19:31 UTC (permalink / raw)
  To: Jan Kaluža
  Cc: rgb-H+wXaHxf7aLQT0dZR+AlfA, netdev-u79uwXL29TY76Z2rM5mHXA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
	Eric Paris, viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn, Tejun Heo,
	cgroups-u79uwXL29TY76Z2rM5mHXA, David Miller

On Thu, Jan 16, 2014 at 10:29 AM, Jan Kaluža <jkaluza@redhat.com> wrote:
> On 01/16/2014 12:23 AM, Tejun Heo wrote:
>> On Wed, Jan 15, 2014 at 06:21:43PM -0500, Eric Paris wrote:
>>>
>>> Reliably being able to audit what process requested an action is
>>> extremely useful.  And I like the audit patch, as it is a couple of ints
>>> we are storing.
>>>
>>> procinfo and cgroup can both be up to 4k of data.
>>>
>>> Is there an alternative he should consider?  Some way to grab a
>>> reference on task_struct and just attach that to the message?
>>
>> Or maybe it can be made separately optional instead of tagging along
>> on an existing option so that it doesn't tax use cases which don't
>> care about the new stuff?
>
> Right, I could add new option next to SOCK_PASSCRED which could be used to
> send newly added stuff. Would this be acceptable?
>
> I would still vote for SCM_AUDIT to be part of SOCK_PASSCRED and move
> SCM_CGROUP and SCM_PROCINFO into new option.

Maybe we could just add a new SOCK_PASS_TASKINFO bit to set in
socket->flags. Set that bit with a new SO_PASS_TASKINFO sockoption.

The SOCK_PASS_TASKINFO can carry all sorts of "struct task" related
stuff, also include the audit data. It is all fully conditional, so
users which do not explicitly subscribe to TASKINFO will never see the
data or needlessly pay for the overhead.

A TASKINFO sounds generic enough to be possibly extended with new data
in the future, without wasting extra bits in the socket flags.

Users which subscribe with SO_PASS_TASKINFO expect some overhead
anyway. In the end it's still a lot cheaper than parsing /proc for the
data; which is also racy and does therefore not work for any
short-living program.

Thanks,
Kay
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/containers

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message
       [not found]                     ` <52D7A68F.5030700-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
  2014-01-23 19:31                       ` Kay Sievers
@ 2014-01-23 19:31                       ` Kay Sievers
  0 siblings, 0 replies; 79+ messages in thread
From: Kay Sievers @ 2014-01-23 19:31 UTC (permalink / raw)
  To: Jan Kaluža
  Cc: Tejun Heo, Eric Paris, David Miller, LKML, netdev, rgb, lizefan,
	containers, cgroups, viro

On Thu, Jan 16, 2014 at 10:29 AM, Jan Kaluža <jkaluza@redhat.com> wrote:
> On 01/16/2014 12:23 AM, Tejun Heo wrote:
>> On Wed, Jan 15, 2014 at 06:21:43PM -0500, Eric Paris wrote:
>>>
>>> Reliably being able to audit what process requested an action is
>>> extremely useful.  And I like the audit patch, as it is a couple of ints
>>> we are storing.
>>>
>>> procinfo and cgroup can both be up to 4k of data.
>>>
>>> Is there an alternative he should consider?  Some way to grab a
>>> reference on task_struct and just attach that to the message?
>>
>> Or maybe it can be made separately optional instead of tagging along
>> on an existing option so that it doesn't tax use cases which don't
>> care about the new stuff?
>
> Right, I could add new option next to SOCK_PASSCRED which could be used to
> send newly added stuff. Would this be acceptable?
>
> I would still vote for SCM_AUDIT to be part of SOCK_PASSCRED and move
> SCM_CGROUP and SCM_PROCINFO into new option.

Maybe we could just add a new SOCK_PASS_TASKINFO bit to set in
socket->flags. Set that bit with a new SO_PASS_TASKINFO sockoption.

The SOCK_PASS_TASKINFO can carry all sorts of "struct task" related
stuff, also include the audit data. It is all fully conditional, so
users which do not explicitly subscribe to TASKINFO will never see the
data or needlessly pay for the overhead.

A TASKINFO sounds generic enough to be possibly extended with new data
in the future, without wasting extra bits in the socket flags.

Users which subscribe with SO_PASS_TASKINFO expect some overhead
anyway. In the end it's still a lot cheaper than parsing /proc for the
data; which is also racy and does therefore not work for any
short-living program.

Thanks,
Kay

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message
@ 2014-01-23 19:31                       ` Kay Sievers
  0 siblings, 0 replies; 79+ messages in thread
From: Kay Sievers @ 2014-01-23 19:31 UTC (permalink / raw)
  To: Jan Kaluža
  Cc: Tejun Heo, Eric Paris, David Miller, LKML,
	netdev-u79uwXL29TY76Z2rM5mHXA, rgb-H+wXaHxf7aLQT0dZR+AlfA,
	lizefan-hv44wF8Li93QT0dZR+AlfA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	cgroups-u79uwXL29TY76Z2rM5mHXA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn

On Thu, Jan 16, 2014 at 10:29 AM, Jan Kaluža <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> On 01/16/2014 12:23 AM, Tejun Heo wrote:
>> On Wed, Jan 15, 2014 at 06:21:43PM -0500, Eric Paris wrote:
>>>
>>> Reliably being able to audit what process requested an action is
>>> extremely useful.  And I like the audit patch, as it is a couple of ints
>>> we are storing.
>>>
>>> procinfo and cgroup can both be up to 4k of data.
>>>
>>> Is there an alternative he should consider?  Some way to grab a
>>> reference on task_struct and just attach that to the message?
>>
>> Or maybe it can be made separately optional instead of tagging along
>> on an existing option so that it doesn't tax use cases which don't
>> care about the new stuff?
>
> Right, I could add new option next to SOCK_PASSCRED which could be used to
> send newly added stuff. Would this be acceptable?
>
> I would still vote for SCM_AUDIT to be part of SOCK_PASSCRED and move
> SCM_CGROUP and SCM_PROCINFO into new option.

Maybe we could just add a new SOCK_PASS_TASKINFO bit to set in
socket->flags. Set that bit with a new SO_PASS_TASKINFO sockoption.

The SOCK_PASS_TASKINFO can carry all sorts of "struct task" related
stuff, also include the audit data. It is all fully conditional, so
users which do not explicitly subscribe to TASKINFO will never see the
data or needlessly pay for the overhead.

A TASKINFO sounds generic enough to be possibly extended with new data
in the future, without wasting extra bits in the socket flags.

Users which subscribe with SO_PASS_TASKINFO expect some overhead
anyway. In the end it's still a lot cheaper than parsing /proc for the
data; which is also racy and does therefore not work for any
short-living program.

Thanks,
Kay

^ permalink raw reply	[flat|nested] 79+ messages in thread

* Re: [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message
@ 2014-01-23 19:31                       ` Kay Sievers
  0 siblings, 0 replies; 79+ messages in thread
From: Kay Sievers @ 2014-01-23 19:31 UTC (permalink / raw)
  To: Jan Kaluža
  Cc: Tejun Heo, Eric Paris, David Miller, LKML,
	netdev-u79uwXL29TY76Z2rM5mHXA, rgb-H+wXaHxf7aLQT0dZR+AlfA,
	lizefan-hv44wF8Li93QT0dZR+AlfA,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	cgroups-u79uwXL29TY76Z2rM5mHXA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn

On Thu, Jan 16, 2014 at 10:29 AM, Jan Kaluža <jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> On 01/16/2014 12:23 AM, Tejun Heo wrote:
>> On Wed, Jan 15, 2014 at 06:21:43PM -0500, Eric Paris wrote:
>>>
>>> Reliably being able to audit what process requested an action is
>>> extremely useful.  And I like the audit patch, as it is a couple of ints
>>> we are storing.
>>>
>>> procinfo and cgroup can both be up to 4k of data.
>>>
>>> Is there an alternative he should consider?  Some way to grab a
>>> reference on task_struct and just attach that to the message?
>>
>> Or maybe it can be made separately optional instead of tagging along
>> on an existing option so that it doesn't tax use cases which don't
>> care about the new stuff?
>
> Right, I could add new option next to SOCK_PASSCRED which could be used to
> send newly added stuff. Would this be acceptable?
>
> I would still vote for SCM_AUDIT to be part of SOCK_PASSCRED and move
> SCM_CGROUP and SCM_PROCINFO into new option.

Maybe we could just add a new SOCK_PASS_TASKINFO bit to set in
socket->flags. Set that bit with a new SO_PASS_TASKINFO sockoption.

The SOCK_PASS_TASKINFO can carry all sorts of "struct task" related
stuff, also include the audit data. It is all fully conditional, so
users which do not explicitly subscribe to TASKINFO will never see the
data or needlessly pay for the overhead.

A TASKINFO sounds generic enough to be possibly extended with new data
in the future, without wasting extra bits in the socket flags.

Users which subscribe with SO_PASS_TASKINFO expect some overhead
anyway. In the end it's still a lot cheaper than parsing /proc for the
data; which is also racy and does therefore not work for any
short-living program.

Thanks,
Kay

^ permalink raw reply	[flat|nested] 79+ messages in thread

end of thread, other threads:[~2014-01-23 19:31 UTC | newest]

Thread overview: 79+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-27 14:39 [PATCH 0/3] Send audit/procinfo/cgroup data in socket-level control message Jan Kaluza
2013-08-27 14:39 ` [PATCH 1/3] Send loginuid and sessionid in SCM_AUDIT Jan Kaluza
2013-08-27 14:39 ` [PATCH 2/3] Send comm and cmdline in SCM_PROCINFO Jan Kaluza
2013-09-09  6:52   ` Eric W. Biederman
2013-08-27 14:40 ` [PATCH 3/3] Send cgroup_path in SCM_CGROUP Jan Kaluza
2013-08-28 14:00   ` Tejun Heo
     [not found] ` <1377614400-27122-1-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2013-08-29 14:13   ` [PATCH v2 0/3] Send audit/procinfo/cgroup data in socket-level control message Jan Kaluza
2013-08-29 14:13     ` Jan Kaluza
     [not found]     ` <1377785602-10766-1-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2013-08-29 14:13       ` [PATCH v2 1/3] Send loginuid and sessionid in SCM_AUDIT Jan Kaluza
2013-08-29 14:13         ` Jan Kaluza
2013-08-29 14:13       ` [PATCH v2 2/3] Send comm and cmdline in SCM_PROCINFO Jan Kaluza
2013-08-29 14:13         ` Jan Kaluza
2013-08-29 14:13       ` [PATCH v2 3/3] Send cgroup_path in SCM_CGROUP Jan Kaluza
2013-08-29 14:13         ` Jan Kaluza
     [not found]         ` <1377785602-10766-4-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2013-09-02 17:17           ` Kay Sievers
2013-09-02 17:17             ` Kay Sievers
2013-09-04  6:14   ` [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message Jan Kaluza
2013-09-04  6:14     ` Jan Kaluza
     [not found]     ` <1378275261-4553-1-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2013-09-04  6:14       ` [PATCH v3 1/3] Send loginuid and sessionid in SCM_AUDIT Jan Kaluza
2013-09-04  6:14         ` Jan Kaluza
2013-09-04  7:22         ` Eric W. Biederman
2013-09-04  7:22           ` Eric W. Biederman
     [not found]           ` <87bo49gifv.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
2013-09-04  9:07             ` Jan Kaluža
2013-09-04  9:07               ` Jan Kaluža
     [not found]         ` <1378275261-4553-2-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2013-09-04  7:22           ` Eric W. Biederman
2013-09-04  6:14       ` [PATCH v3 2/3] Send comm and cmdline in SCM_PROCINFO Jan Kaluza
2013-09-04  6:14         ` Jan Kaluza
2013-09-04  6:14       ` [PATCH v3 3/3] Send cgroup_path in SCM_CGROUP Jan Kaluza
2013-09-04  7:42       ` [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message Eric W. Biederman
2013-09-04  6:14     ` [PATCH v3 3/3] Send cgroup_path in SCM_CGROUP Jan Kaluza
2013-09-04  7:42     ` [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message Eric W. Biederman
2013-09-04  7:42       ` Eric W. Biederman
     [not found]       ` <878uzdf2xp.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
2013-09-04 14:45         ` Tejun Heo
2013-09-04 14:45           ` Tejun Heo
2013-09-04 14:58         ` Richard Guy Briggs
2013-09-04 14:58           ` Richard Guy Briggs
     [not found]           ` <20130904145830.GC28517-bcJWsdo4jJjeVoXN4CMphl7TgLCtbB0G@public.gmane.org>
2013-09-04 15:04             ` Jan Kaluža
2013-09-04 15:20             ` Richard Guy Briggs
2013-09-04 15:04           ` Jan Kaluža
2013-09-04 15:04             ` Jan Kaluža
2013-09-04 15:20           ` Richard Guy Briggs
2013-09-04 15:20             ` Richard Guy Briggs
     [not found]             ` <20130904152022.GD28517-bcJWsdo4jJjeVoXN4CMphl7TgLCtbB0G@public.gmane.org>
2013-09-04 15:30               ` Eric Dumazet
2013-09-04 15:30                 ` Eric Dumazet
2013-09-04 15:40                 ` Jan Kaluža
2013-09-04 15:40                   ` Jan Kaluža
2013-09-04 15:40                 ` Jan Kaluža
2014-01-13  8:01   ` [PATCH v4 " Jan Kaluza
2014-01-13  8:01     ` Jan Kaluza
     [not found]     ` <1389600109-30739-1-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2014-01-13  8:01       ` [PATCH v4 1/3] Send loginuid and sessionid in SCM_AUDIT Jan Kaluza
2014-01-13  8:01         ` Jan Kaluza
     [not found]         ` <1389600109-30739-2-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2014-01-15  4:02           ` Richard Guy Briggs
2014-01-15  4:02             ` Richard Guy Briggs
2014-01-13  8:01       ` [PATCH v4 2/3] Send comm and cmdline in SCM_PROCINFO Jan Kaluza
2014-01-13  8:01         ` Jan Kaluza
     [not found]         ` <1389600109-30739-3-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2014-01-15  4:03           ` Richard Guy Briggs
2014-01-15  4:03             ` Richard Guy Briggs
2014-01-13  8:01       ` [PATCH v4 3/3] Send cgroup_path in SCM_CGROUP Jan Kaluza
2014-01-13  8:01         ` Jan Kaluza
     [not found]         ` <1389600109-30739-4-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2014-01-13 16:52           ` Tejun Heo
2014-01-13 16:52             ` Tejun Heo
2014-01-13 16:55       ` [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message Tejun Heo
2014-01-13 16:55         ` Tejun Heo
2014-01-13 19:44       ` Casey Schaufler
2014-01-15 20:17       ` David Miller
2014-01-15 20:17         ` David Miller
     [not found]         ` <20140115.121730.1984913330507219167.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
2014-01-15 23:21           ` Eric Paris
2014-01-15 23:21             ` Eric Paris
     [not found]             ` <1389828103.681.34.camel-OjZBOOqb7SR7cYLChsl7DafLeoKvNuZc@public.gmane.org>
2014-01-15 23:23               ` Tejun Heo
2014-01-15 23:23                 ` Tejun Heo
     [not found]                 ` <20140115232345.GA22237-9pTldWuhBndy/B6EtB590w@public.gmane.org>
2014-01-16  9:29                   ` Jan Kaluža
2014-01-16  9:29                     ` Jan Kaluža
2014-01-23 19:31                     ` Kay Sievers
2014-01-23 19:31                       ` Kay Sievers
2014-01-23 19:31                       ` Kay Sievers
     [not found]                     ` <52D7A68F.5030700-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2014-01-23 19:31                       ` Kay Sievers
2014-01-13 19:44     ` Casey Schaufler
     [not found]       ` <52D44206.2000906-iSGtlc1asvQWG2LlvL+J4A@public.gmane.org>
2014-01-14  8:25         ` Jan Kaluža
2014-01-14  8:25           ` Jan Kaluža

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.