From 3c3eaa105335cdddc69b39113670022ae92e4e07 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 21 Jan 2020 18:25:45 +0100 Subject: [PATCH] 4.14-stable patches added patches: hv_netvsc-fix-memory-leak-when-removing-rndis-device.patch net-dsa-tag_qca-fix-doubled-tx-statistics.patch net-hns-fix-soft-lockup-when-there-is-not-enough-memory.patch net-usb-lan78xx-limit-size-of-local-tso-packets.patch net-wan-fsl_ucc_hdlc-fix-out-of-bounds-write-on-array-utdm_info.patch ptp-free-ptp-device-pin-descriptors-properly.patch r8152-add-missing-endpoint-sanity-check.patch tcp-fix-marked-lost-packets-not-being-retransmitted.patch --- ...mory-leak-when-removing-rndis-device.patch | 61 ++++++++++++++ ...reset_mac_header-in-macvlan_queue_xm.patch | 11 +-- ...sa-tag_qca-fix-doubled-tx-statistics.patch | 37 +++++++++ ...ckup-when-there-is-not-enough-memory.patch | 57 +++++++++++++ ...78xx-limit-size-of-local-tso-packets.patch | 46 ++++++++++ ...t-of-bounds-write-on-array-utdm_info.patch | 35 ++++++++ ...-ptp-device-pin-descriptors-properly.patch | 51 ++++++++++++ ...52-add-missing-endpoint-sanity-check.patch | 35 ++++++++ queue-4.14/series | 8 ++ ...lost-packets-not-being-retransmitted.patch | 83 +++++++++++++++++++ 10 files changed, 416 insertions(+), 8 deletions(-) create mode 100644 queue-4.14/hv_netvsc-fix-memory-leak-when-removing-rndis-device.patch create mode 100644 queue-4.14/net-dsa-tag_qca-fix-doubled-tx-statistics.patch create mode 100644 queue-4.14/net-hns-fix-soft-lockup-when-there-is-not-enough-memory.patch create mode 100644 queue-4.14/net-usb-lan78xx-limit-size-of-local-tso-packets.patch create mode 100644 queue-4.14/net-wan-fsl_ucc_hdlc-fix-out-of-bounds-write-on-array-utdm_info.patch create mode 100644 queue-4.14/ptp-free-ptp-device-pin-descriptors-properly.patch create mode 100644 queue-4.14/r8152-add-missing-endpoint-sanity-check.patch create mode 100644 queue-4.14/tcp-fix-marked-lost-packets-not-being-retransmitted.patch diff --git a/queue-4.14/hv_netvsc-fix-memory-leak-when-removing-rndis-device.patch b/queue-4.14/hv_netvsc-fix-memory-leak-when-removing-rndis-device.patch new file mode 100644 index 00000000000..582ffbff44c --- /dev/null +++ b/queue-4.14/hv_netvsc-fix-memory-leak-when-removing-rndis-device.patch @@ -0,0 +1,61 @@ +From foo@baz Tue 21 Jan 2020 05:54:02 PM CET +From: Mohammed Gamal +Date: Tue, 14 Jan 2020 15:09:50 +0200 +Subject: hv_netvsc: Fix memory leak when removing rndis device + +From: Mohammed Gamal + +[ Upstream commit 536dc5df2808efbefc5acee334d3c4f701790ec0 ] + +kmemleak detects the following memory leak when hot removing +a network device: + +unreferenced object 0xffff888083f63600 (size 256): + comm "kworker/0:1", pid 12, jiffies 4294831717 (age 1113.676s) + hex dump (first 32 bytes): + 00 40 c7 33 80 88 ff ff 00 00 00 00 10 00 00 00 .@.3............ + 00 00 00 00 ad 4e ad de ff ff ff ff 00 00 00 00 .....N.......... + backtrace: + [<00000000d4a8f5be>] rndis_filter_device_add+0x117/0x11c0 [hv_netvsc] + [<000000009c02d75b>] netvsc_probe+0x5e7/0xbf0 [hv_netvsc] + [<00000000ddafce23>] vmbus_probe+0x74/0x170 [hv_vmbus] + [<00000000046e64f1>] really_probe+0x22f/0xb50 + [<000000005cc35eb7>] driver_probe_device+0x25e/0x370 + [<0000000043c642b2>] bus_for_each_drv+0x11f/0x1b0 + [<000000005e3d09f0>] __device_attach+0x1c6/0x2f0 + [<00000000a72c362f>] bus_probe_device+0x1a6/0x260 + [<0000000008478399>] device_add+0x10a3/0x18e0 + [<00000000cf07b48c>] vmbus_device_register+0xe7/0x1e0 [hv_vmbus] + [<00000000d46cf032>] vmbus_add_channel_work+0x8ab/0x1770 [hv_vmbus] + [<000000002c94bb64>] process_one_work+0x919/0x17d0 + [<0000000096de6781>] worker_thread+0x87/0xb40 + [<00000000fbe7397e>] kthread+0x333/0x3f0 + [<000000004f844269>] ret_from_fork+0x3a/0x50 + +rndis_filter_device_add() allocates an instance of struct rndis_device +which never gets deallocated as rndis_filter_device_remove() sets +net_device->extension which points to the rndis_device struct to NULL, +leaving the rndis_device dangling. + +Since net_device->extension is eventually freed in free_netvsc_device(), +we refrain from setting it to NULL inside rndis_filter_device_remove() + +Signed-off-by: Mohammed Gamal +Reviewed-by: Haiyang Zhang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/hyperv/rndis_filter.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/net/hyperv/rndis_filter.c ++++ b/drivers/net/hyperv/rndis_filter.c +@@ -1331,8 +1331,6 @@ void rndis_filter_device_remove(struct h + /* Halt and release the rndis device */ + rndis_filter_halt_device(rndis_dev); + +- net_dev->extension = NULL; +- + netvsc_device_remove(dev); + } + diff --git a/queue-4.14/macvlan-use-skb_reset_mac_header-in-macvlan_queue_xm.patch b/queue-4.14/macvlan-use-skb_reset_mac_header-in-macvlan_queue_xm.patch index 0622cbff253..614c819614b 100644 --- a/queue-4.14/macvlan-use-skb_reset_mac_header-in-macvlan_queue_xm.patch +++ b/queue-4.14/macvlan-use-skb_reset_mac_header-in-macvlan_queue_xm.patch @@ -20,14 +20,12 @@ Tested-by: Matteo Croce Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- - drivers/net/macvlan.c | 5 +++-- + drivers/net/macvlan.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) -diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c -index 2b977655834c..ab539136d5bf 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c -@@ -263,7 +263,7 @@ static void macvlan_broadcast(struct sk_buff *skb, +@@ -263,7 +263,7 @@ static void macvlan_broadcast(struct sk_ struct net_device *src, enum macvlan_mode mode) { @@ -36,7 +34,7 @@ index 2b977655834c..ab539136d5bf 100644 const struct macvlan_dev *vlan; struct sk_buff *nskb; unsigned int i; -@@ -515,10 +515,11 @@ static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev) +@@ -515,10 +515,11 @@ static int macvlan_queue_xmit(struct sk_ const struct macvlan_dev *dest; if (vlan->mode == MACVLAN_MODE_BRIDGE) { @@ -49,6 +47,3 @@ index 2b977655834c..ab539136d5bf 100644 macvlan_broadcast(skb, port, dev, MACVLAN_MODE_BRIDGE); goto xmit_world; } --- -2.20.1 - diff --git a/queue-4.14/net-dsa-tag_qca-fix-doubled-tx-statistics.patch b/queue-4.14/net-dsa-tag_qca-fix-doubled-tx-statistics.patch new file mode 100644 index 00000000000..e6e5edda1a4 --- /dev/null +++ b/queue-4.14/net-dsa-tag_qca-fix-doubled-tx-statistics.patch @@ -0,0 +1,37 @@ +From foo@baz Tue 21 Jan 2020 05:54:02 PM CET +From: Alexander Lobakin +Date: Wed, 15 Jan 2020 11:56:52 +0300 +Subject: net: dsa: tag_qca: fix doubled Tx statistics + +From: Alexander Lobakin + +[ Upstream commit bd5874da57edd001b35cf28ae737779498c16a56 ] + +DSA subsystem takes care of netdev statistics since commit 4ed70ce9f01c +("net: dsa: Refactor transmit path to eliminate duplication"), so +any accounting inside tagger callbacks is redundant and can lead to +messing up the stats. +This bug is present in Qualcomm tagger since day 0. + +Fixes: cafdc45c949b ("net-next: dsa: add Qualcomm tag RX/TX handler") +Reviewed-by: Andrew Lunn +Signed-off-by: Alexander Lobakin +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/dsa/tag_qca.c | 3 --- + 1 file changed, 3 deletions(-) + +--- a/net/dsa/tag_qca.c ++++ b/net/dsa/tag_qca.c +@@ -41,9 +41,6 @@ static struct sk_buff *qca_tag_xmit(stru + struct dsa_slave_priv *p = netdev_priv(dev); + u16 *phdr, hdr; + +- dev->stats.tx_packets++; +- dev->stats.tx_bytes += skb->len; +- + if (skb_cow_head(skb, 0) < 0) + return NULL; + diff --git a/queue-4.14/net-hns-fix-soft-lockup-when-there-is-not-enough-memory.patch b/queue-4.14/net-hns-fix-soft-lockup-when-there-is-not-enough-memory.patch new file mode 100644 index 00000000000..e6e0dad20f8 --- /dev/null +++ b/queue-4.14/net-hns-fix-soft-lockup-when-there-is-not-enough-memory.patch @@ -0,0 +1,57 @@ +From foo@baz Tue 21 Jan 2020 05:54:02 PM CET +From: Yonglong Liu +Date: Thu, 16 Jan 2020 15:41:17 +0800 +Subject: net: hns: fix soft lockup when there is not enough memory + +From: Yonglong Liu + +[ Upstream commit 49edd6a2c456150870ddcef5b7ed11b21d849e13 ] + +When there is not enough memory and napi_alloc_skb() return NULL, +the HNS driver will print error message, and than try again, if +the memory is not enough for a while, huge error message and the +retry operation will cause soft lockup. + +When napi_alloc_skb() return NULL because of no memory, we can +get a warn_alloc() call trace, so this patch deletes the error +message. We already use polling mode to handle irq, but the +retry operation will render the polling weight inactive, this +patch just return budget when the rx is not completed to avoid +dead loop. + +Fixes: 36eedfde1a36 ("net: hns: Optimize hns_nic_common_poll for better performance") +Fixes: b5996f11ea54 ("net: add Hisilicon Network Subsystem basic ethernet support") +Signed-off-by: Yonglong Liu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/hisilicon/hns/hns_enet.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c ++++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c +@@ -669,7 +669,6 @@ static int hns_nic_poll_rx_skb(struct hn + skb = *out_skb = napi_alloc_skb(&ring_data->napi, + HNS_RX_HEAD_SIZE); + if (unlikely(!skb)) { +- netdev_err(ndev, "alloc rx skb fail\n"); + ring->stats.sw_err_cnt++; + return -ENOMEM; + } +@@ -1180,7 +1179,6 @@ static int hns_nic_common_poll(struct na + container_of(napi, struct hns_nic_ring_data, napi); + struct hnae_ring *ring = ring_data->ring; + +-try_again: + clean_complete += ring_data->poll_one( + ring_data, budget - clean_complete, + ring_data->ex_process); +@@ -1190,7 +1188,7 @@ try_again: + napi_complete(napi); + ring->q->handle->dev->ops->toggle_ring_irq(ring, 0); + } else { +- goto try_again; ++ return budget; + } + } + diff --git a/queue-4.14/net-usb-lan78xx-limit-size-of-local-tso-packets.patch b/queue-4.14/net-usb-lan78xx-limit-size-of-local-tso-packets.patch new file mode 100644 index 00000000000..a8daf02b421 --- /dev/null +++ b/queue-4.14/net-usb-lan78xx-limit-size-of-local-tso-packets.patch @@ -0,0 +1,46 @@ +From foo@baz Tue 21 Jan 2020 05:54:02 PM CET +From: Eric Dumazet +Date: Mon, 13 Jan 2020 09:27:11 -0800 +Subject: net: usb: lan78xx: limit size of local TSO packets + +From: Eric Dumazet + +[ Upstream commit f8d7408a4d7f60f8b2df0f81decdc882dd9c20dc ] + +lan78xx_tx_bh() makes sure to not exceed MAX_SINGLE_PACKET_SIZE +bytes in the aggregated packets it builds, but does +nothing to prevent large GSO packets being submitted. + +Pierre-Francois reported various hangs when/if TSO is enabled. + +For localy generated packets, we can use netif_set_gso_max_size() +to limit the size of TSO packets. + +Note that forwarded packets could still hit the issue, +so a complete fix might require implementing .ndo_features_check +for this driver, forcing a software segmentation if the size +of the TSO packet exceeds MAX_SINGLE_PACKET_SIZE. + +Fixes: 55d7de9de6c3 ("Microchip's LAN7800 family USB 2/3 to 10/100/1000 Ethernet device driver") +Signed-off-by: Eric Dumazet +Reported-by: RENARD Pierre-Francois +Tested-by: RENARD Pierre-Francois +Cc: Stefan Wahren +Cc: Woojung Huh +Cc: Microchip Linux Driver Support +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/lan78xx.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -3612,6 +3612,7 @@ static int lan78xx_probe(struct usb_inte + + /* MTU range: 68 - 9000 */ + netdev->max_mtu = MAX_SINGLE_PACKET_SIZE; ++ netif_set_gso_max_size(netdev, MAX_SINGLE_PACKET_SIZE - MAX_HEADER); + + dev->ep_blkin = (intf->cur_altsetting)->endpoint + 0; + dev->ep_blkout = (intf->cur_altsetting)->endpoint + 1; diff --git a/queue-4.14/net-wan-fsl_ucc_hdlc-fix-out-of-bounds-write-on-array-utdm_info.patch b/queue-4.14/net-wan-fsl_ucc_hdlc-fix-out-of-bounds-write-on-array-utdm_info.patch new file mode 100644 index 00000000000..d4751343b22 --- /dev/null +++ b/queue-4.14/net-wan-fsl_ucc_hdlc-fix-out-of-bounds-write-on-array-utdm_info.patch @@ -0,0 +1,35 @@ +From foo@baz Tue 21 Jan 2020 05:54:02 PM CET +From: Colin Ian King +Date: Tue, 14 Jan 2020 14:54:48 +0000 +Subject: net/wan/fsl_ucc_hdlc: fix out of bounds write on array utdm_info + +From: Colin Ian King + +[ Upstream commit ddf420390526ede3b9ff559ac89f58cb59d9db2f ] + +Array utdm_info is declared as an array of MAX_HDLC_NUM (4) elements +however up to UCC_MAX_NUM (8) elements are potentially being written +to it. Currently we have an array out-of-bounds write error on the +last 4 elements. Fix this by making utdm_info UCC_MAX_NUM elements in +size. + +Addresses-Coverity: ("Out-of-bounds write") +Fixes: c19b6d246a35 ("drivers/net: support hdlc function for QE-UCC") +Signed-off-by: Colin Ian King +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wan/fsl_ucc_hdlc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wan/fsl_ucc_hdlc.c ++++ b/drivers/net/wan/fsl_ucc_hdlc.c +@@ -76,7 +76,7 @@ static struct ucc_tdm_info utdm_primary_ + }, + }; + +-static struct ucc_tdm_info utdm_info[MAX_HDLC_NUM]; ++static struct ucc_tdm_info utdm_info[UCC_MAX_NUM]; + + static int uhdlc_init(struct ucc_hdlc_private *priv) + { diff --git a/queue-4.14/ptp-free-ptp-device-pin-descriptors-properly.patch b/queue-4.14/ptp-free-ptp-device-pin-descriptors-properly.patch new file mode 100644 index 00000000000..b7e828ff10d --- /dev/null +++ b/queue-4.14/ptp-free-ptp-device-pin-descriptors-properly.patch @@ -0,0 +1,51 @@ +From foo@baz Tue 21 Jan 2020 05:54:02 PM CET +From: Vladis Dronov +Date: Mon, 13 Jan 2020 14:00:09 +0100 +Subject: ptp: free ptp device pin descriptors properly + +From: Vladis Dronov + +[ Upstream commit 75718584cb3c64e6269109d4d54f888ac5a5fd15 ] + +There is a bug in ptp_clock_unregister(), where ptp_cleanup_pin_groups() +first frees ptp->pin_{,dev_}attr, but then posix_clock_unregister() needs +them to destroy a related sysfs device. + +These functions can not be just swapped, as posix_clock_unregister() frees +ptp which is needed in the ptp_cleanup_pin_groups(). Fix this by calling +ptp_cleanup_pin_groups() in ptp_clock_release(), right before ptp is freed. + +This makes this patch fix an UAF bug in a patch which fixes an UAF bug. + +Reported-by: Antti Laakso +Fixes: a33121e5487b ("ptp: fix the race between the release of ptp_clock and cdev") +Link: https://lore.kernel.org/netdev/3d2bd09735dbdaf003585ca376b7c1e5b69a19bd.camel@intel.com/ +Signed-off-by: Vladis Dronov +Acked-by: Richard Cochran +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ptp/ptp_clock.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/ptp/ptp_clock.c ++++ b/drivers/ptp/ptp_clock.c +@@ -179,6 +179,7 @@ static void ptp_clock_release(struct dev + { + struct ptp_clock *ptp = container_of(dev, struct ptp_clock, dev); + ++ ptp_cleanup_pin_groups(ptp); + mutex_destroy(&ptp->tsevq_mux); + mutex_destroy(&ptp->pincfg_mux); + ida_simple_remove(&ptp_clocks_map, ptp->index); +@@ -315,9 +316,8 @@ int ptp_clock_unregister(struct ptp_cloc + if (ptp->pps_source) + pps_unregister_source(ptp->pps_source); + +- ptp_cleanup_pin_groups(ptp); +- + posix_clock_unregister(&ptp->clock); ++ + return 0; + } + EXPORT_SYMBOL(ptp_clock_unregister); diff --git a/queue-4.14/r8152-add-missing-endpoint-sanity-check.patch b/queue-4.14/r8152-add-missing-endpoint-sanity-check.patch new file mode 100644 index 00000000000..db607e923b0 --- /dev/null +++ b/queue-4.14/r8152-add-missing-endpoint-sanity-check.patch @@ -0,0 +1,35 @@ +From foo@baz Tue 21 Jan 2020 05:54:02 PM CET +From: Johan Hovold +Date: Tue, 14 Jan 2020 09:27:29 +0100 +Subject: r8152: add missing endpoint sanity check + +From: Johan Hovold + +[ Upstream commit 86f3f4cd53707ceeec079b83205c8d3c756eca93 ] + +Add missing endpoint sanity check to probe in order to prevent a +NULL-pointer dereference (or slab out-of-bounds access) when retrieving +the interrupt-endpoint bInterval on ndo_open() in case a device lacks +the expected endpoints. + +Fixes: 40a82917b1d3 ("net/usb/r8152: enable interrupt transfer") +Cc: hayeswang +Signed-off-by: Johan Hovold +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/r8152.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -5158,6 +5158,9 @@ static int rtl8152_probe(struct usb_inte + return -ENODEV; + } + ++ if (intf->cur_altsetting->desc.bNumEndpoints < 3) ++ return -ENODEV; ++ + usb_reset_device(udev); + netdev = alloc_etherdev(sizeof(struct r8152)); + if (!netdev) { diff --git a/queue-4.14/series b/queue-4.14/series index 031d8bc6817..5539f1639b0 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -39,3 +39,11 @@ netfilter-arp_tables-init-netns-pointer-in-xt_tgdtor_param-struct.patch nfc-pn533-fix-bulk-message-timeout.patch batman-adv-fix-dat-candidate-selection-on-little-endian-systems.patch macvlan-use-skb_reset_mac_header-in-macvlan_queue_xm.patch +hv_netvsc-fix-memory-leak-when-removing-rndis-device.patch +net-dsa-tag_qca-fix-doubled-tx-statistics.patch +net-hns-fix-soft-lockup-when-there-is-not-enough-memory.patch +net-usb-lan78xx-limit-size-of-local-tso-packets.patch +net-wan-fsl_ucc_hdlc-fix-out-of-bounds-write-on-array-utdm_info.patch +ptp-free-ptp-device-pin-descriptors-properly.patch +r8152-add-missing-endpoint-sanity-check.patch +tcp-fix-marked-lost-packets-not-being-retransmitted.patch diff --git a/queue-4.14/tcp-fix-marked-lost-packets-not-being-retransmitted.patch b/queue-4.14/tcp-fix-marked-lost-packets-not-being-retransmitted.patch new file mode 100644 index 00000000000..6cc2db3c4d2 --- /dev/null +++ b/queue-4.14/tcp-fix-marked-lost-packets-not-being-retransmitted.patch @@ -0,0 +1,83 @@ +From foo@baz Tue 21 Jan 2020 05:54:02 PM CET +From: Pengcheng Yang +Date: Tue, 14 Jan 2020 17:23:40 +0800 +Subject: tcp: fix marked lost packets not being retransmitted + +From: Pengcheng Yang + +[ Upstream commit e176b1ba476cf36f723cfcc7a9e57f3cb47dec70 ] + +When the packet pointed to by retransmit_skb_hint is unlinked by ACK, +retransmit_skb_hint will be set to NULL in tcp_clean_rtx_queue(). +If packet loss is detected at this time, retransmit_skb_hint will be set +to point to the current packet loss in tcp_verify_retransmit_hint(), +then the packets that were previously marked lost but not retransmitted +due to the restriction of cwnd will be skipped and cannot be +retransmitted. + +To fix this, when retransmit_skb_hint is NULL, retransmit_skb_hint can +be reset only after all marked lost packets are retransmitted +(retrans_out >= lost_out), otherwise we need to traverse from +tcp_rtx_queue_head in tcp_xmit_retransmit_queue(). + +Packetdrill to demonstrate: + +// Disable RACK and set max_reordering to keep things simple + 0 `sysctl -q net.ipv4.tcp_recovery=0` + +0 `sysctl -q net.ipv4.tcp_max_reordering=3` + +// Establish a connection + +0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 + +0 bind(3, ..., ...) = 0 + +0 listen(3, 1) = 0 + + +.1 < S 0:0(0) win 32792 + +0 > S. 0:0(0) ack 1 <...> + +.01 < . 1:1(0) ack 1 win 257 + +0 accept(3, ..., ...) = 4 + +// Send 8 data segments + +0 write(4, ..., 8000) = 8000 + +0 > P. 1:8001(8000) ack 1 + +// Enter recovery and 1:3001 is marked lost + +.01 < . 1:1(0) ack 1 win 257 + +0 < . 1:1(0) ack 1 win 257 + +0 < . 1:1(0) ack 1 win 257 + +// Retransmit 1:1001, now retransmit_skb_hint points to 1001:2001 + +0 > . 1:1001(1000) ack 1 + +// 1001:2001 was ACKed causing retransmit_skb_hint to be set to NULL + +.01 < . 1:1(0) ack 2001 win 257 +// Now retransmit_skb_hint points to 4001:5001 which is now marked lost + +// BUG: 2001:3001 was not retransmitted + +0 > . 2001:3001(1000) ack 1 + +Signed-off-by: Pengcheng Yang +Acked-by: Neal Cardwell +Tested-by: Neal Cardwell +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_input.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -932,9 +932,10 @@ static void tcp_update_reordering(struct + /* This must be called before lost_out is incremented */ + static void tcp_verify_retransmit_hint(struct tcp_sock *tp, struct sk_buff *skb) + { +- if (!tp->retransmit_skb_hint || +- before(TCP_SKB_CB(skb)->seq, +- TCP_SKB_CB(tp->retransmit_skb_hint)->seq)) ++ if ((!tp->retransmit_skb_hint && tp->retrans_out >= tp->lost_out) || ++ (tp->retransmit_skb_hint && ++ before(TCP_SKB_CB(skb)->seq, ++ TCP_SKB_CB(tp->retransmit_skb_hint)->seq))) + tp->retransmit_skb_hint = skb; + } + -- 2.47.3