Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1301764

[PATCH 3.12 73/91] net: fix IP early demux races

From Jiri Slaby <jslaby@suse.cz>
Newsgroups linux.kernel
Subject [PATCH 3.12 73/91] net: fix IP early demux races
Date 2016-01-05 19:00 +0100
Message-ID <qNE3M-69u-13@gated-at.bofh.it> (permalink)
References <qNDU6-65D-3@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


From: Eric Dumazet <edumazet@google.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

[ Upstream commit 5037e9ef9454917b047f9f3a19b4dd179fbf7cd4 ]

David Wilder reported crashes caused by dst reuse.

<quote David>
  I am seeing a crash on a distro V4.2.3 kernel caused by a double
  release of a dst_entry.  In ipv4_dst_destroy() the call to
  list_empty() finds a poisoned next pointer, indicating the dst_entry
  has already been removed from the list and freed. The crash occurs
  18 to 24 hours into a run of a network stress exerciser.
</quote>

Thanks to his detailed report and analysis, we were able to understand
the core issue.

IP early demux can associate a dst to skb, after a lookup in TCP/UDP
sockets.

When socket cache is not properly set, we want to store into
sk->sk_dst_cache the dst for future IP early demux lookups,
by acquiring a stable refcount on the dst.

Problem is this acquisition is simply using an atomic_inc(),
which works well, unless the dst was queued for destruction from
dst_release() noticing dst refcount went to zero, if DST_NOCACHE
was set on dst.

We need to make sure current refcount is not zero before incrementing
it, or risk double free as David reported.

This patch, being a stable candidate, adds two new helpers, and use
them only from IP early demux problematic paths.

It might be possible to merge in net-next skb_dst_force() and
skb_dst_force_safe(), but I prefer having the smallest patch for stable
kernels : Maybe some skb_dst_force() callers do not expect skb->dst
can suddenly be cleared.

Can probably be backported back to linux-3.6 kernels

Reported-by: David J. Wilder <dwilder@us.ibm.com>
Tested-by: David J. Wilder <dwilder@us.ibm.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 include/net/dst.h   | 33 +++++++++++++++++++++++++++++++++
 include/net/sock.h  |  2 +-
 net/ipv4/tcp_ipv4.c |  9 +++++----
 net/ipv6/tcp_ipv6.c | 11 ++++++-----
 4 files changed, 45 insertions(+), 10 deletions(-)

diff --git a/include/net/dst.h b/include/net/dst.h
index 30cd2f9cd1dd..d30afbdc1a59 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -306,6 +306,39 @@ static inline void skb_dst_force(struct sk_buff *skb)
 	}
 }
 
+/**
+ * dst_hold_safe - Take a reference on a dst if possible
+ * @dst: pointer to dst entry
+ *
+ * This helper returns false if it could not safely
+ * take a reference on a dst.
+ */
+static inline bool dst_hold_safe(struct dst_entry *dst)
+{
+	if (dst->flags & DST_NOCACHE)
+		return atomic_inc_not_zero(&dst->__refcnt);
+	dst_hold(dst);
+	return true;
+}
+
+/**
+ * skb_dst_force_safe - makes sure skb dst is refcounted
+ * @skb: buffer
+ *
+ * If dst is not yet refcounted and not destroyed, grab a ref on it.
+ */
+static inline void skb_dst_force_safe(struct sk_buff *skb)
+{
+	if (skb_dst_is_noref(skb)) {
+		struct dst_entry *dst = skb_dst(skb);
+
+		if (!dst_hold_safe(dst))
+			dst = NULL;
+
+		skb->_skb_refdst = (unsigned long)dst;
+	}
+}
+
 
 /**
  *	__skb_tunnel_rx - prepare skb for rx reinsert
diff --git a/include/net/sock.h b/include/net/sock.h
index 41d98f1d0459..6ed6df149bce 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -760,7 +760,7 @@ extern void sk_stream_write_space(struct sock *sk);
 static inline void __sk_add_backlog(struct sock *sk, struct sk_buff *skb)
 {
 	/* dont let skb dst not refcounted, we are going to leave rcu lock */
