All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Dumazet <eric.dumazet@gmail.com>
To: dormando <dormando@rydia.net>
Cc: "Alexey Preobrazhensky" <preobr@google.com>,
	"Steffen Klassert" <steffen.klassert@secunet.com>,
	"David Miller" <davem@davemloft.net>,
	paulmck@linux.vnet.ibm.com, netdev@vger.kernel.org,
	"Kostya Serebryany" <kcc@google.com>,
	"Dmitry Vyukov" <dvyukov@google.com>,
	"Lars Bull" <larsbull@google.com>,
	"Eric Dumazet" <edumazet@google.com>,
	"Bruce Curtis" <brutus@google.com>,
	"Maciej Żenczykowski" <maze@google.com>,
	"Alexei Starovoitov" <alexei.starovoitov@gmail.com>
Subject: Re: [PATCH] ipv4: fix a race in ip4_datagram_release_cb()
Date: Tue, 10 Jun 2014 18:26:49 -0700	[thread overview]
Message-ID: <1402450009.3645.444.camel@edumazet-glaptop2.roam.corp.google.com> (raw)
In-Reply-To: <1402449173.3645.440.camel@edumazet-glaptop2.roam.corp.google.com>

On Tue, 2014-06-10 at 18:12 -0700, Eric Dumazet wrote:

> 
> For the curious, another problem is in ipv4_sk_update_pmtu()
> 
> This can be called on UDP sockets, but from softirq context.
> 
> We cannot use sk_dst_lock because this lock is not softirq safe.
> 
> I guess we should use xchg() for sk_dst_set() and sk_dst_reset()

This would be something like this untested patch :

 include/net/sock.h |   12 ++++++------
 net/ipv4/route.c   |   15 ++++++++-------
 2 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/include/net/sock.h b/include/net/sock.h
index 21569cf456ed..04400978ceb5 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1766,9 +1766,11 @@ __sk_dst_set(struct sock *sk, struct dst_entry *dst)
 static inline void
 sk_dst_set(struct sock *sk, struct dst_entry *dst)
 {
-	spin_lock(&sk->sk_dst_lock);
-	__sk_dst_set(sk, dst);
-	spin_unlock(&sk->sk_dst_lock);
+	struct dst_entry *old_dst;
+
+	sk_tx_queue_clear(sk);
+	old_dst = xchg(&sk->sk_dst_cache, dst);
+	dst_release(old_dst);
 }
 
 static inline void
@@ -1780,9 +1782,7 @@ __sk_dst_reset(struct sock *sk)
 static inline void
 sk_dst_reset(struct sock *sk)
 {
-	spin_lock(&sk->sk_dst_lock);
-	__sk_dst_reset(sk);
-	spin_unlock(&sk->sk_dst_lock);
+	sk_dst_set(sk, NULL);
 }
 
 struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 5e676be3daeb..be9f2b1ac3ab 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1022,7 +1022,7 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu)
 	const struct iphdr *iph = (const struct iphdr *) skb->data;
 	struct flowi4 fl4;
 	struct rtable *rt;
-	struct dst_entry *dst;
+	struct dst_entry *odst = NULL;
 	bool new = false;
 
 	bh_lock_sock(sk);
@@ -1030,16 +1030,17 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu)
 	if (!ip_sk_accept_pmtu(sk))
 		goto out;
 
-	rt = (struct rtable *) __sk_dst_get(sk);
+	odst = sk_dst_get(sk);
 
