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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to