aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2012-05-24 19:58:08 -0400
committerEric W. Biederman <ebiederm@xmission.com>2012-08-15 00:55:20 -0400
commitd06ca9564350184a19b5aae9ac150f1b1306de29 (patch)
treea6f5e39232911fe0582690f223390997a84f0b86 /net
parentc336d148adc4181f31741ae066df41429be64b67 (diff)
userns: Teach inet_diag to work with user namespaces
Compute the user namespace of the socket that we are replying to and translate the kuids of reported sockets into that user namespace. Cc: Andrew Vagin <avagin@openvz.org> Acked-by: David S. Miller <davem@davemloft.net> Acked-by: Pavel Emelyanov <xemul@parallels.com> Acked-by: Serge Hallyn <serge.hallyn@canonical.com> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/inet_diag.c21
-rw-r--r--net/ipv4/udp_diag.c5
2 files changed, 19 insertions, 7 deletions
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 570e61f9611f..8bc005b1435f 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -69,6 +69,7 @@ static inline void inet_diag_unlock_handler(
69 69
70int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, 70int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
71 struct sk_buff *skb, struct inet_diag_req_v2 *req, 71 struct sk_buff *skb, struct inet_diag_req_v2 *req,
72 struct user_namespace *user_ns,
72 u32 pid, u32 seq, u16 nlmsg_flags, 73 u32 pid, u32 seq, u16 nlmsg_flags,
73 const struct nlmsghdr *unlh) 74 const struct nlmsghdr *unlh)
74{ 75{
@@ -124,7 +125,7 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
124 } 125 }
125#endif 126#endif
126 127
127 r->idiag_uid = sock_i_uid(sk); 128 r->idiag_uid = from_kuid_munged(user_ns, sock_i_uid(sk));
128 r->idiag_inode = sock_i_ino(sk); 129 r->idiag_inode = sock_i_ino(sk);
129 130
130 if (ext & (1 << (INET_DIAG_MEMINFO - 1))) { 131 if (ext & (1 << (INET_DIAG_MEMINFO - 1))) {
@@ -199,11 +200,12 @@ EXPORT_SYMBOL_GPL(inet_sk_diag_fill);
199 200
200static int inet_csk_diag_fill(struct sock *sk, 201static int inet_csk_diag_fill(struct sock *sk,
201 struct sk_buff *skb, struct inet_diag_req_v2 *req, 202 struct sk_buff *skb, struct inet_diag_req_v2 *req,
203 struct user_namespace *user_ns,
202 u32 pid, u32 seq, u16 nlmsg_flags, 204 u32 pid, u32 seq, u16 nlmsg_flags,
203 const struct nlmsghdr *unlh) 205 const struct nlmsghdr *unlh)
204{ 206{
205 return inet_sk_diag_fill(sk, inet_csk(sk), 207 return inet_sk_diag_fill(sk, inet_csk(sk),
206 skb, req, pid, seq, nlmsg_flags, unlh); 208 skb, req, user_ns, pid, seq, nlmsg_flags, unlh);
207} 209}
208 210
209static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, 211static int inet_twsk_diag_fill(struct inet_timewait_sock *tw,
@@ -256,14 +258,16 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw,
256} 258}
257 259
258static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, 260static int sk_diag_fill(struct sock *sk, struct sk_buff *skb,
259 struct inet_diag_req_v2 *r, u32 pid, u32 seq, u16 nlmsg_flags, 261 struct inet_diag_req_v2 *r,
262 struct user_namespace *user_ns,
263 u32 pid, u32 seq, u16 nlmsg_flags,
260 const struct nlmsghdr *unlh) 264 const struct nlmsghdr *unlh)
261{ 265{
262 if (sk->sk_state == TCP_TIME_WAIT) 266 if (sk->sk_state == TCP_TIME_WAIT)
263 return inet_twsk_diag_fill((struct inet_timewait_sock *)sk, 267 return inet_twsk_diag_fill((struct inet_timewait_sock *)sk,
264 skb, r, pid, seq, nlmsg_flags, 268 skb, r, pid, seq, nlmsg_flags,
265 unlh); 269 unlh);
266 return inet_csk_diag_fill(sk, skb, r, pid, seq, nlmsg_flags, unlh); 270 return inet_csk_diag_fill(sk, skb, r, user_ns, pid, seq, nlmsg_flags, unlh);
267} 271}
268 272
269int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_skb, 273int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_skb,
@@ -311,6 +315,7 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_s
311 } 315 }
312 316
313 err = sk_diag_fill(sk, rep, req, 317 err = sk_diag_fill(sk, rep, req,
318 sk_user_ns(NETLINK_CB(in_skb).ssk),
314 NETLINK_CB(in_skb).pid, 319 NETLINK_CB(in_skb).pid,
315 nlh->nlmsg_seq, 0, nlh); 320 nlh->nlmsg_seq, 0, nlh);
316 if (err < 0) { 321 if (err < 0) {
@@ -551,6 +556,7 @@ static int inet_csk_diag_dump(struct sock *sk,
551 return 0; 556 return 0;
552 557
553 return inet_csk_diag_fill(sk, skb, r, 558 return inet_csk_diag_fill(sk, skb, r,
559 sk_user_ns(NETLINK_CB(cb->skb).ssk),
554 NETLINK_CB(cb->skb).pid, 560 NETLINK_CB(cb->skb).pid,
555 cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh); 561 cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh);
556} 562}
@@ -591,7 +597,9 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw,
591} 597}
592 598
593static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, 599static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk,
594 struct request_sock *req, u32 pid, u32 seq, 600 struct request_sock *req,
601 struct user_namespace *user_ns,
602 u32 pid, u32 seq,
595 const struct nlmsghdr *unlh) 603 const struct nlmsghdr *unlh)
596{ 604{
597 const struct inet_request_sock *ireq = inet_rsk(req); 605 const struct inet_request_sock *ireq = inet_rsk(req);
@@ -625,7 +633,7 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk,
625 r->idiag_expires = jiffies_to_msecs(tmo); 633 r->idiag_expires = jiffies_to_msecs(tmo);
626 r->idiag_rqueue = 0; 634 r->idiag_rqueue = 0;
627 r->idiag_wqueue = 0; 635 r->idiag_wqueue = 0;
628 r->idiag_uid = sock_i_uid(sk); 636 r->idiag_uid = from_kuid_munged(user_ns, sock_i_uid(sk));
629 r->idiag_inode = 0; 637 r->idiag_inode = 0;
630#if IS_ENABLED(CONFIG_IPV6) 638#if IS_ENABLED(CONFIG_IPV6)
631 if (r->idiag_family == AF_INET6) { 639 if (r->idiag_family == AF_INET6) {
@@ -702,6 +710,7 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk,
702 } 710 }
703 711
704 err = inet_diag_fill_req(skb, sk, req, 712 err = inet_diag_fill_req(skb, sk, req,
713 sk_user_ns(NETLINK_CB(cb->skb).ssk),
705 NETLINK_CB(cb->skb).pid, 714 NETLINK_CB(cb->skb).pid,
706 cb->nlh->nlmsg_seq, cb->nlh); 715 cb->nlh->nlmsg_seq, cb->nlh);
707 if (err < 0) { 716 if (err < 0) {
diff --git a/net/ipv4/udp_diag.c b/net/ipv4/udp_diag.c
index 16d0960062be..d2f336ea82ca 100644
--- a/net/ipv4/udp_diag.c
+++ b/net/ipv4/udp_diag.c
@@ -24,7 +24,9 @@ static int sk_diag_dump(struct sock *sk, struct sk_buff *skb,
24 if (!inet_diag_bc_sk(bc, sk)) 24 if (!inet_diag_bc_sk(bc, sk))
25 return 0; 25 return 0;
26 26
27 return inet_sk_diag_fill(sk, NULL, skb, req, NETLINK_CB(cb->skb).pid, 27 return inet_sk_diag_fill(sk, NULL, skb, req,
28 sk_user_ns(NETLINK_CB(cb->skb).ssk),
29 NETLINK_CB(cb->skb).pid,
28 cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh); 30 cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh);
29} 31}
30 32
@@ -69,6 +71,7 @@ static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb,
69 goto out; 71 goto out;
70 72
71 err = inet_sk_diag_fill(sk, NULL, rep, req, 73 err = inet_sk_diag_fill(sk, NULL, rep, req,
74 sk_user_ns(NETLINK_CB(in_skb).ssk),
72 NETLINK_CB(in_skb).pid, 75 NETLINK_CB(in_skb).pid,
73 nlh->nlmsg_seq, 0, nlh); 76 nlh->nlmsg_seq, 0, nlh);
74 if (err < 0) { 77 if (err < 0) {