-	if (sock_owned_by_user(sk) || !rt) {
+	if (sock_owned_by_user(sk) || !odst) {
 		__ipv4_sk_update_pmtu(skb, sk, mtu);
 		goto out;
 	}
 
 	__build_flow_key(&fl4, sk, iph, 0, 0, 0, 0, 0);
 
-	if (!__sk_dst_check(sk, 0)) {
+	rt = (struct rtable *)odst;
+	if (odst->obsolete && odst->ops->check(odst, 0) == NULL) {
 		rt = ip_route_output_flow(sock_net(sk), &fl4, sk);
 		if (IS_ERR(rt))
 			goto out;
@@ -1049,8 +1050,7 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu)
 
 	__ip_rt_update_pmtu((struct rtable *) rt->dst.path, &fl4, mtu);
 
-	dst = dst_check(&rt->dst, 0);
-	if (!dst) {
+	if (!dst_check(&rt->dst, 0)) {
 		if (new)
 			dst_release(&rt->dst);
 
@@ -1062,10 +1062,11 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu)
 	}
 
 	if (new)
-		__sk_dst_set(sk, &rt->dst);
+		sk_dst_set(sk, &rt->dst);
 
 out:
 	bh_unlock_sock(sk);
+	dst_release(odst);
 }
 EXPORT_SYMBOL_GPL(ipv4_sk_update_pmtu);
 

  reply	other threads:[~2014-06-11  1:26 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-06 11:29 Potential race in ip4_datagram_release_cb Alexey Preobrazhensky
2014-06-06 12:56 ` Eric Dumazet
2014-06-06 15:59   ` Alexei Starovoitov
2014-06-06 16:16     ` Eric Dumazet
2014-06-06 17:44       ` Alexei Starovoitov
2014-06-06 17:56         ` Eric Dumazet
2014-06-06 18:13           ` Alexei Starovoitov
2014-06-10 13:43 ` [PATCH] ipv4: fix a race in ip4_datagram_release_cb() Eric Dumazet
2014-06-11  0:32   ` dormando
2014-06-11  0:55     ` Eric Dumazet
2014-06-11  1:12       ` Eric Dumazet
2014-06-11  1:26         ` Eric Dumazet [this message]
2014-06-11  4:16           ` dormando
2014-06-11  5:54             ` Eric Dumazet
2014-06-11  7:20               ` dormando
2014-06-11  7:26                 ` dormando
2014-06-11  7:38                   ` dormando
2014-06-11 12:41                     ` Eric Dumazet
2014-06-11 13:12                       ` Eric Dumazet
2014-06-12  1:55                         ` dormando
2014-06-12  3:43                           ` Eric Dumazet
2014-06-12  4:05                             ` dormando
2014-06-22 19:07                             ` dormando
2014-06-23  8:33                               ` Eric Dumazet
2014-06-23  8:55                                 ` dormando
2014-06-23 16:57                                   ` Dmitry Vyukov
2014-06-24 17:05                                 ` [PATCH net] ipv4: fix dst race in sk_dst_get() Eric Dumazet
2014-06-26  0:42                                   ` David Miller
2014-06-11 13:38             ` [PATCH] ipv4: fix a race in ip4_datagram_release_cb() Kostya Serebryany
2014-06-29  0:25           ` dormando
2014-06-30  6:38             ` Eric Dumazet
2014-06-30  8:15               ` dormando
2014-06-30  8:30                 ` Eric Dumazet
2014-07-08  1:41                   ` dormando
2014-07-08  6:47                     ` Eric Dumazet
2014-07-08  7:01                       ` dormando
2014-07-16 21:03                       ` dormando
2014-07-25  8:11                         ` dormando
2014-06-30  8:26           ` [PATCH] ipv4: irq safe sk_dst_[re]set() and ipv4_sk_update_pmtu() fix Eric Dumazet
2014-07-01  6:43             ` David Miller
2014-06-11 22:39   ` [PATCH] ipv4: fix a race in ip4_datagram_release_cb() David Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1402450009.3645.444.camel@edumazet-glaptop2.roam.corp.google.com \
    --to=eric.dumazet@gmail.com \
    --cc=alexei.starovoitov@gmail.com \
    --cc=brutus@google.com \
    --cc=davem@davemloft.net \
    --cc=dormando@rydia.net \
    --cc=dvyukov@google.com \
    --cc=edumazet@google.com \
    --cc=kcc@google.com \
    --cc=larsbull@google.com \
    --cc=maze@google.com \
    --cc=netdev@vger.kernel.org \
    --cc=paulmck@linux.vnet.ibm.com \
    --cc=preobr@google.com \
    --cc=steffen.klassert@secunet.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.