-	skb_dst_force(skb);
+	skb_dst_force_safe(skb);
 
 	if (!sk->sk_backlog.tail)
 		sk->sk_backlog.head = skb;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 624ceca7ffd1..09451a2cbd6a 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1905,7 +1905,7 @@ bool tcp_prequeue(struct sock *sk, struct sk_buff *skb)
 	    skb_queue_len(&tp->ucopy.prequeue) == 0)
 		return false;
 
-	skb_dst_force(skb);
+	skb_dst_force_safe(skb);
 	__skb_queue_tail(&tp->ucopy.prequeue, skb);
 	tp->ucopy.memory += skb->truesize;
 	if (tp->ucopy.memory > sk->sk_rcvbuf) {
@@ -2098,9 +2098,10 @@ void inet_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb)
 {
 	struct dst_entry *dst = skb_dst(skb);
 
-	dst_hold(dst);
-	sk->sk_rx_dst = dst;
-	inet_sk(sk)->rx_dst_ifindex = skb->skb_iif;
+	if (dst_hold_safe(dst)) {
+		sk->sk_rx_dst = dst;
+		inet_sk(sk)->rx_dst_ifindex = skb->skb_iif;
+	}
 }
 EXPORT_SYMBOL(inet_sk_rx_dst_set);
 
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 65c310d6e92a..90004c6e3bff 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -97,11 +97,12 @@ static void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb)
 	struct dst_entry *dst = skb_dst(skb);
 	const struct rt6_info *rt = (const struct rt6_info *)dst;
 
-	dst_hold(dst);
-	sk->sk_rx_dst = dst;
-	inet_sk(sk)->rx_dst_ifindex = skb->skb_iif;
-	if (rt->rt6i_node)
-		inet6_sk(sk)->rx_dst_cookie = rt->rt6i_node->fn_sernum;
+	if (dst_hold_safe(dst)) {
+		sk->sk_rx_dst = dst;
+		inet_sk(sk)->rx_dst_ifindex = skb->skb_iif;
+		if (rt->rt6i_node)
+			inet6_sk(sk)->rx_dst_cookie = rt->rt6i_node->fn_sernum;
+	}
 }
 
 static void tcp_v6_hash(struct sock *sk)
-- 
2.6.4

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

Back to linux.kernel | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

