aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/inet_diag.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/inet_diag.c')
-rw-r--r--net/ipv4/inet_diag.c45
1 files changed, 27 insertions, 18 deletions
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 570e61f9611f..535584c00f91 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -69,7 +69,8 @@ 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 u32 pid, u32 seq, u16 nlmsg_flags, 72 struct user_namespace *user_ns,
73 u32 portid, u32 seq, u16 nlmsg_flags,
73 const struct nlmsghdr *unlh) 74 const struct nlmsghdr *unlh)
74{ 75{
75 const struct inet_sock *inet = inet_sk(sk); 76 const struct inet_sock *inet = inet_sk(sk);
@@ -83,7 +84,7 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
83 handler = inet_diag_table[req->sdiag_protocol]; 84 handler = inet_diag_table[req->sdiag_protocol];
84 BUG_ON(handler == NULL); 85 BUG_ON(handler == NULL);
85 86
86 nlh = nlmsg_put(skb, pid, seq, unlh->nlmsg_type, sizeof(*r), 87 nlh = nlmsg_put(skb, portid, seq, unlh->nlmsg_type, sizeof(*r),
87 nlmsg_flags); 88 nlmsg_flags);
88 if (!nlh) 89 if (!nlh)
89 return -EMSGSIZE; 90 return -EMSGSIZE;
@@ -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,23 +200,24 @@ 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,
202 u32 pid, u32 seq, u16 nlmsg_flags, 203 struct user_namespace *user_ns,
204 u32 portid, 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, portid, 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,
210 struct sk_buff *skb, struct inet_diag_req_v2 *req, 212 struct sk_buff *skb, struct inet_diag_req_v2 *req,
211 u32 pid, u32 seq, u16 nlmsg_flags, 213 u32 portid, u32 seq, u16 nlmsg_flags,
212 const struct nlmsghdr *unlh) 214 const struct nlmsghdr *unlh)
213{ 215{
214 long tmo; 216 long tmo;
215 struct inet_diag_msg *r; 217 struct inet_diag_msg *r;
216 struct nlmsghdr *nlh; 218 struct nlmsghdr *nlh;
217 219
218 nlh = nlmsg_put(skb, pid, seq, unlh->nlmsg_type, sizeof(*r), 220 nlh = nlmsg_put(skb, portid, seq, unlh->nlmsg_type, sizeof(*r),
219 nlmsg_flags); 221 nlmsg_flags);
220 if (!nlh) 222 if (!nlh)
221 return -EMSGSIZE; 223 return -EMSGSIZE;
@@ -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 portid, 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, portid, 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, portid, 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,14 +315,15 @@ 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,
314 NETLINK_CB(in_skb).pid, 318 sk_user_ns(NETLINK_CB(in_skb).ssk),
319 NETLINK_CB(in_skb).portid,
315 nlh->nlmsg_seq, 0, nlh); 320 nlh->nlmsg_seq, 0, nlh);
316 if (err < 0) { 321 if (err < 0) {
317 WARN_ON(err == -EMSGSIZE); 322 WARN_ON(err == -EMSGSIZE);
318 nlmsg_free(rep); 323 nlmsg_free(rep);
319 goto out; 324 goto out;
320 } 325 }
321 err = netlink_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).pid, 326 err = netlink_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).portid,
322 MSG_DONTWAIT); 327 MSG_DONTWAIT);
323 if (err > 0) 328 if (err > 0)
324 err = 0; 329 err = 0;
@@ -551,7 +556,8 @@ 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,
554 NETLINK_CB(cb->skb).pid, 559 sk_user_ns(NETLINK_CB(cb->skb).ssk),
560 NETLINK_CB(cb->skb).portid,
555 cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh); 561 cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh);
556} 562}
557 563
@@ -586,12 +592,14 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw,
586 } 592 }
587 593
588 return inet_twsk_diag_fill(tw, skb, r, 594 return inet_twsk_diag_fill(tw, skb, r,
589 NETLINK_CB(cb->skb).pid, 595 NETLINK_CB(cb->skb).portid,
590 cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh); 596 cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh);
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 portid, 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);
@@ -600,7 +608,7 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk,
600 struct nlmsghdr *nlh; 608 struct nlmsghdr *nlh;
601 long tmo; 609 long tmo;
602 610
603 nlh = nlmsg_put(skb, pid, seq, unlh->nlmsg_type, sizeof(*r), 611 nlh = nlmsg_put(skb, portid, seq, unlh->nlmsg_type, sizeof(*r),
604 NLM_F_MULTI); 612 NLM_F_MULTI);
605 if (!nlh) 613 if (!nlh)
606 return -EMSGSIZE; 614 return -EMSGSIZE;
@@ -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,7 +710,8 @@ 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,
705 NETLINK_CB(cb->skb).pid, 713 sk_user_ns(NETLINK_CB(cb->skb).ssk),
714 NETLINK_CB(cb->skb).portid,
706 cb->nlh->nlmsg_seq, cb->nlh); 715 cb->nlh->nlmsg_seq, cb->nlh);
707 if (err < 0) { 716 if (err < 0) {
708 cb->args[3] = j + 1; 717 cb->args[3] = j + 1;