* [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; 39+ 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] 39+ 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; 39+ 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] 39+ 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; 39+ 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] 39+ 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; 39+ 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] 39+ 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; 39+ 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] 39+ 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; 39+ 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] 39+ messages in thread
[parent not found: <1377614400-27122-1-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>]
* [PATCH v2 0/3] Send audit/procinfo/cgroup data in socket-level control message [not found] ` <1377614400-27122-1-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> @ 2013-08-29 14:13 ` Jan Kaluza [not found] ` <1377785602-10766-1-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> 2013-09-04 6:14 ` [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message Jan Kaluza 2014-01-13 8:01 ` [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message Jan Kaluza 2 siblings, 1 reply; 39+ 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] 39+ messages in thread
[parent not found: <1377785602-10766-1-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>]
* [PATCH v2 1/3] Send loginuid and sessionid in SCM_AUDIT [not found] ` <1377785602-10766-1-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> @ 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 ` [PATCH v2 3/3] Send cgroup_path in SCM_CGROUP Jan Kaluza 2 siblings, 0 replies; 39+ 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] 39+ messages in thread
* [PATCH v2 2/3] Send comm and cmdline in SCM_PROCINFO [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 3/3] Send cgroup_path in SCM_CGROUP Jan Kaluza 2 siblings, 0 replies; 39+ 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] 39+ messages in thread
* [PATCH v2 3/3] Send cgroup_path in SCM_CGROUP [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 ` [PATCH v2 2/3] Send comm and cmdline in SCM_PROCINFO Jan Kaluza @ 2013-08-29 14:13 ` Jan Kaluza [not found] ` <1377785602-10766-4-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> 2 siblings, 1 reply; 39+ 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] 39+ messages in thread
[parent not found: <1377785602-10766-4-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>]
* Re: [PATCH v2 3/3] Send cgroup_path in SCM_CGROUP [not found] ` <1377785602-10766-4-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> @ 2013-09-02 17:17 ` Kay Sievers 0 siblings, 0 replies; 39+ 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] 39+ messages in thread
* [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message [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-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 3/3] Send cgroup_path in SCM_CGROUP Jan Kaluza 2014-01-13 8:01 ` [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message Jan Kaluza 2 siblings, 2 replies; 39+ 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] 39+ messages in thread
[parent not found: <1378275261-4553-1-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>]
* [PATCH v3 1/3] Send loginuid and sessionid in SCM_AUDIT [not found] ` <1378275261-4553-1-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> @ 2013-09-04 6:14 ` Jan Kaluza [not found] ` <1378275261-4553-2-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> 2013-09-04 6:14 ` [PATCH v3 2/3] Send comm and cmdline in SCM_PROCINFO Jan Kaluza 2013-09-04 7:42 ` [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message Eric W. Biederman 2 siblings, 1 reply; 39+ 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] 39+ messages in thread
[parent not found: <1378275261-4553-2-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>]
* 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 [not found] ` <87bo49gifv.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org> 0 siblings, 1 reply; 39+ 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] 39+ messages in thread
[parent not found: <87bo49gifv.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>]
* Re: [PATCH v3 1/3] Send loginuid and sessionid in SCM_AUDIT [not found] ` <87bo49gifv.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org> @ 2013-09-04 9:07 ` Jan Kaluža 0 siblings, 0 replies; 39+ 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] 39+ messages in thread
* [PATCH v3 2/3] Send comm and cmdline in SCM_PROCINFO [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:42 ` [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message Eric W. Biederman 2 siblings, 0 replies; 39+ 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] 39+ 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 6:14 ` [PATCH v3 1/3] Send loginuid and sessionid in SCM_AUDIT Jan Kaluza 2013-09-04 6:14 ` [PATCH v3 2/3] Send comm and cmdline in SCM_PROCINFO Jan Kaluza @ 2013-09-04 7:42 ` Eric W. Biederman [not found] ` <878uzdf2xp.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org> 2 siblings, 1 reply; 39+ 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] 39+ messages in thread
[parent not found: <878uzdf2xp.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>]
* Re: [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message [not found] ` <878uzdf2xp.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org> @ 2013-09-04 14:45 ` Tejun Heo 2013-09-04 14:58 ` Richard Guy Briggs 1 sibling, 0 replies; 39+ 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] 39+ messages in thread
* Re: [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message [not found] ` <878uzdf2xp.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org> 2013-09-04 14:45 ` Tejun Heo @ 2013-09-04 14:58 ` Richard Guy Briggs [not found] ` <20130904145830.GC28517-bcJWsdo4jJjeVoXN4CMphl7TgLCtbB0G@public.gmane.org> 1 sibling, 1 reply; 39+ 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] 39+ messages in thread
[parent not found: <20130904145830.GC28517-bcJWsdo4jJjeVoXN4CMphl7TgLCtbB0G@public.gmane.org>]
* 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; 39+ 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] 39+ 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 [not found] ` <20130904152022.GD28517-bcJWsdo4jJjeVoXN4CMphl7TgLCtbB0G@public.gmane.org> 1 sibling, 1 reply; 39+ 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] 39+ messages in thread
[parent not found: <20130904152022.GD28517-bcJWsdo4jJjeVoXN4CMphl7TgLCtbB0G@public.gmane.org>]
* Re: [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message [not found] ` <20130904152022.GD28517-bcJWsdo4jJjeVoXN4CMphl7TgLCtbB0G@public.gmane.org> @ 2013-09-04 15:30 ` Eric Dumazet 2013-09-04 15:40 ` Jan Kaluža 0 siblings, 1 reply; 39+ 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] 39+ 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 0 siblings, 0 replies; 39+ 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] 39+ messages in thread
* [PATCH v3 3/3] Send cgroup_path in SCM_CGROUP 2013-09-04 6:14 ` [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message Jan Kaluza [not found] ` <1378275261-4553-1-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> @ 2013-09-04 6:14 ` Jan Kaluza 1 sibling, 0 replies; 39+ 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] 39+ messages in thread
* [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message [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-09-04 6:14 ` [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message 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 19:44 ` Casey Schaufler 2 siblings, 2 replies; 39+ 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] 39+ messages in thread
[parent not found: <1389600109-30739-1-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>]
* [PATCH v4 1/3] Send loginuid and sessionid in SCM_AUDIT [not found] ` <1389600109-30739-1-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> @ 2014-01-13 8:01 ` Jan Kaluza [not found] ` <1389600109-30739-2-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> 2014-01-13 8:01 ` [PATCH v4 2/3] Send comm and cmdline in SCM_PROCINFO Jan Kaluza ` (3 subsequent siblings) 4 siblings, 1 reply; 39+ 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] 39+ messages in thread
[parent not found: <1389600109-30739-2-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>]
* Re: [PATCH v4 1/3] Send loginuid and sessionid in SCM_AUDIT [not found] ` <1389600109-30739-2-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> @ 2014-01-15 4:02 ` Richard Guy Briggs 0 siblings, 0 replies; 39+ 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] 39+ messages in thread
* [PATCH v4 2/3] Send comm and cmdline in SCM_PROCINFO [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-3-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> 2014-01-13 8:01 ` [PATCH v4 3/3] Send cgroup_path in SCM_CGROUP Jan Kaluza ` (2 subsequent siblings) 4 siblings, 1 reply; 39+ 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] 39+ messages in thread
[parent not found: <1389600109-30739-3-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>]
* Re: [PATCH v4 2/3] Send comm and cmdline in SCM_PROCINFO [not found] ` <1389600109-30739-3-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> @ 2014-01-15 4:03 ` Richard Guy Briggs 0 siblings, 0 replies; 39+ 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] 39+ messages in thread
* [PATCH v4 3/3] Send cgroup_path in SCM_CGROUP [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 ` [PATCH v4 2/3] Send comm and cmdline in SCM_PROCINFO 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:55 ` [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message Tejun Heo 2014-01-15 20:17 ` David Miller 4 siblings, 1 reply; 39+ 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] 39+ messages in thread
[parent not found: <1389600109-30739-4-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>]
* Re: [PATCH v4 3/3] Send cgroup_path in SCM_CGROUP [not found] ` <1389600109-30739-4-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> @ 2014-01-13 16:52 ` Tejun Heo 0 siblings, 0 replies; 39+ 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] 39+ 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> ` (2 preceding siblings ...) 2014-01-13 8:01 ` [PATCH v4 3/3] Send cgroup_path in SCM_CGROUP Jan Kaluza @ 2014-01-13 16:55 ` Tejun Heo 2014-01-15 20:17 ` David Miller 4 siblings, 0 replies; 39+ 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] 39+ 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 ` [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message Tejun Heo @ 2014-01-15 20:17 ` David Miller [not found] ` <20140115.121730.1984913330507219167.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org> 4 siblings, 1 reply; 39+ 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] 39+ messages in thread
[parent not found: <20140115.121730.1984913330507219167.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>]
* Re: [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message [not found] ` <20140115.121730.1984913330507219167.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org> @ 2014-01-15 23:21 ` Eric Paris [not found] ` <1389828103.681.34.camel-OjZBOOqb7SR7cYLChsl7DafLeoKvNuZc@public.gmane.org> 0 siblings, 1 reply; 39+ 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] 39+ messages in thread
[parent not found: <1389828103.681.34.camel-OjZBOOqb7SR7cYLChsl7DafLeoKvNuZc@public.gmane.org>]
* Re: [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message [not found] ` <1389828103.681.34.camel-OjZBOOqb7SR7cYLChsl7DafLeoKvNuZc@public.gmane.org> @ 2014-01-15 23:23 ` Tejun Heo [not found] ` <20140115232345.GA22237-9pTldWuhBndy/B6EtB590w@public.gmane.org> 0 siblings, 1 reply; 39+ 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] 39+ messages in thread
[parent not found: <20140115232345.GA22237-9pTldWuhBndy/B6EtB590w@public.gmane.org>]
* Re: [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message [not found] ` <20140115232345.GA22237-9pTldWuhBndy/B6EtB590w@public.gmane.org> @ 2014-01-16 9:29 ` Jan Kaluža [not found] ` <52D7A68F.5030700-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> 0 siblings, 1 reply; 39+ 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] 39+ messages in thread
[parent not found: <52D7A68F.5030700-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>]
* 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; 39+ 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] 39+ messages in thread
* Re: [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message 2014-01-13 8:01 ` [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message Jan Kaluza [not found] ` <1389600109-30739-1-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> @ 2014-01-13 19:44 ` Casey Schaufler [not found] ` <52D44206.2000906-iSGtlc1asvQWG2LlvL+J4A@public.gmane.org> 1 sibling, 1 reply; 39+ 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] 39+ messages in thread
[parent not found: <52D44206.2000906-iSGtlc1asvQWG2LlvL+J4A@public.gmane.org>]
* Re: [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message [not found] ` <52D44206.2000906-iSGtlc1asvQWG2LlvL+J4A@public.gmane.org> @ 2014-01-14 8:25 ` Jan Kaluža 0 siblings, 0 replies; 39+ 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] 39+ messages in thread
end of thread, other threads:[~2014-01-23 19:31 UTC | newest] Thread overview: 39+ 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 [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 ` [PATCH v2 2/3] Send comm and cmdline in SCM_PROCINFO Jan Kaluza 2013-08-29 14:13 ` [PATCH v2 3/3] Send cgroup_path in SCM_CGROUP 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-04 6:14 ` [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message 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 [not found] ` <1378275261-4553-2-git-send-email-jkaluza-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> 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 6:14 ` [PATCH v3 2/3] Send comm and cmdline in SCM_PROCINFO Jan Kaluza 2013-09-04 7:42 ` [PATCH v3 0/3] Send audit/procinfo/cgroup data in socket-level control message Eric W. Biederman [not found] ` <878uzdf2xp.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org> 2013-09-04 14:45 ` Tejun Heo 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 [not found] ` <20130904152022.GD28517-bcJWsdo4jJjeVoXN4CMphl7TgLCtbB0G@public.gmane.org> 2013-09-04 15:30 ` Eric Dumazet 2013-09-04 15:40 ` Jan Kaluža 2013-09-04 6:14 ` [PATCH v3 3/3] Send cgroup_path in SCM_CGROUP Jan Kaluza 2014-01-13 8:01 ` [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message 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 [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-13 8:01 ` [PATCH v4 2/3] Send comm and cmdline in SCM_PROCINFO 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-13 8:01 ` [PATCH v4 3/3] Send cgroup_path in SCM_CGROUP 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:55 ` [PATCH v4 0/3] Send audit/procinfo/cgroup data in socket-level control message Tejun Heo 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 [not found] ` <1389828103.681.34.camel-OjZBOOqb7SR7cYLChsl7DafLeoKvNuZc@public.gmane.org> 2014-01-15 23:23 ` Tejun Heo [not found] ` <20140115232345.GA22237-9pTldWuhBndy/B6EtB590w@public.gmane.org> 2014-01-16 9:29 ` Jan Kaluža [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
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).