[PATCH 3.12 00/91] 3.12.52-stable review Jiri Slaby <jslaby@suse.cz> - 2016-01-05 18:50 +0100
  [PATCH 3.12 01/91] ipv6: fix tunnel error handling Jiri Slaby <jslaby@suse.cz> - 2016-01-05 18:50 +0100
    [PATCH 3.12 68/91] sctp: use the same clock as if sock source timestamps were on Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 73/91] net: fix IP early demux races Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 62/91] USB: cp210x: Remove CP2110 ID from compatibility list Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 81/91] ahci: add new Intel device IDs Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 75/91] skbuff: Fix offset error in skb_reorder_vlan_header Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 71/91] net: add validation for the socket syscall protocol argument Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 63/91] USB: add quirk for devices with broken LPM Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 57/91] nfs4: start callback_ident at idr 1 Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 58/91] nfs: if we have no valid attrs, then don't declare the attribute cache valid Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 74/91] vlan: Fix untag operations of stacked vlans with REORDER_HEADER off Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 48/91] netfilter: ipt_rpfilter: remove the nh_scope test in rpfilter_lookup_reverse Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 86/91] i2c: i801: add Intel Lewisburg device IDs Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 61/91] USB: serial: Another Infineon flash loader USB ID Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 51/91] ip6mr: call del_timer_sync() in ip6mr_free_table() Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 60/91] USB: cdc_acm: Ignore Infineon Flash Loader utility Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 77/91] bluetooth: Validate socket address length in sco_sock_bind(). Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 65/91] usb: Use the USB_SS_MULT() macro to decode burst multiplier for log message Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 69/91] sctp: update the netstamp_needed counter when copying sockets Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 72/91] sh_eth: fix kernel oops in skb_put() Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 64/91] USB: whci-hcd: add check for dma mapping error Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 76/91] pptp: verify sockaddr_len in pptp_bind() and pptp_connect() Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 91/91] HID: dragonrise: fix HID Descriptor for 0x0006 PID Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 87/91] cdrom: Random writing support for BD-RE media Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 70/91] ipv6: sctp: clone options to avoid use after free Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 59/91] ocfs2: fix umask ignored issue Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 67/91] atl1c: Improve driver not to do order 4 GFP_ATOMIC allocation Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 85/91] i2c: i801: Add support for Intel Broxton Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 82/91] target/stat: print full t10_wwn.model buffer Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 90/91] gpio/omap: raw read and write endian fix Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:00 +0100
    [PATCH 3.12 36/91] can: sja1000: clear interrupts on start Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 29/91] mac80211: fix driver RSSI event calculations Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 38/91] usblp: do not set TASK_INTERRUPTIBLE before lock Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 47/91] module: Call module notifier on failure after complete_formation() Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 27/91] x86/cpu: Call verify_cpu() after having entered long mode too Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 32/91] staging: rtl8712: Add device ID for Sitecom WLA2100 Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 41/91] USB: serial: option: add support for Novatel MiFi USB620L Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 56/91] firewire: ohci: fix JMicron JMB38x IT context discovery Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 46/91] tty: fix stall caused by missing memory barrier in drivers/tty/n_tty.c Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 37/91] arm64: Fix compat register mappings Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 30/91] net: mvneta: Fix CPU_MAP registers initialisation Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 26/91] x86/setup: Fix low identity map for >= 2GB kernel range Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 53/91] Btrfs: fix race leading to BUG_ON when running delalloc for nodatacow Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 55/91] ext4, jbd2: ensure entering into panic after recording an error in superblock Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 66/91] gre6: allow to update all parameters via rtnl Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 43/91] ALSA: usb-audio: add packet size quirk for the Medeli DD305 Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 54/91] ext4: fix potential use after free in __ext4_journal_stop Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 24/91] ARM: common: edma: Fix channel parameter for irq callbacks Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 14/91] net: ipmr: fix static mfc/dev leaks on table destruction Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 39/91] usb: musb: core: fix order of arguments to ulpi write callback Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 45/91] ALSA: usb-audio: work around CH345 input SysEx corruption Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 40/91] USB: ti_usb_3410_5052: Add Honeywell HGI80 ID Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 31/91] mwifiex: fix mwifiex_rdeeprom_read() Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 52/91] Btrfs: fix race leading to incorrect item deletion when dropping extents Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 33/91] Bluetooth: hidp: fix device disconnect on idle timeout Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 25/91] x86/setup: Extend low identity map to cover whole kernel range Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
      Re: [PATCH 3.12 25/91] x86/setup: Extend low identity map to cover  whole kernel range Paolo Bonzini <pbonzini@redhat.com> - 2016-01-06 11:50 +0100
        Re: [PATCH 3.12 25/91] x86/setup: Extend low identity map to cover  whole kernel range Matt Fleming <matt@codeblueprint.co.uk> - 2016-01-06 12:10 +0100
          Re: [PATCH 3.12 25/91] x86/setup: Extend low identity map to cover  whole kernel range Luis Henriques <luis.henriques@canonical.com> - 2016-01-06 12:30 +0100
            Re: [PATCH 3.12 25/91] x86/setup: Extend low identity map to cover  whole kernel range Matt Fleming <matt@codeblueprint.co.uk> - 2016-01-06 14:40 +0100
              Re: [PATCH 3.12 25/91] x86/setup: Extend low identity map to cover  whole kernel range Luis Henriques <luis.henriques@canonical.com> - 2016-01-06 15:30 +0100
                Re: [PATCH 3.12 25/91] x86/setup: Extend low identity map to cover  whole kernel range Matt Fleming <matt@codeblueprint.co.uk> - 2016-01-08 13:00 +0100
                Re: [PATCH 3.12 25/91] x86/setup: Extend low identity map to cover  whole kernel range Luis Henriques <luis.henriques@canonical.com> - 2016-01-08 14:40 +0100
                Re: [PATCH 3.12 25/91] x86/setup: Extend low identity map to cover  whole kernel range Jiri Slaby <jslaby@suse.cz> - 2016-01-09 08:10 +0100
                Re: [PATCH 3.12 25/91] x86/setup: Extend low identity map to cover  whole kernel range Kamal Mostafa <kamal@canonical.com> - 2016-01-14 22:00 +0100
    [PATCH 3.12 34/91] Bluetooth: ath3k: Add new AR3012 0930:021c id Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 44/91] ALSA: usb-audio: prevent CH345 multiport output SysEx corruption Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 35/91] Bluetooth: ath3k: Add support of AR3012 0cf3:817b device Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 28/91] x86/cpu: Fix SMAP check in PVOPS environments Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 49/91] netfilter: ip6t_SYNPROXY: fix NULL pointer dereference Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 42/91] USB: option: add XS Stick W100-2 from 4G Systems Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:10 +0100
    [PATCH 3.12 10/91] net: qmi_wwan: add XS Stick W100-2 from 4G Systems Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:20 +0100
    [PATCH 3.12 11/91] tcp: md5: fix lockdep annotation Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:20 +0100
    [PATCH 3.12 19/91] net/neighbour: fix crash at dumping device-agnostic proxy entries Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:20 +0100
    [PATCH 3.12 23/91] ARM: 8427/1: dma-mapping: add support for offset parameter in dma_mmap() Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:20 +0100
    [PATCH 3.12 07/91] packet: infer protocol from ethernet header if unset Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:20 +0100
    [PATCH 3.12 21/91] Bluetooth: ath3k: Add support of 04ca:300d AR3012 device Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:20 +0100
    [PATCH 3.12 08/91] sctp: translate host order to network order when setting a hmacid Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:20 +0100
    [PATCH 3.12 22/91] ARM: 8426/1: dma-mapping: add missing range check in dma_mmap() Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:20 +0100
    [PATCH 3.12 05/91] unix: avoid use-after-free in ep_remove_wait_queue Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:20 +0100
    [PATCH 3.12 02/91] MIPS: KVM: Fix ASID restoration logic Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:20 +0100
    [PATCH 3.12 20/91] ipv6: sctp: implement sctp_v6_destroy_sock() Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:20 +0100
    [PATCH 3.12 13/91] net, scm: fix PaX detected msg_controllen overflow in scm_detach_fds Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:20 +0100
    [PATCH 3.12 18/91] ipv6: add complete rcu protection around np->opt Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:20 +0100
    [PATCH 3.12 12/91] tcp: initialize tp->copied_seq in case of cross SYN connection Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:20 +0100
    [PATCH 3.12 04/91] MIPS: KVM: Uninit VCPU in vcpu_create error path Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:20 +0100
    [PATCH 3.12 06/91] packet: do skb_probe_transport_header when we actually have data Jiri Slaby <jslaby@suse.cz> - 2016-01-05 19:20 +0100
  Re: [PATCH 3.12 00/91] 3.12.52-stable review Guenter Roeck <linux@roeck-us.net> - 2016-01-05 21:50 +0100
    Re: [PATCH 3.12 00/91] 3.12.52-stable review Jiri Slaby <jslaby@suse.cz> - 2016-01-09 09:50 +0100
  Re: [PATCH 3.12 00/91] 3.12.52-stable review Shuah Khan <shuahkh@osg.samsung.com> - 2016-01-05 22:20 +0100
  Re: [PATCH 3.12 00/91] 3.12.52-stable review Nikolay Borisov <kernel@kyup.com> - 2016-01-06 08:40 +0100
    Re: [PATCH 3.12 00/91] 3.12.52-stable review Greg KH <gregkh@linuxfoundation.org> - 2016-01-06 09:20 +0100

csiph-web