diff options
-rw-r--r-- | include/uapi/linux/unix_diag.h | 2 | ||||
-rw-r--r-- | net/unix/diag.c | 12 |
2 files changed, 14 insertions, 0 deletions
diff --git a/include/uapi/linux/unix_diag.h b/include/uapi/linux/unix_diag.h index 5c502fdf7a42..a1988576fa8a 100644 --- a/include/uapi/linux/unix_diag.h +++ b/include/uapi/linux/unix_diag.h | |||
@@ -20,6 +20,7 @@ struct unix_diag_req { | |||
20 | #define UDIAG_SHOW_ICONS 0x00000008 /* show pending connections */ | 20 | #define UDIAG_SHOW_ICONS 0x00000008 /* show pending connections */ |
21 | #define UDIAG_SHOW_RQLEN 0x00000010 /* show skb receive queue len */ | 21 | #define UDIAG_SHOW_RQLEN 0x00000010 /* show skb receive queue len */ |
22 | #define UDIAG_SHOW_MEMINFO 0x00000020 /* show memory info of a socket */ | 22 | #define UDIAG_SHOW_MEMINFO 0x00000020 /* show memory info of a socket */ |
23 | #define UDIAG_SHOW_UID 0x00000040 /* show socket's UID */ | ||
23 | 24 | ||
24 | struct unix_diag_msg { | 25 | struct unix_diag_msg { |
25 | __u8 udiag_family; | 26 | __u8 udiag_family; |
@@ -40,6 +41,7 @@ enum { | |||
40 | UNIX_DIAG_RQLEN, | 41 | UNIX_DIAG_RQLEN, |
41 | UNIX_DIAG_MEMINFO, | 42 | UNIX_DIAG_MEMINFO, |
42 | UNIX_DIAG_SHUTDOWN, | 43 | UNIX_DIAG_SHUTDOWN, |
44 | UNIX_DIAG_UID, | ||
43 | 45 | ||
44 | __UNIX_DIAG_MAX, | 46 | __UNIX_DIAG_MAX, |
45 | }; | 47 | }; |
diff --git a/net/unix/diag.c b/net/unix/diag.c index c51a707260fa..9ff64f9df1f3 100644 --- a/net/unix/diag.c +++ b/net/unix/diag.c | |||
@@ -5,9 +5,11 @@ | |||
5 | #include <linux/unix_diag.h> | 5 | #include <linux/unix_diag.h> |
6 | #include <linux/skbuff.h> | 6 | #include <linux/skbuff.h> |
7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
8 | #include <linux/uidgid.h> | ||
8 | #include <net/netlink.h> | 9 | #include <net/netlink.h> |
9 | #include <net/af_unix.h> | 10 | #include <net/af_unix.h> |
10 | #include <net/tcp_states.h> | 11 | #include <net/tcp_states.h> |
12 | #include <net/sock.h> | ||
11 | 13 | ||
12 | static int sk_diag_dump_name(struct sock *sk, struct sk_buff *nlskb) | 14 | static int sk_diag_dump_name(struct sock *sk, struct sk_buff *nlskb) |
13 | { | 15 | { |
@@ -111,6 +113,12 @@ static int sk_diag_show_rqlen(struct sock *sk, struct sk_buff *nlskb) | |||
111 | return nla_put(nlskb, UNIX_DIAG_RQLEN, sizeof(rql), &rql); | 113 | return nla_put(nlskb, UNIX_DIAG_RQLEN, sizeof(rql), &rql); |
112 | } | 114 | } |
113 | 115 | ||
116 | static int sk_diag_dump_uid(struct sock *sk, struct sk_buff *nlskb) | ||
117 | { | ||
118 | uid_t uid = from_kuid_munged(sk_user_ns(nlskb->sk), sock_i_uid(sk)); | ||
119 | return nla_put(nlskb, UNIX_DIAG_UID, sizeof(uid_t), &uid); | ||
120 | } | ||
121 | |||
114 | static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_req *req, | 122 | static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_req *req, |
115 | u32 portid, u32 seq, u32 flags, int sk_ino) | 123 | u32 portid, u32 seq, u32 flags, int sk_ino) |
116 | { | 124 | { |
@@ -157,6 +165,10 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_r | |||
157 | if (nla_put_u8(skb, UNIX_DIAG_SHUTDOWN, sk->sk_shutdown)) | 165 | if (nla_put_u8(skb, UNIX_DIAG_SHUTDOWN, sk->sk_shutdown)) |
158 | goto out_nlmsg_trim; | 166 | goto out_nlmsg_trim; |
159 | 167 | ||
168 | if ((req->udiag_show & UDIAG_SHOW_UID) && | ||
169 | sk_diag_dump_uid(sk, skb)) | ||
170 | goto out_nlmsg_trim; | ||
171 | |||
160 | nlmsg_end(skb, nlh); | 172 | nlmsg_end(skb, nlh); |
161 | return 0; | 173 | return 0; |
162 | 174 | ||