From: Sasha Levin Date: Thu, 21 Feb 2019 05:43:04 +0000 (-0500) Subject: patches for 4.19 X-Git-Tag: v3.18.136~28 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4e45db15a77c10c7dd0730b96d9bc70eab7ad50c;p=thirdparty%2Fkernel%2Fstable-queue.git patches for 4.19 Signed-off-by: Sasha Levin --- diff --git a/queue-4.19/af_packet-fix-raw-sockets-over-6in4-tunnel.patch b/queue-4.19/af_packet-fix-raw-sockets-over-6in4-tunnel.patch new file mode 100644 index 00000000000..e50942a6bc5 --- /dev/null +++ b/queue-4.19/af_packet-fix-raw-sockets-over-6in4-tunnel.patch @@ -0,0 +1,65 @@ +From 13d3b88b0b4694924fbf4d64fabd248a64f3db00 Mon Sep 17 00:00:00 2001 +From: Nicolas Dichtel +Date: Thu, 17 Jan 2019 11:27:22 +0100 +Subject: af_packet: fix raw sockets over 6in4 tunnel + +[ Upstream commit 88a8121dc1d3d0dbddd411b79ed236b6b6ea415c ] + +Since commit cb9f1b783850, scapy (which uses an AF_PACKET socket in +SOCK_RAW mode) is unable to send a basic icmp packet over a sit tunnel: + +Here is a example of the setup: +$ ip link set ntfp2 up +$ ip addr add 10.125.0.1/24 dev ntfp2 +$ ip tunnel add tun1 mode sit ttl 64 local 10.125.0.1 remote 10.125.0.2 dev ntfp2 +$ ip addr add fd00:cafe:cafe::1/128 dev tun1 +$ ip link set dev tun1 up +$ ip route add fd00:200::/64 dev tun1 +$ scapy +>>> p = [] +>>> p += IPv6(src='fd00:100::1', dst='fd00:200::1')/ICMPv6EchoRequest() +>>> send(p, count=1, inter=0.1) +>>> quit() +$ ip -s link ls dev tun1 | grep -A1 "TX.*errors" + TX: bytes packets errors dropped carrier collsns + 0 0 1 0 0 0 + +The problem is that the network offset is set to the hard_header_len of the +output device (tun1, ie 14 + 20) and in our case, because the packet is +small (48 bytes) the pskb_inet_may_pull() fails (it tries to pull 40 bytes +(ipv6 header) starting from the network offset). + +This problem is more generally related to device with variable hard header +length. To avoid a too intrusive patch in the current release, a (ugly) +workaround is proposed in this patch. It has to be cleaned up in net-next. + +Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=993675a3100b1 +Link: http://patchwork.ozlabs.org/patch/1024489/ +Fixes: cb9f1b783850 ("ip: validate header length on virtual device xmit") +CC: Willem de Bruijn +CC: Maxim Mikityanskiy +Signed-off-by: Nicolas Dichtel +Acked-by: Willem de Bruijn +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/packet/af_packet.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index b6ea0fadb34fa..c76c21604ffd9 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -2887,7 +2887,8 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) + goto out_free; + } else if (reserve) { + skb_reserve(skb, -reserve); +- if (len < reserve) ++ if (len < reserve + sizeof(struct ipv6hdr) && ++ dev->min_header_len != dev->hard_header_len) + skb_reset_network_header(skb); + } + +-- +2.19.1 + diff --git a/queue-4.19/dsa-mv88e6xxx-ensure-all-pending-interrupts-are-hand.patch b/queue-4.19/dsa-mv88e6xxx-ensure-all-pending-interrupts-are-hand.patch new file mode 100644 index 00000000000..43c5623482b --- /dev/null +++ b/queue-4.19/dsa-mv88e6xxx-ensure-all-pending-interrupts-are-hand.patch @@ -0,0 +1,92 @@ +From e26d3526c3a8435d040aa787623c7ee51029fcbc Mon Sep 17 00:00:00 2001 +From: John David Anglin +Date: Mon, 11 Feb 2019 13:40:21 -0500 +Subject: dsa: mv88e6xxx: Ensure all pending interrupts are handled prior to + exit + +[ Upstream commit 7c0db24cc431e2196d98a5d5ddaa9088e2fcbfe5 ] + +The GPIO interrupt controller on the espressobin board only supports edge interrupts. +If one enables the use of hardware interrupts in the device tree for the 88E6341, it is +possible to miss an edge. When this happens, the INTn pin on the Marvell switch is +stuck low and no further interrupts occur. + +I found after adding debug statements to mv88e6xxx_g1_irq_thread_work() that there is +a race in handling device interrupts (e.g. PHY link interrupts). Some interrupts are +directly cleared by reading the Global 1 status register. However, the device interrupt +flag, for example, is not cleared until all the unmasked SERDES and PHY ports are serviced. +This is done by reading the relevant SERDES and PHY status register. + +The code only services interrupts whose status bit is set at the time of reading its status +register. If an interrupt event occurs after its status is read and before all interrupts +are serviced, then this event will not be serviced and the INTn output pin will remain low. + +This is not a problem with polling or level interrupts since the handler will be called +again to process the event. However, it's a big problem when using level interrupts. + +The fix presented here is to add a loop around the code servicing switch interrupts. If +any pending interrupts remain after the current set has been handled, we loop and process +the new set. If there are no pending interrupts after servicing, we are sure that INTn has +gone high and we will get an edge when a new event occurs. + +Tested on espressobin board. + +Fixes: dc30c35be720 ("net: dsa: mv88e6xxx: Implement interrupt support.") +Signed-off-by: John David Anglin +Tested-by: Andrew Lunn +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/mv88e6xxx/chip.c | 28 ++++++++++++++++++++++------ + 1 file changed, 22 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c +index 258918d8a4165..9f697a5b8e3df 100644 +--- a/drivers/net/dsa/mv88e6xxx/chip.c ++++ b/drivers/net/dsa/mv88e6xxx/chip.c +@@ -261,6 +261,7 @@ static irqreturn_t mv88e6xxx_g1_irq_thread_work(struct mv88e6xxx_chip *chip) + unsigned int sub_irq; + unsigned int n; + u16 reg; ++ u16 ctl1; + int err; + + mutex_lock(&chip->reg_lock); +@@ -270,13 +271,28 @@ static irqreturn_t mv88e6xxx_g1_irq_thread_work(struct mv88e6xxx_chip *chip) + if (err) + goto out; + +- for (n = 0; n < chip->g1_irq.nirqs; ++n) { +- if (reg & (1 << n)) { +- sub_irq = irq_find_mapping(chip->g1_irq.domain, n); +- handle_nested_irq(sub_irq); +- ++nhandled; ++ do { ++ for (n = 0; n < chip->g1_irq.nirqs; ++n) { ++ if (reg & (1 << n)) { ++ sub_irq = irq_find_mapping(chip->g1_irq.domain, ++ n); ++ handle_nested_irq(sub_irq); ++ ++nhandled; ++ } + } +- } ++ ++ mutex_lock(&chip->reg_lock); ++ err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &ctl1); ++ if (err) ++ goto unlock; ++ err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, ®); ++unlock: ++ mutex_unlock(&chip->reg_lock); ++ if (err) ++ goto out; ++ ctl1 &= GENMASK(chip->g1_irq.nirqs, 0); ++ } while (reg & ctl1); ++ + out: + return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE); + } +-- +2.19.1 + diff --git a/queue-4.19/mlxsw-__mlxsw_sp_port_headroom_set-fix-a-use-of-loca.patch b/queue-4.19/mlxsw-__mlxsw_sp_port_headroom_set-fix-a-use-of-loca.patch new file mode 100644 index 00000000000..508210beeb1 --- /dev/null +++ b/queue-4.19/mlxsw-__mlxsw_sp_port_headroom_set-fix-a-use-of-loca.patch @@ -0,0 +1,60 @@ +From f684dd0ac10c395c4ef8ca0ccab982a57f48ce73 Mon Sep 17 00:00:00 2001 +From: Petr Machata +Date: Sun, 17 Feb 2019 07:18:41 +0000 +Subject: mlxsw: __mlxsw_sp_port_headroom_set(): Fix a use of local variable + +[ Upstream commit 289460404f6947ef1c38e67d680be9a84161250b ] + +The function-local variable "delay" enters the loop interpreted as delay +in bits. However, inside the loop it gets overwritten by the result of +mlxsw_sp_pg_buf_delay_get(), and thus leaves the loop as quantity in +cells. Thus on second and further loop iterations, the headroom for a +given priority is configured with a wrong size. + +Fix by introducing a loop-local variable, delay_cells. Rename thres to +thres_cells for consistency. + +Fixes: f417f04da589 ("mlxsw: spectrum: Refactor port buffer configuration") +Signed-off-by: Petr Machata +Acked-by: Jiri Pirko +Signed-off-by: Ido Schimmel +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +index d64cd8d44d837..a12b5710891ec 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +@@ -841,8 +841,9 @@ int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port, int mtu, + for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { + bool configure = false; + bool pfc = false; ++ u16 thres_cells; ++ u16 delay_cells; + bool lossy; +- u16 thres; + + for (j = 0; j < IEEE_8021QAZ_MAX_TCS; j++) { + if (prio_tc[j] == i) { +@@ -856,10 +857,11 @@ int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port, int mtu, + continue; + + lossy = !(pfc || pause_en); +- thres = mlxsw_sp_pg_buf_threshold_get(mlxsw_sp, mtu); +- delay = mlxsw_sp_pg_buf_delay_get(mlxsw_sp, mtu, delay, pfc, +- pause_en); +- mlxsw_sp_pg_buf_pack(pbmc_pl, i, thres + delay, thres, lossy); ++ thres_cells = mlxsw_sp_pg_buf_threshold_get(mlxsw_sp, mtu); ++ delay_cells = mlxsw_sp_pg_buf_delay_get(mlxsw_sp, mtu, delay, ++ pfc, pause_en); ++ mlxsw_sp_pg_buf_pack(pbmc_pl, i, thres_cells + delay_cells, ++ thres_cells, lossy); + } + + return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pbmc), pbmc_pl); +-- +2.19.1 + diff --git a/queue-4.19/net-add-header-for-usage-of-fls64.patch b/queue-4.19/net-add-header-for-usage-of-fls64.patch new file mode 100644 index 00000000000..1a1905ce85b --- /dev/null +++ b/queue-4.19/net-add-header-for-usage-of-fls64.patch @@ -0,0 +1,30 @@ +From 34049611c8f9c8c73adf503ec134576966f40c02 Mon Sep 17 00:00:00 2001 +From: "David S. Miller" +Date: Sat, 16 Feb 2019 13:44:39 -0800 +Subject: net: Add header for usage of fls64() + +[ Upstream commit 8681ef1f3d295bd3600315325f3b3396d76d02f6 ] + +Fixes: 3b89ea9c5902 ("net: Fix for_each_netdev_feature on Big endian") +Suggested-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + include/linux/netdev_features.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h +index fce28562bed29..4c76fe2c84880 100644 +--- a/include/linux/netdev_features.h ++++ b/include/linux/netdev_features.h +@@ -11,6 +11,7 @@ + #define _LINUX_NETDEV_FEATURES_H + + #include ++#include + #include + + typedef u64 netdev_features_t; +-- +2.19.1 + diff --git a/queue-4.19/net-crypto-set-sk-to-null-when-af_alg_release.patch b/queue-4.19/net-crypto-set-sk-to-null-when-af_alg_release.patch new file mode 100644 index 00000000000..c4720529eb1 --- /dev/null +++ b/queue-4.19/net-crypto-set-sk-to-null-when-af_alg_release.patch @@ -0,0 +1,124 @@ +From 1fe3706b3c90f2039d23ed7772df8d44f794831c Mon Sep 17 00:00:00 2001 +From: Mao Wenan +Date: Mon, 18 Feb 2019 10:44:44 +0800 +Subject: net: crypto set sk to NULL when af_alg_release. + +[ Upstream commit 9060cb719e61b685ec0102574e10337fa5f445ea ] + +KASAN has found use-after-free in sockfs_setattr. +The existed commit 6d8c50dcb029 ("socket: close race condition between sock_close() +and sockfs_setattr()") is to fix this simillar issue, but it seems to ignore +that crypto module forgets to set the sk to NULL after af_alg_release. + +KASAN report details as below: +BUG: KASAN: use-after-free in sockfs_setattr+0x120/0x150 +Write of size 4 at addr ffff88837b956128 by task syz-executor0/4186 + +CPU: 2 PID: 4186 Comm: syz-executor0 Not tainted xxx + #1 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS +1.10.2-1ubuntu1 04/01/2014 +Call Trace: + dump_stack+0xca/0x13e + print_address_description+0x79/0x330 + ? vprintk_func+0x5e/0xf0 + kasan_report+0x18a/0x2e0 + ? sockfs_setattr+0x120/0x150 + sockfs_setattr+0x120/0x150 + ? sock_register+0x2d0/0x2d0 + notify_change+0x90c/0xd40 + ? chown_common+0x2ef/0x510 + chown_common+0x2ef/0x510 + ? chmod_common+0x3b0/0x3b0 + ? __lock_is_held+0xbc/0x160 + ? __sb_start_write+0x13d/0x2b0 + ? __mnt_want_write+0x19a/0x250 + do_fchownat+0x15c/0x190 + ? __ia32_sys_chmod+0x80/0x80 + ? trace_hardirqs_on_thunk+0x1a/0x1c + __x64_sys_fchownat+0xbf/0x160 + ? lockdep_hardirqs_on+0x39a/0x5e0 + do_syscall_64+0xc8/0x580 + entry_SYSCALL_64_after_hwframe+0x49/0xbe +RIP: 0033:0x462589 +Code: f7 d8 64 89 02 b8 ff ff ff ff c3 66 0f 1f 44 00 00 48 89 f8 48 89 +f7 48 89 d6 48 89 +ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 +48 c7 c1 bc ff ff +ff f7 d8 64 89 01 48 +RSP: 002b:00007fb4b2c83c58 EFLAGS: 00000246 ORIG_RAX: 0000000000000104 +RAX: ffffffffffffffda RBX: 000000000072bfa0 RCX: 0000000000462589 +RDX: 0000000000000000 RSI: 00000000200000c0 RDI: 0000000000000007 +RBP: 0000000000000005 R08: 0000000000001000 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000246 R12: 00007fb4b2c846bc +R13: 00000000004bc733 R14: 00000000006f5138 R15: 00000000ffffffff + +Allocated by task 4185: + kasan_kmalloc+0xa0/0xd0 + __kmalloc+0x14a/0x350 + sk_prot_alloc+0xf6/0x290 + sk_alloc+0x3d/0xc00 + af_alg_accept+0x9e/0x670 + hash_accept+0x4a3/0x650 + __sys_accept4+0x306/0x5c0 + __x64_sys_accept4+0x98/0x100 + do_syscall_64+0xc8/0x580 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + +Freed by task 4184: + __kasan_slab_free+0x12e/0x180 + kfree+0xeb/0x2f0 + __sk_destruct+0x4e6/0x6a0 + sk_destruct+0x48/0x70 + __sk_free+0xa9/0x270 + sk_free+0x2a/0x30 + af_alg_release+0x5c/0x70 + __sock_release+0xd3/0x280 + sock_close+0x1a/0x20 + __fput+0x27f/0x7f0 + task_work_run+0x136/0x1b0 + exit_to_usermode_loop+0x1a7/0x1d0 + do_syscall_64+0x461/0x580 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + +Syzkaller reproducer: +r0 = perf_event_open(&(0x7f0000000000)={0x0, 0x70, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, @perf_config_ext}, 0x0, 0x0, +0xffffffffffffffff, 0x0) +r1 = socket$alg(0x26, 0x5, 0x0) +getrusage(0x0, 0x0) +bind(r1, &(0x7f00000001c0)=@alg={0x26, 'hash\x00', 0x0, 0x0, +'sha256-ssse3\x00'}, 0x80) +r2 = accept(r1, 0x0, 0x0) +r3 = accept4$unix(r2, 0x0, 0x0, 0x0) +r4 = dup3(r3, r0, 0x0) +fchownat(r4, &(0x7f00000000c0)='\x00', 0x0, 0x0, 0x1000) + +Fixes: 6d8c50dcb029 ("socket: close race condition between sock_close() and sockfs_setattr()") +Signed-off-by: Mao Wenan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + crypto/af_alg.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/crypto/af_alg.c b/crypto/af_alg.c +index 17eb09d222ff4..ec78a04eb136e 100644 +--- a/crypto/af_alg.c ++++ b/crypto/af_alg.c +@@ -122,8 +122,10 @@ static void alg_do_release(const struct af_alg_type *type, void *private) + + int af_alg_release(struct socket *sock) + { +- if (sock->sk) ++ if (sock->sk) { + sock_put(sock->sk); ++ sock->sk = NULL; ++ } + return 0; + } + EXPORT_SYMBOL_GPL(af_alg_release); +-- +2.19.1 + diff --git a/queue-4.19/net-do-not-allocate-page-fragments-that-are-not-skb-.patch b/queue-4.19/net-do-not-allocate-page-fragments-that-are-not-skb-.patch new file mode 100644 index 00000000000..327e6f1848a --- /dev/null +++ b/queue-4.19/net-do-not-allocate-page-fragments-that-are-not-skb-.patch @@ -0,0 +1,48 @@ +From 23153f4df6e9fda4a05826161fce5a011bc6558d Mon Sep 17 00:00:00 2001 +From: Alexander Duyck +Date: Fri, 15 Feb 2019 14:44:18 -0800 +Subject: net: Do not allocate page fragments that are not skb aligned + +[ Upstream commit 3bed3cc4156eedf652b4df72bdb35d4f1a2a739d ] + +This patch addresses the fact that there are drivers, specifically tun, +that will call into the network page fragment allocators with buffer sizes +that are not cache aligned. Doing this could result in data alignment +and DMA performance issues as these fragment pools are also shared with the +skb allocator and any other devices that will use napi_alloc_frags or +netdev_alloc_frags. + +Fixes: ffde7328a36d ("net: Split netdev_alloc_frag into __alloc_page_frag and add __napi_alloc_frag") +Reported-by: Jann Horn +Signed-off-by: Alexander Duyck +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/core/skbuff.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index 589ec5b9ec5f5..8656b1e20d35a 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -353,6 +353,8 @@ static void *__netdev_alloc_frag(unsigned int fragsz, gfp_t gfp_mask) + */ + void *netdev_alloc_frag(unsigned int fragsz) + { ++ fragsz = SKB_DATA_ALIGN(fragsz); ++ + return __netdev_alloc_frag(fragsz, GFP_ATOMIC); + } + EXPORT_SYMBOL(netdev_alloc_frag); +@@ -366,6 +368,8 @@ static void *__napi_alloc_frag(unsigned int fragsz, gfp_t gfp_mask) + + void *napi_alloc_frag(unsigned int fragsz) + { ++ fragsz = SKB_DATA_ALIGN(fragsz); ++ + return __napi_alloc_frag(fragsz, GFP_ATOMIC); + } + EXPORT_SYMBOL(napi_alloc_frag); +-- +2.19.1 + diff --git a/queue-4.19/net-fix-for_each_netdev_feature-on-big-endian.patch b/queue-4.19/net-fix-for_each_netdev_feature-on-big-endian.patch new file mode 100644 index 00000000000..c38305ebe2c --- /dev/null +++ b/queue-4.19/net-fix-for_each_netdev_feature-on-big-endian.patch @@ -0,0 +1,93 @@ +From c335f47f8f4d92c31c7582e34e857ce4018891c4 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens +Date: Fri, 15 Feb 2019 17:58:54 +0100 +Subject: net: Fix for_each_netdev_feature on Big endian + +[ Upstream commit 3b89ea9c5902acccdbbdec307c85edd1bf52515e ] + +The features attribute is of type u64 and stored in the native endianes on +the system. The for_each_set_bit() macro takes a pointer to a 32 bit array +and goes over the bits in this area. On little Endian systems this also +works with an u64 as the most significant bit is on the highest address, +but on big endian the words are swapped. When we expect bit 15 here we get +bit 47 (15 + 32). + +This patch converts it more or less to its own for_each_set_bit() +implementation which works on 64 bit integers directly. This is then +completely in host endianness and should work like expected. + +Fixes: fd867d51f ("net/core: generic support for disabling netdev features down stack") +Signed-off-by: Hauke Mehrtens +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + include/linux/netdev_features.h | 23 +++++++++++++++++++++-- + net/core/dev.c | 4 ++-- + 2 files changed, 23 insertions(+), 4 deletions(-) + +diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h +index 2b2a6dce16301..fce28562bed29 100644 +--- a/include/linux/netdev_features.h ++++ b/include/linux/netdev_features.h +@@ -11,6 +11,7 @@ + #define _LINUX_NETDEV_FEATURES_H + + #include ++#include + + typedef u64 netdev_features_t; + +@@ -154,8 +155,26 @@ enum { + #define NETIF_F_HW_TLS_TX __NETIF_F(HW_TLS_TX) + #define NETIF_F_HW_TLS_RX __NETIF_F(HW_TLS_RX) + +-#define for_each_netdev_feature(mask_addr, bit) \ +- for_each_set_bit(bit, (unsigned long *)mask_addr, NETDEV_FEATURE_COUNT) ++/* Finds the next feature with the highest number of the range of start till 0. ++ */ ++static inline int find_next_netdev_feature(u64 feature, unsigned long start) ++{ ++ /* like BITMAP_LAST_WORD_MASK() for u64 ++ * this sets the most significant 64 - start to 0. ++ */ ++ feature &= ~0ULL >> (-start & ((sizeof(feature) * 8) - 1)); ++ ++ return fls64(feature) - 1; ++} ++ ++/* This goes for the MSB to the LSB through the set feature bits, ++ * mask_addr should be a u64 and bit an int ++ */ ++#define for_each_netdev_feature(mask_addr, bit) \ ++ for ((bit) = find_next_netdev_feature((mask_addr), \ ++ NETDEV_FEATURE_COUNT); \ ++ (bit) >= 0; \ ++ (bit) = find_next_netdev_feature((mask_addr), (bit) - 1)) + + /* Features valid for ethtool to change */ + /* = all defined minus driver/device-class-related */ +diff --git a/net/core/dev.c b/net/core/dev.c +index af097ca9cb4fb..5c8c0a572ee9c 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -8039,7 +8039,7 @@ static netdev_features_t netdev_sync_upper_features(struct net_device *lower, + netdev_features_t feature; + int feature_bit; + +- for_each_netdev_feature(&upper_disables, feature_bit) { ++ for_each_netdev_feature(upper_disables, feature_bit) { + feature = __NETIF_F_BIT(feature_bit); + if (!(upper->wanted_features & feature) + && (features & feature)) { +@@ -8059,7 +8059,7 @@ static void netdev_sync_lower_features(struct net_device *upper, + netdev_features_t feature; + int feature_bit; + +- for_each_netdev_feature(&upper_disables, feature_bit) { ++ for_each_netdev_feature(upper_disables, feature_bit) { + feature = __NETIF_F_BIT(feature_bit); + if (!(features & feature) && (lower->features & feature)) { + netdev_dbg(upper, "Disabling feature %pNF on lower dev %s.\n", +-- +2.19.1 + diff --git a/queue-4.19/net-fix-ipv6-prefix-route-residue.patch b/queue-4.19/net-fix-ipv6-prefix-route-residue.patch new file mode 100644 index 00000000000..85b34b7c3ce --- /dev/null +++ b/queue-4.19/net-fix-ipv6-prefix-route-residue.patch @@ -0,0 +1,49 @@ +From e19cfa0f0b9c8bec88cb3a8abed586ed4917b937 Mon Sep 17 00:00:00 2001 +From: Zhiqiang Liu +Date: Mon, 11 Feb 2019 10:57:46 +0800 +Subject: net: fix IPv6 prefix route residue + +[ Upstream commit e75913c93f7cd5f338ab373c34c93a655bd309cb ] + +Follow those steps: + # ip addr add 2001:123::1/32 dev eth0 + # ip addr add 2001:123:456::2/64 dev eth0 + # ip addr del 2001:123::1/32 dev eth0 + # ip addr del 2001:123:456::2/64 dev eth0 +and then prefix route of 2001:123::1/32 will still exist. + +This is because ipv6_prefix_equal in check_cleanup_prefix_route +func does not check whether two IPv6 addresses have the same +prefix length. If the prefix of one address starts with another +shorter address prefix, even though their prefix lengths are +different, the return value of ipv6_prefix_equal is true. + +Here I add a check of whether two addresses have the same prefix +to decide whether their prefixes are equal. + +Fixes: 5b84efecb7d9 ("ipv6 addrconf: don't cleanup prefix route for IFA_F_NOPREFIXROUTE") +Signed-off-by: Zhiqiang Liu +Reported-by: Wenhao Zhang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/ipv6/addrconf.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index 3dfc50cd86d68..c57efd5c5b387 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -1148,7 +1148,8 @@ check_cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long *expires) + list_for_each_entry(ifa, &idev->addr_list, if_list) { + if (ifa == ifp) + continue; +- if (!ipv6_prefix_equal(&ifa->addr, &ifp->addr, ++ if (ifa->prefix_len != ifp->prefix_len || ++ !ipv6_prefix_equal(&ifa->addr, &ifp->addr, + ifp->prefix_len)) + continue; + if (ifa->flags & (IFA_F_PERMANENT | IFA_F_NOPREFIXROUTE)) +-- +2.19.1 + diff --git a/queue-4.19/net-ip6_gre-initialize-erspan_ver-just-for-erspan-tu.patch b/queue-4.19/net-ip6_gre-initialize-erspan_ver-just-for-erspan-tu.patch new file mode 100644 index 00000000000..3e7babdad81 --- /dev/null +++ b/queue-4.19/net-ip6_gre-initialize-erspan_ver-just-for-erspan-tu.patch @@ -0,0 +1,94 @@ +From b371017c0cb6d487dc92aa536f2981e95bd5952f Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Fri, 15 Feb 2019 15:10:32 +0100 +Subject: net: ip6_gre: initialize erspan_ver just for erspan tunnels + +[ Upstream commit 4974d5f678abb34401558559d47e2ea3d1c15cba ] + +After commit c706863bc890 ("net: ip6_gre: always reports o_key to +userspace"), ip6gre and ip6gretap tunnels started reporting TUNNEL_KEY +output flag even if it is not configured. +ip6gre_fill_info checks erspan_ver value to add TUNNEL_KEY for +erspan tunnels, however in commit 84581bdae9587 ("erspan: set +erspan_ver to 1 by default when adding an erspan dev") +erspan_ver is initialized to 1 even for ip6gre or ip6gretap +Fix the issue moving erspan_ver initialization in a dedicated routine + +Fixes: c706863bc890 ("net: ip6_gre: always reports o_key to userspace") +Signed-off-by: Lorenzo Bianconi +Reviewed-by: Greg Rose +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/ipv6/ip6_gre.c | 34 ++++++++++++++++++++-------------- + 1 file changed, 20 insertions(+), 14 deletions(-) + +diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c +index be04877b3827b..faed98dab9137 100644 +--- a/net/ipv6/ip6_gre.c ++++ b/net/ipv6/ip6_gre.c +@@ -1735,6 +1735,24 @@ static int ip6erspan_tap_validate(struct nlattr *tb[], struct nlattr *data[], + return 0; + } + ++static void ip6erspan_set_version(struct nlattr *data[], ++ struct __ip6_tnl_parm *parms) ++{ ++ parms->erspan_ver = 1; ++ if (data[IFLA_GRE_ERSPAN_VER]) ++ parms->erspan_ver = nla_get_u8(data[IFLA_GRE_ERSPAN_VER]); ++ ++ if (parms->erspan_ver == 1) { ++ if (data[IFLA_GRE_ERSPAN_INDEX]) ++ parms->index = nla_get_u32(data[IFLA_GRE_ERSPAN_INDEX]); ++ } else if (parms->erspan_ver == 2) { ++ if (data[IFLA_GRE_ERSPAN_DIR]) ++ parms->dir = nla_get_u8(data[IFLA_GRE_ERSPAN_DIR]); ++ if (data[IFLA_GRE_ERSPAN_HWID]) ++ parms->hwid = nla_get_u16(data[IFLA_GRE_ERSPAN_HWID]); ++ } ++} ++ + static void ip6gre_netlink_parms(struct nlattr *data[], + struct __ip6_tnl_parm *parms) + { +@@ -1783,20 +1801,6 @@ static void ip6gre_netlink_parms(struct nlattr *data[], + + if (data[IFLA_GRE_COLLECT_METADATA]) + parms->collect_md = true; +- +- parms->erspan_ver = 1; +- if (data[IFLA_GRE_ERSPAN_VER]) +- parms->erspan_ver = nla_get_u8(data[IFLA_GRE_ERSPAN_VER]); +- +- if (parms->erspan_ver == 1) { +- if (data[IFLA_GRE_ERSPAN_INDEX]) +- parms->index = nla_get_u32(data[IFLA_GRE_ERSPAN_INDEX]); +- } else if (parms->erspan_ver == 2) { +- if (data[IFLA_GRE_ERSPAN_DIR]) +- parms->dir = nla_get_u8(data[IFLA_GRE_ERSPAN_DIR]); +- if (data[IFLA_GRE_ERSPAN_HWID]) +- parms->hwid = nla_get_u16(data[IFLA_GRE_ERSPAN_HWID]); +- } + } + + static int ip6gre_tap_init(struct net_device *dev) +@@ -2225,6 +2229,7 @@ static int ip6erspan_newlink(struct net *src_net, struct net_device *dev, + int err; + + ip6gre_netlink_parms(data, &nt->parms); ++ ip6erspan_set_version(data, &nt->parms); + ign = net_generic(net, ip6gre_net_id); + + if (nt->parms.collect_md) { +@@ -2270,6 +2275,7 @@ static int ip6erspan_changelink(struct net_device *dev, struct nlattr *tb[], + if (IS_ERR(t)) + return PTR_ERR(t); + ++ ip6erspan_set_version(data, &p); + ip6gre_tunnel_unlink_md(ign, t); + ip6gre_tunnel_unlink(ign, t); + ip6erspan_tnl_change(t, &p, !tb[IFLA_MTU]); +-- +2.19.1 + diff --git a/queue-4.19/net-ipv4-use-a-dedicated-counter-for-icmp_v4-redirec.patch b/queue-4.19/net-ipv4-use-a-dedicated-counter-for-icmp_v4-redirec.patch new file mode 100644 index 00000000000..46b91239a01 --- /dev/null +++ b/queue-4.19/net-ipv4-use-a-dedicated-counter-for-icmp_v4-redirec.patch @@ -0,0 +1,93 @@ +From c13b37eebab1ed392c2ba804bd01ac1cecf72c6f Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Wed, 6 Feb 2019 19:18:04 +0100 +Subject: net: ipv4: use a dedicated counter for icmp_v4 redirect packets + +[ Upstream commit c09551c6ff7fe16a79a42133bcecba5fc2fc3291 ] + +According to the algorithm described in the comment block at the +beginning of ip_rt_send_redirect, the host should try to send +'ip_rt_redirect_number' ICMP redirect packets with an exponential +backoff and then stop sending them at all assuming that the destination +ignores redirects. +If the device has previously sent some ICMP error packets that are +rate-limited (e.g TTL expired) and continues to receive traffic, +the redirect packets will never be transmitted. This happens since +peer->rate_tokens will be typically greater than 'ip_rt_redirect_number' +and so it will never be reset even if the redirect silence timeout +(ip_rt_redirect_silence) has elapsed without receiving any packet +requiring redirects. + +Fix it by using a dedicated counter for the number of ICMP redirect +packets that has been sent by the host + +I have not been able to identify a given commit that introduced the +issue since ip_rt_send_redirect implements the same rate-limiting +algorithm from commit 1da177e4c3f4 ("Linux-2.6.12-rc2") + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + include/net/inetpeer.h | 1 + + net/ipv4/inetpeer.c | 1 + + net/ipv4/route.c | 7 +++++-- + 3 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h +index 00b5e7825508a..74ff688568a0c 100644 +--- a/include/net/inetpeer.h ++++ b/include/net/inetpeer.h +@@ -39,6 +39,7 @@ struct inet_peer { + + u32 metrics[RTAX_MAX]; + u32 rate_tokens; /* rate limiting for ICMP */ ++ u32 n_redirects; + unsigned long rate_last; + /* + * Once inet_peer is queued for deletion (refcnt == 0), following field +diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c +index d757b9642d0d1..be778599bfedf 100644 +--- a/net/ipv4/inetpeer.c ++++ b/net/ipv4/inetpeer.c +@@ -216,6 +216,7 @@ struct inet_peer *inet_getpeer(struct inet_peer_base *base, + atomic_set(&p->rid, 0); + p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW; + p->rate_tokens = 0; ++ p->n_redirects = 0; + /* 60*HZ is arbitrary, but chosen enough high so that the first + * calculation of tokens is at its maximum. + */ +diff --git a/net/ipv4/route.c b/net/ipv4/route.c +index 8501554e96a4a..436b46c0e687f 100644 +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -887,13 +887,15 @@ void ip_rt_send_redirect(struct sk_buff *skb) + /* No redirected packets during ip_rt_redirect_silence; + * reset the algorithm. + */ +- if (time_after(jiffies, peer->rate_last + ip_rt_redirect_silence)) ++ if (time_after(jiffies, peer->rate_last + ip_rt_redirect_silence)) { + peer->rate_tokens = 0; ++ peer->n_redirects = 0; ++ } + + /* Too many ignored redirects; do not send anything + * set dst.rate_last to the last seen redirected packet. + */ +- if (peer->rate_tokens >= ip_rt_redirect_number) { ++ if (peer->n_redirects >= ip_rt_redirect_number) { + peer->rate_last = jiffies; + goto out_put_peer; + } +@@ -910,6 +912,7 @@ void ip_rt_send_redirect(struct sk_buff *skb) + icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, gw); + peer->rate_last = jiffies; + ++peer->rate_tokens; ++ ++peer->n_redirects; + #ifdef CONFIG_IP_ROUTE_VERBOSE + if (log_martians && + peer->rate_tokens == ip_rt_redirect_number) +-- +2.19.1 + diff --git a/queue-4.19/net-phy-xgmiitorgmii-support-generic-phy-status-read.patch b/queue-4.19/net-phy-xgmiitorgmii-support-generic-phy-status-read.patch new file mode 100644 index 00000000000..1274469f9d0 --- /dev/null +++ b/queue-4.19/net-phy-xgmiitorgmii-support-generic-phy-status-read.patch @@ -0,0 +1,41 @@ +From 9608b6f87a8979ed4bec4301f47bc645c727cf3d Mon Sep 17 00:00:00 2001 +From: Paul Kocialkowski +Date: Fri, 15 Feb 2019 17:17:08 +0100 +Subject: net: phy: xgmiitorgmii: Support generic PHY status read + +[ Upstream commit 197f9ab7f08ce4b9ece662f747c3991b2f0fbb57 ] + +Some PHY drivers like the generic one do not provide a read_status +callback on their own but rely on genphy_read_status being called +directly. + +With the current code, this results in a NULL function pointer call. +Call genphy_read_status instead when there is no specific callback. + +Fixes: f411a6160bd4 ("net: phy: Add gmiitorgmii converter support") +Signed-off-by: Paul Kocialkowski +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/phy/xilinx_gmii2rgmii.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/phy/xilinx_gmii2rgmii.c b/drivers/net/phy/xilinx_gmii2rgmii.c +index 74a8782313cf5..bd6084e315de2 100644 +--- a/drivers/net/phy/xilinx_gmii2rgmii.c ++++ b/drivers/net/phy/xilinx_gmii2rgmii.c +@@ -44,7 +44,10 @@ static int xgmiitorgmii_read_status(struct phy_device *phydev) + u16 val = 0; + int err; + +- err = priv->phy_drv->read_status(phydev); ++ if (priv->phy_drv->read_status) ++ err = priv->phy_drv->read_status(phydev); ++ else ++ err = genphy_read_status(phydev); + if (err < 0) + return err; + +-- +2.19.1 + diff --git a/queue-4.19/net-stmmac-fix-a-race-in-eee-enable-callback.patch b/queue-4.19/net-stmmac-fix-a-race-in-eee-enable-callback.patch new file mode 100644 index 00000000000..1ad4ee5595a --- /dev/null +++ b/queue-4.19/net-stmmac-fix-a-race-in-eee-enable-callback.patch @@ -0,0 +1,71 @@ +From 7d91218c06548310706e779833b0802616b5303e Mon Sep 17 00:00:00 2001 +From: Jose Abreu +Date: Mon, 18 Feb 2019 14:35:03 +0100 +Subject: net: stmmac: Fix a race in EEE enable callback + +[ Upstream commit 8a7493e58ad688eb23b81e45461c5d314f4402f1 ] + +We are saving the status of EEE even before we try to enable it. This +leads to a race with XMIT function that tries to arm EEE timer before we +set it up. + +Fix this by only saving the EEE parameters after all operations are +performed with success. + +Signed-off-by: Jose Abreu +Fixes: d765955d2ae0 ("stmmac: add the Energy Efficient Ethernet support") +Cc: Joao Pinto +Cc: David S. Miller +Cc: Giuseppe Cavallaro +Cc: Alexandre Torgue +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + .../ethernet/stmicro/stmmac/stmmac_ethtool.c | 22 ++++++++++--------- + 1 file changed, 12 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +index 5710864fa8090..9caf79ba5ef16 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +@@ -692,25 +692,27 @@ static int stmmac_ethtool_op_set_eee(struct net_device *dev, + struct ethtool_eee *edata) + { + struct stmmac_priv *priv = netdev_priv(dev); ++ int ret; + +- priv->eee_enabled = edata->eee_enabled; +- +- if (!priv->eee_enabled) ++ if (!edata->eee_enabled) { + stmmac_disable_eee_mode(priv); +- else { ++ } else { + /* We are asking for enabling the EEE but it is safe + * to verify all by invoking the eee_init function. + * In case of failure it will return an error. + */ +- priv->eee_enabled = stmmac_eee_init(priv); +- if (!priv->eee_enabled) ++ edata->eee_enabled = stmmac_eee_init(priv); ++ if (!edata->eee_enabled) + return -EOPNOTSUPP; +- +- /* Do not change tx_lpi_timer in case of failure */ +- priv->tx_lpi_timer = edata->tx_lpi_timer; + } + +- return phy_ethtool_set_eee(dev->phydev, edata); ++ ret = phy_ethtool_set_eee(dev->phydev, edata); ++ if (ret) ++ return ret; ++ ++ priv->eee_enabled = edata->eee_enabled; ++ priv->tx_lpi_timer = edata->tx_lpi_timer; ++ return 0; + } + + static u32 stmmac_usec2riwt(u32 usec, struct stmmac_priv *priv) +-- +2.19.1 + diff --git a/queue-4.19/net-stmmac-handle-endianness-in-dwmac4_get_timestamp.patch b/queue-4.19/net-stmmac-handle-endianness-in-dwmac4_get_timestamp.patch new file mode 100644 index 00000000000..f021e8fc84f --- /dev/null +++ b/queue-4.19/net-stmmac-handle-endianness-in-dwmac4_get_timestamp.patch @@ -0,0 +1,48 @@ +From f2cb51071caacb999e50a0ebfae8aa8cf1956a20 Mon Sep 17 00:00:00 2001 +From: Alexandre Torgue +Date: Fri, 15 Feb 2019 10:49:09 +0100 +Subject: net: stmmac: handle endianness in dwmac4_get_timestamp + +[ Upstream commit 224babd62d6f19581757a6d8bae3bf9501fc10de ] + +GMAC IP is little-endian and used on several kind of CPU (big or little +endian). Main callbacks functions of the stmmac drivers take care about +it. It was not the case for dwmac4_get_timestamp function. + +Fixes: ba1ffd74df74 ("stmmac: fix PTP support for GMAC4") +Signed-off-by: Alexandre Torgue +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c +index 20299f6f65fce..736e29635b772 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c +@@ -241,15 +241,18 @@ static inline void dwmac4_get_timestamp(void *desc, u32 ats, u64 *ts) + static int dwmac4_rx_check_timestamp(void *desc) + { + struct dma_desc *p = (struct dma_desc *)desc; ++ unsigned int rdes0 = le32_to_cpu(p->des0); ++ unsigned int rdes1 = le32_to_cpu(p->des1); ++ unsigned int rdes3 = le32_to_cpu(p->des3); + u32 own, ctxt; + int ret = 1; + +- own = p->des3 & RDES3_OWN; +- ctxt = ((p->des3 & RDES3_CONTEXT_DESCRIPTOR) ++ own = rdes3 & RDES3_OWN; ++ ctxt = ((rdes3 & RDES3_CONTEXT_DESCRIPTOR) + >> RDES3_CONTEXT_DESCRIPTOR_SHIFT); + + if (likely(!own && ctxt)) { +- if ((p->des0 == 0xffffffff) && (p->des1 == 0xffffffff)) ++ if ((rdes0 == 0xffffffff) && (rdes1 == 0xffffffff)) + /* Corrupted value */ + ret = -EINVAL; + else +-- +2.19.1 + diff --git a/queue-4.19/net-validate-untrusted-gso-packets-without-csum-offl.patch b/queue-4.19/net-validate-untrusted-gso-packets-without-csum-offl.patch new file mode 100644 index 00000000000..098d7913a3b --- /dev/null +++ b/queue-4.19/net-validate-untrusted-gso-packets-without-csum-offl.patch @@ -0,0 +1,69 @@ +From 6090bbe4cbbd0f0ee07fefaeef143fdcb582d9b5 Mon Sep 17 00:00:00 2001 +From: Willem de Bruijn +Date: Fri, 15 Feb 2019 12:15:47 -0500 +Subject: net: validate untrusted gso packets without csum offload + +[ Upstream commit d5be7f632bad0f489879eed0ff4b99bd7fe0b74c ] + +Syzkaller again found a path to a kernel crash through bad gso input. +By building an excessively large packet to cause an skb field to wrap. + +If VIRTIO_NET_HDR_F_NEEDS_CSUM was set this would have been dropped in +skb_partial_csum_set. + +GSO packets that do not set checksum offload are suspicious and rare. +Most callers of virtio_net_hdr_to_skb already pass them to +skb_probe_transport_header. + +Move that test forward, change it to detect parse failure and drop +packets on failure as those cleary are not one of the legitimate +VIRTIO_NET_HDR_GSO types. + +Fixes: bfd5f4a3d605 ("packet: Add GSO/csum offload support.") +Fixes: f43798c27684 ("tun: Allow GSO using virtio_net_hdr") +Reported-by: syzbot +Signed-off-by: Willem de Bruijn +Reviewed-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + include/linux/skbuff.h | 2 +- + include/linux/virtio_net.h | 9 +++++++++ + 2 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h +index 5d69e208e8d91..a404d475acee3 100644 +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -2392,7 +2392,7 @@ static inline void skb_probe_transport_header(struct sk_buff *skb, + + if (skb_flow_dissect_flow_keys_basic(skb, &keys, NULL, 0, 0, 0, 0)) + skb_set_transport_header(skb, keys.control.thoff); +- else ++ else if (offset_hint >= 0) + skb_set_transport_header(skb, offset_hint); + } + +diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h +index cb462f9ab7dd5..71f2394abbf7c 100644 +--- a/include/linux/virtio_net.h ++++ b/include/linux/virtio_net.h +@@ -57,6 +57,15 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb, + + if (!skb_partial_csum_set(skb, start, off)) + return -EINVAL; ++ } else { ++ /* gso packets without NEEDS_CSUM do not set transport_offset. ++ * probe and drop if does not match one of the above types. ++ */ ++ if (gso_type) { ++ skb_probe_transport_header(skb, -1); ++ if (!skb_transport_header_was_set(skb)) ++ return -EINVAL; ++ } + } + + if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) { +-- +2.19.1 + diff --git a/queue-4.19/series b/queue-4.19/series new file mode 100644 index 00000000000..578b159088d --- /dev/null +++ b/queue-4.19/series @@ -0,0 +1,20 @@ +af_packet-fix-raw-sockets-over-6in4-tunnel.patch +dsa-mv88e6xxx-ensure-all-pending-interrupts-are-hand.patch +mlxsw-__mlxsw_sp_port_headroom_set-fix-a-use-of-loca.patch +net-crypto-set-sk-to-null-when-af_alg_release.patch +net-fix-for_each_netdev_feature-on-big-endian.patch +net-fix-ipv6-prefix-route-residue.patch +net-ip6_gre-initialize-erspan_ver-just-for-erspan-tu.patch +net-ipv4-use-a-dedicated-counter-for-icmp_v4-redirec.patch +net-phy-xgmiitorgmii-support-generic-phy-status-read.patch +net-stmmac-fix-a-race-in-eee-enable-callback.patch +net-stmmac-handle-endianness-in-dwmac4_get_timestamp.patch +net-validate-untrusted-gso-packets-without-csum-offl.patch +sky2-increase-d3-delay-again.patch +vhost-correctly-check-the-return-value-of-translate_.patch +vsock-cope-with-memory-allocation-failure-at-socket-.patch +vxlan-test-dev-flags-iff_up-before-calling-netif_rx.patch +net-add-header-for-usage-of-fls64.patch +tcp-clear-icsk_backoff-in-tcp_write_queue_purge.patch +tcp-tcp_v4_err-should-be-more-careful.patch +net-do-not-allocate-page-fragments-that-are-not-skb-.patch diff --git a/queue-4.19/sky2-increase-d3-delay-again.patch b/queue-4.19/sky2-increase-d3-delay-again.patch new file mode 100644 index 00000000000..37b7f0437f1 --- /dev/null +++ b/queue-4.19/sky2-increase-d3-delay-again.patch @@ -0,0 +1,37 @@ +From a5e9ace0ad73cd1134475525c106f6c0ba55d6f9 Mon Sep 17 00:00:00 2001 +From: Kai-Heng Feng +Date: Tue, 19 Feb 2019 23:45:29 +0800 +Subject: sky2: Increase D3 delay again + +[ Upstream commit 1765f5dcd00963e33f1b8a4e0f34061fbc0e2f7f ] + +Another platform requires even longer delay to make the device work +correctly after S3. + +So increase the delay to 300ms. + +BugLink: https://bugs.launchpad.net/bugs/1798921 + +Signed-off-by: Kai-Heng Feng +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/marvell/sky2.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c +index 697d9b374f5e1..ae2f35039343b 100644 +--- a/drivers/net/ethernet/marvell/sky2.c ++++ b/drivers/net/ethernet/marvell/sky2.c +@@ -5087,7 +5087,7 @@ static int sky2_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + INIT_WORK(&hw->restart_work, sky2_restart); + + pci_set_drvdata(pdev, hw); +- pdev->d3_delay = 200; ++ pdev->d3_delay = 300; + + return 0; + +-- +2.19.1 + diff --git a/queue-4.19/tcp-clear-icsk_backoff-in-tcp_write_queue_purge.patch b/queue-4.19/tcp-clear-icsk_backoff-in-tcp_write_queue_purge.patch new file mode 100644 index 00000000000..92d1fdb1f33 --- /dev/null +++ b/queue-4.19/tcp-clear-icsk_backoff-in-tcp_write_queue_purge.patch @@ -0,0 +1,52 @@ +From d10073013d3683f88bed675b7824da2c552115df Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Fri, 15 Feb 2019 13:36:20 -0800 +Subject: tcp: clear icsk_backoff in tcp_write_queue_purge() + +[ Upstream commit 04c03114be82194d4a4858d41dba8e286ad1787c ] + +soukjin bae reported a crash in tcp_v4_err() handling +ICMP_DEST_UNREACH after tcp_write_queue_head(sk) +returned a NULL pointer. + +Current logic should have prevented this : + + if (seq != tp->snd_una || !icsk->icsk_retransmits || + !icsk->icsk_backoff || fastopen) + break; + +Problem is the write queue might have been purged +and icsk_backoff has not been cleared. + +Signed-off-by: Eric Dumazet +Reported-by: soukjin bae +Acked-by: Neal Cardwell +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/ipv4/tcp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index 87fe44197aa1f..432dc9af11720 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -2519,6 +2519,7 @@ void tcp_write_queue_purge(struct sock *sk) + sk_mem_reclaim(sk); + tcp_clear_all_retrans_hints(tcp_sk(sk)); + tcp_sk(sk)->packets_out = 0; ++ inet_csk(sk)->icsk_backoff = 0; + } + + int tcp_disconnect(struct sock *sk, int flags) +@@ -2567,7 +2568,6 @@ int tcp_disconnect(struct sock *sk, int flags) + tp->write_seq += tp->max_window + 2; + if (tp->write_seq == 0) + tp->write_seq = 1; +- icsk->icsk_backoff = 0; + tp->snd_cwnd = 2; + icsk->icsk_probes_out = 0; + tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; +-- +2.19.1 + diff --git a/queue-4.19/tcp-tcp_v4_err-should-be-more-careful.patch b/queue-4.19/tcp-tcp_v4_err-should-be-more-careful.patch new file mode 100644 index 00000000000..93a067eb033 --- /dev/null +++ b/queue-4.19/tcp-tcp_v4_err-should-be-more-careful.patch @@ -0,0 +1,42 @@ +From 94e74a6e433409982245977b6f77e0d0bf12cb29 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Fri, 15 Feb 2019 13:36:21 -0800 +Subject: tcp: tcp_v4_err() should be more careful + +[ Upstream commit 2c4cc9712364c051b1de2d175d5fbea6be948ebf ] + +ICMP handlers are not very often stressed, we should +make them more resilient to bugs that might surface in +the future. + +If there is no packet in retransmit queue, we should +avoid a NULL deref. + +Signed-off-by: Eric Dumazet +Reported-by: soukjin bae +Acked-by: Neal Cardwell +Acked-by: Soheil Hassas Yeganeh +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/ipv4/tcp_ipv4.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c +index cd426313a2981..4370ef1d547e1 100644 +--- a/net/ipv4/tcp_ipv4.c ++++ b/net/ipv4/tcp_ipv4.c +@@ -535,6 +535,10 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) + if (sock_owned_by_user(sk)) + break; + ++ skb = tcp_rtx_queue_head(sk); ++ if (WARN_ON_ONCE(!skb)) ++ break; ++ + icsk->icsk_backoff--; + icsk->icsk_rto = tp->srtt_us ? __tcp_set_rto(tp) : + TCP_TIMEOUT_INIT; +-- +2.19.1 + diff --git a/queue-4.19/vhost-correctly-check-the-return-value-of-translate_.patch b/queue-4.19/vhost-correctly-check-the-return-value-of-translate_.patch new file mode 100644 index 00000000000..618138b43c2 --- /dev/null +++ b/queue-4.19/vhost-correctly-check-the-return-value-of-translate_.patch @@ -0,0 +1,40 @@ +From 1f4af01ad0030703aaeaa0317fd2be25797804e0 Mon Sep 17 00:00:00 2001 +From: Jason Wang +Date: Tue, 19 Feb 2019 14:53:44 +0800 +Subject: vhost: correctly check the return value of translate_desc() in + log_used() + +[ Upstream commit 816db7663565cd23f74ed3d5c9240522e3fb0dda ] + +When fail, translate_desc() returns negative value, otherwise the +number of iovs. So we should fail when the return value is negative +instead of a blindly check against zero. + +Detected by CoverityScan, CID# 1442593: Control flow issues (DEADCODE) + +Fixes: cc5e71075947 ("vhost: log dirty page correctly") +Acked-by: Michael S. Tsirkin +Reported-by: Stephen Hemminger +Signed-off-by: Jason Wang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/vhost/vhost.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c +index cf82e72663976..5eaeca805c95c 100644 +--- a/drivers/vhost/vhost.c ++++ b/drivers/vhost/vhost.c +@@ -1784,7 +1784,7 @@ static int log_used(struct vhost_virtqueue *vq, u64 used_offset, u64 len) + + ret = translate_desc(vq, (uintptr_t)vq->used + used_offset, + len, iov, 64, VHOST_ACCESS_WO); +- if (ret) ++ if (ret < 0) + return ret; + + for (i = 0; i < ret; i++) { +-- +2.19.1 + diff --git a/queue-4.19/vsock-cope-with-memory-allocation-failure-at-socket-.patch b/queue-4.19/vsock-cope-with-memory-allocation-failure-at-socket-.patch new file mode 100644 index 00000000000..37cd9eaeff5 --- /dev/null +++ b/queue-4.19/vsock-cope-with-memory-allocation-failure-at-socket-.patch @@ -0,0 +1,43 @@ +From e3928867b8812df6289ee538231e07463cb3a3da Mon Sep 17 00:00:00 2001 +From: Paolo Abeni +Date: Thu, 7 Feb 2019 14:13:18 +0100 +Subject: vsock: cope with memory allocation failure at socket creation time + +[ Upstream commit 225d9464268599a5b4d094d02ec17808e44c7553 ] + +In the unlikely event that the kmalloc call in vmci_transport_socket_init() +fails, we end-up calling vmci_transport_destruct() with a NULL vmci_trans() +and oopsing. + +This change addresses the above explicitly checking for zero vmci_trans() +at destruction time. + +Reported-by: Xiumei Mu +Fixes: d021c344051a ("VSOCK: Introduce VM Sockets") +Signed-off-by: Paolo Abeni +Reviewed-by: Stefano Garzarella +Reviewed-by: Jorgen Hansen +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/vmw_vsock/vmci_transport.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c +index c361ce7824123..c3d5ab01fba7b 100644 +--- a/net/vmw_vsock/vmci_transport.c ++++ b/net/vmw_vsock/vmci_transport.c +@@ -1651,6 +1651,10 @@ static void vmci_transport_cleanup(struct work_struct *work) + + static void vmci_transport_destruct(struct vsock_sock *vsk) + { ++ /* transport can be NULL if we hit a failure at init() time */ ++ if (!vmci_trans(vsk)) ++ return; ++ + /* Ensure that the detach callback doesn't use the sk/vsk + * we are about to destruct. + */ +-- +2.19.1 + diff --git a/queue-4.19/vxlan-test-dev-flags-iff_up-before-calling-netif_rx.patch b/queue-4.19/vxlan-test-dev-flags-iff_up-before-calling-netif_rx.patch new file mode 100644 index 00000000000..53cf0ac6733 --- /dev/null +++ b/queue-4.19/vxlan-test-dev-flags-iff_up-before-calling-netif_rx.patch @@ -0,0 +1,86 @@ +From 430ae01fe18936ca36dd0c90f0ce6c8114af4f7b Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Thu, 7 Feb 2019 12:27:38 -0800 +Subject: vxlan: test dev->flags & IFF_UP before calling netif_rx() + +[ Upstream commit 4179cb5a4c924cd233eaadd081882425bc98f44e ] + +netif_rx() must be called under a strict contract. + +At device dismantle phase, core networking clears IFF_UP +and flush_all_backlogs() is called after rcu grace period +to make sure no incoming packet might be in a cpu backlog +and still referencing the device. + +Most drivers call netif_rx() from their interrupt handler, +and since the interrupts are disabled at device dismantle, +netif_rx() does not have to check dev->flags & IFF_UP + +Virtual drivers do not have this guarantee, and must +therefore make the check themselves. + +Otherwise we risk use-after-free and/or crashes. + +Note this patch also fixes a small issue that came +with commit ce6502a8f957 ("vxlan: fix a use after free +in vxlan_encap_bypass"), since the dev->stats.rx_dropped +change was done on the wrong device. + +Fixes: d342894c5d2f ("vxlan: virtual extensible lan") +Fixes: ce6502a8f957 ("vxlan: fix a use after free in vxlan_encap_bypass") +Signed-off-by: Eric Dumazet +Cc: Petr Machata +Cc: Ido Schimmel +Cc: Roopa Prabhu +Cc: Stefano Brivio +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/vxlan.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c +index 27bd586b94b0a..9fc9aed6ca9a7 100644 +--- a/drivers/net/vxlan.c ++++ b/drivers/net/vxlan.c +@@ -2003,7 +2003,7 @@ static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan, + struct pcpu_sw_netstats *tx_stats, *rx_stats; + union vxlan_addr loopback; + union vxlan_addr *remote_ip = &dst_vxlan->default_dst.remote_ip; +- struct net_device *dev = skb->dev; ++ struct net_device *dev; + int len = skb->len; + + tx_stats = this_cpu_ptr(src_vxlan->dev->tstats); +@@ -2023,9 +2023,15 @@ static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan, + #endif + } + ++ rcu_read_lock(); ++ dev = skb->dev; ++ if (unlikely(!(dev->flags & IFF_UP))) { ++ kfree_skb(skb); ++ goto drop; ++ } ++ + if (dst_vxlan->cfg.flags & VXLAN_F_LEARN) +- vxlan_snoop(skb->dev, &loopback, eth_hdr(skb)->h_source, 0, +- vni); ++ vxlan_snoop(dev, &loopback, eth_hdr(skb)->h_source, 0, vni); + + u64_stats_update_begin(&tx_stats->syncp); + tx_stats->tx_packets++; +@@ -2038,8 +2044,10 @@ static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan, + rx_stats->rx_bytes += len; + u64_stats_update_end(&rx_stats->syncp); + } else { ++drop: + dev->stats.rx_dropped++; + } ++ rcu_read_unlock(); + } + + static int encap_bypass_if_local(struct sk_buff *skb, struct net_device *dev, +-- +2.19.1 +