From: Greg Kroah-Hartman Date: Thu, 11 Jun 2020 10:47:09 +0000 (+0200) Subject: 5.4-stable patches X-Git-Tag: v5.4.47~143 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3e5932df1c3d7297cfcffff3a7d79f00f77ca05b;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: bridge-avoid-infinite-loop-when-suppressing-ns-messages-with-invalid-options.patch ipv6-fix-ipv6_addrform-operation-logic.patch mlxsw-core-use-different-get_trend-callbacks-for-different-thermal-zones.patch net_failover-fixed-rollback-in-net_failover_open.patch tun-correct-header-offsets-in-napi-frags-mode.patch vxlan-avoid-infinite-loop-when-suppressing-ns-messages-with-invalid-options.patch --- diff --git a/queue-5.4/bridge-avoid-infinite-loop-when-suppressing-ns-messages-with-invalid-options.patch b/queue-5.4/bridge-avoid-infinite-loop-when-suppressing-ns-messages-with-invalid-options.patch new file mode 100644 index 00000000000..3c024adc128 --- /dev/null +++ b/queue-5.4/bridge-avoid-infinite-loop-when-suppressing-ns-messages-with-invalid-options.patch @@ -0,0 +1,50 @@ +From foo@baz Thu 11 Jun 2020 12:42:45 PM CEST +From: Ido Schimmel +Date: Mon, 1 Jun 2020 15:58:54 +0300 +Subject: bridge: Avoid infinite loop when suppressing NS messages with invalid options + +From: Ido Schimmel + +[ Upstream commit 53fc685243bd6fb90d90305cea54598b78d3cbfc ] + +When neighbor suppression is enabled the bridge device might reply to +Neighbor Solicitation (NS) messages on behalf of remote hosts. + +In case the NS message includes the "Source link-layer address" option +[1], the bridge device will use the specified address as the link-layer +destination address in its reply. + +To avoid an infinite loop, break out of the options parsing loop when +encountering an option with length zero and disregard the NS message. + +This is consistent with the IPv6 ndisc code and RFC 4886 which states +that "Nodes MUST silently discard an ND packet that contains an option +with length zero" [2]. + +[1] https://tools.ietf.org/html/rfc4861#section-4.3 +[2] https://tools.ietf.org/html/rfc4861#section-4.6 + +Fixes: ed842faeb2bd ("bridge: suppress nd pkts on BR_NEIGH_SUPPRESS ports") +Signed-off-by: Ido Schimmel +Reported-by: Alla Segal +Tested-by: Alla Segal +Acked-by: Nikolay Aleksandrov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/bridge/br_arp_nd_proxy.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/net/bridge/br_arp_nd_proxy.c ++++ b/net/bridge/br_arp_nd_proxy.c +@@ -276,6 +276,10 @@ static void br_nd_send(struct net_bridge + ns_olen = request->len - (skb_network_offset(request) + + sizeof(struct ipv6hdr)) - sizeof(*ns); + for (i = 0; i < ns_olen - 1; i += (ns->opt[i + 1] << 3)) { ++ if (!ns->opt[i + 1]) { ++ kfree_skb(reply); ++ return; ++ } + if (ns->opt[i] == ND_OPT_SOURCE_LL_ADDR) { + daddr = ns->opt + i + sizeof(struct nd_opt_hdr); + break; diff --git a/queue-5.4/ipv6-fix-ipv6_addrform-operation-logic.patch b/queue-5.4/ipv6-fix-ipv6_addrform-operation-logic.patch new file mode 100644 index 00000000000..fb6351af78c --- /dev/null +++ b/queue-5.4/ipv6-fix-ipv6_addrform-operation-logic.patch @@ -0,0 +1,77 @@ +From foo@baz Thu 11 Jun 2020 12:42:45 PM CEST +From: Hangbin Liu +Date: Mon, 1 Jun 2020 11:55:03 +0800 +Subject: ipv6: fix IPV6_ADDRFORM operation logic + +From: Hangbin Liu + +[ Upstream commit 79a1f0ccdbb4ad700590f61b00525b390cb53905 ] + +Socket option IPV6_ADDRFORM supports UDP/UDPLITE and TCP at present. +Previously the checking logic looks like: +if (sk->sk_protocol == IPPROTO_UDP || sk->sk_protocol == IPPROTO_UDPLITE) + do_some_check; +else if (sk->sk_protocol != IPPROTO_TCP) + break; + +After commit b6f6118901d1 ("ipv6: restrict IPV6_ADDRFORM operation"), TCP +was blocked as the logic changed to: +if (sk->sk_protocol == IPPROTO_UDP || sk->sk_protocol == IPPROTO_UDPLITE) + do_some_check; +else if (sk->sk_protocol == IPPROTO_TCP) + do_some_check; + break; +else + break; + +Then after commit 82c9ae440857 ("ipv6: fix restrict IPV6_ADDRFORM operation") +UDP/UDPLITE were blocked as the logic changed to: +if (sk->sk_protocol == IPPROTO_UDP || sk->sk_protocol == IPPROTO_UDPLITE) + do_some_check; +if (sk->sk_protocol == IPPROTO_TCP) + do_some_check; + +if (sk->sk_protocol != IPPROTO_TCP) + break; + +Fix it by using Eric's code and simply remove the break in TCP check, which +looks like: +if (sk->sk_protocol == IPPROTO_UDP || sk->sk_protocol == IPPROTO_UDPLITE) + do_some_check; +else if (sk->sk_protocol == IPPROTO_TCP) + do_some_check; +else + break; + +Fixes: 82c9ae440857 ("ipv6: fix restrict IPV6_ADDRFORM operation") +Signed-off-by: Hangbin Liu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ipv6_sockglue.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +--- a/net/ipv6/ipv6_sockglue.c ++++ b/net/ipv6/ipv6_sockglue.c +@@ -183,14 +183,15 @@ static int do_ipv6_setsockopt(struct soc + retv = -EBUSY; + break; + } +- } +- if (sk->sk_protocol == IPPROTO_TCP && +- sk->sk_prot != &tcpv6_prot) { +- retv = -EBUSY; ++ } else if (sk->sk_protocol == IPPROTO_TCP) { ++ if (sk->sk_prot != &tcpv6_prot) { ++ retv = -EBUSY; ++ break; ++ } ++ } else { + break; + } +- if (sk->sk_protocol != IPPROTO_TCP) +- break; ++ + if (sk->sk_state != TCP_ESTABLISHED) { + retv = -ENOTCONN; + break; diff --git a/queue-5.4/mlxsw-core-use-different-get_trend-callbacks-for-different-thermal-zones.patch b/queue-5.4/mlxsw-core-use-different-get_trend-callbacks-for-different-thermal-zones.patch new file mode 100644 index 00000000000..5984412c5e9 --- /dev/null +++ b/queue-5.4/mlxsw-core-use-different-get_trend-callbacks-for-different-thermal-zones.patch @@ -0,0 +1,83 @@ +From foo@baz Thu 11 Jun 2020 12:42:45 PM CEST +From: Vadim Pasternak +Date: Sun, 7 Jun 2020 11:10:27 +0300 +Subject: mlxsw: core: Use different get_trend() callbacks for different thermal zones + +From: Vadim Pasternak + +[ Upstream commit 2dc2f760052da4925482ecdcdc5c94d4a599153c ] + +The driver registers three different types of thermal zones: For the +ASIC itself, for port modules and for gearboxes. + +Currently, all three types use the same get_trend() callback which does +not work correctly for the ASIC thermal zone. The callback assumes that +the device data is of type 'struct mlxsw_thermal_module', whereas for +the ASIC thermal zone 'struct mlxsw_thermal' is passed as device data. + +Fix this by using one get_trend() callback for the ASIC thermal zone and +another for the other two types. + +Fixes: 6f73862fabd9 ("mlxsw: core: Add the hottest thermal zone detection") +Signed-off-by: Vadim Pasternak +Reviewed-by: Jiri Pirko +Signed-off-by: Ido Schimmel +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | 23 +++++++++++++++++---- + 1 file changed, 19 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c +@@ -390,8 +390,7 @@ static int mlxsw_thermal_set_trip_hyst(s + static int mlxsw_thermal_trend_get(struct thermal_zone_device *tzdev, + int trip, enum thermal_trend *trend) + { +- struct mlxsw_thermal_module *tz = tzdev->devdata; +- struct mlxsw_thermal *thermal = tz->parent; ++ struct mlxsw_thermal *thermal = tzdev->devdata; + + if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS) + return -EINVAL; +@@ -592,6 +591,22 @@ mlxsw_thermal_module_trip_hyst_set(struc + return 0; + } + ++static int mlxsw_thermal_module_trend_get(struct thermal_zone_device *tzdev, ++ int trip, enum thermal_trend *trend) ++{ ++ struct mlxsw_thermal_module *tz = tzdev->devdata; ++ struct mlxsw_thermal *thermal = tz->parent; ++ ++ if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS) ++ return -EINVAL; ++ ++ if (tzdev == thermal->tz_highest_dev) ++ return 1; ++ ++ *trend = THERMAL_TREND_STABLE; ++ return 0; ++} ++ + static struct thermal_zone_device_ops mlxsw_thermal_module_ops = { + .bind = mlxsw_thermal_module_bind, + .unbind = mlxsw_thermal_module_unbind, +@@ -603,7 +618,7 @@ static struct thermal_zone_device_ops ml + .set_trip_temp = mlxsw_thermal_module_trip_temp_set, + .get_trip_hyst = mlxsw_thermal_module_trip_hyst_get, + .set_trip_hyst = mlxsw_thermal_module_trip_hyst_set, +- .get_trend = mlxsw_thermal_trend_get, ++ .get_trend = mlxsw_thermal_module_trend_get, + }; + + static int mlxsw_thermal_gearbox_temp_get(struct thermal_zone_device *tzdev, +@@ -642,7 +657,7 @@ static struct thermal_zone_device_ops ml + .set_trip_temp = mlxsw_thermal_module_trip_temp_set, + .get_trip_hyst = mlxsw_thermal_module_trip_hyst_get, + .set_trip_hyst = mlxsw_thermal_module_trip_hyst_set, +- .get_trend = mlxsw_thermal_trend_get, ++ .get_trend = mlxsw_thermal_module_trend_get, + }; + + static int mlxsw_thermal_get_max_state(struct thermal_cooling_device *cdev, diff --git a/queue-5.4/net_failover-fixed-rollback-in-net_failover_open.patch b/queue-5.4/net_failover-fixed-rollback-in-net_failover_open.patch new file mode 100644 index 00000000000..3ed07db4772 --- /dev/null +++ b/queue-5.4/net_failover-fixed-rollback-in-net_failover_open.patch @@ -0,0 +1,33 @@ +From foo@baz Thu 11 Jun 2020 12:42:45 PM CEST +From: Vasily Averin +Date: Tue, 2 Jun 2020 15:55:26 +0300 +Subject: net_failover: fixed rollback in net_failover_open() + +From: Vasily Averin + +[ Upstream commit e8224bfe77293494626f6eec1884fee7b87d0ced ] + +found by smatch: +drivers/net/net_failover.c:65 net_failover_open() error: + we previously assumed 'primary_dev' could be null (see line 43) + +Fixes: cfc80d9a1163 ("net: Introduce net_failover driver") +Signed-off-by: Vasily Averin +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/net_failover.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/net_failover.c ++++ b/drivers/net/net_failover.c +@@ -61,7 +61,8 @@ static int net_failover_open(struct net_ + return 0; + + err_standby_open: +- dev_close(primary_dev); ++ if (primary_dev) ++ dev_close(primary_dev); + err_primary_open: + netif_tx_disable(dev); + return err; diff --git a/queue-5.4/tun-correct-header-offsets-in-napi-frags-mode.patch b/queue-5.4/tun-correct-header-offsets-in-napi-frags-mode.patch new file mode 100644 index 00000000000..b1f0a2a8603 --- /dev/null +++ b/queue-5.4/tun-correct-header-offsets-in-napi-frags-mode.patch @@ -0,0 +1,65 @@ +From foo@baz Thu 11 Jun 2020 12:42:45 PM CEST +From: Willem de Bruijn +Date: Sat, 30 May 2020 15:41:31 -0400 +Subject: tun: correct header offsets in napi frags mode + +From: Willem de Bruijn + +[ Upstream commit 96aa1b22bd6bb9fccf62f6261f390ed6f3e7967f ] + +Tun in IFF_NAPI_FRAGS mode calls napi_gro_frags. Unlike netif_rx and +netif_gro_receive, this expects skb->data to point to the mac layer. + +But skb_probe_transport_header, __skb_get_hash_symmetric, and +xdp_do_generic in tun_get_user need skb->data to point to the network +header. Flow dissection also needs skb->protocol set, so +eth_type_trans has to be called. + +Ensure the link layer header lies in linear as eth_type_trans pulls +ETH_HLEN. Then take the same code paths for frags as for not frags. +Push the link layer header back just before calling napi_gro_frags. + +By pulling up to ETH_HLEN from frag0 into linear, this disables the +frag0 optimization in the special case when IFF_NAPI_FRAGS is used +with zero length iov[0] (and thus empty skb->linear). + +Fixes: 90e33d459407 ("tun: enable napi_gro_frags() for TUN/TAP driver") +Signed-off-by: Willem de Bruijn +Acked-by: Petar Penkov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/tun.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -1908,8 +1908,11 @@ drop: + skb->dev = tun->dev; + break; + case IFF_TAP: +- if (!frags) +- skb->protocol = eth_type_trans(skb, tun->dev); ++ if (frags && !pskb_may_pull(skb, ETH_HLEN)) { ++ err = -ENOMEM; ++ goto drop; ++ } ++ skb->protocol = eth_type_trans(skb, tun->dev); + break; + } + +@@ -1966,9 +1969,12 @@ drop: + } + + if (frags) { ++ u32 headlen; ++ + /* Exercise flow dissector code path. */ +- u32 headlen = eth_get_headlen(tun->dev, skb->data, +- skb_headlen(skb)); ++ skb_push(skb, ETH_HLEN); ++ headlen = eth_get_headlen(tun->dev, skb->data, ++ skb_headlen(skb)); + + if (unlikely(headlen > skb_headlen(skb))) { + this_cpu_inc(tun->pcpu_stats->rx_dropped); diff --git a/queue-5.4/vxlan-avoid-infinite-loop-when-suppressing-ns-messages-with-invalid-options.patch b/queue-5.4/vxlan-avoid-infinite-loop-when-suppressing-ns-messages-with-invalid-options.patch new file mode 100644 index 00000000000..eb03ab0def1 --- /dev/null +++ b/queue-5.4/vxlan-avoid-infinite-loop-when-suppressing-ns-messages-with-invalid-options.patch @@ -0,0 +1,48 @@ +From foo@baz Thu 11 Jun 2020 12:42:45 PM CEST +From: Ido Schimmel +Date: Mon, 1 Jun 2020 15:58:55 +0300 +Subject: vxlan: Avoid infinite loop when suppressing NS messages with invalid options + +From: Ido Schimmel + +[ Upstream commit 8066e6b449e050675df48e7c4b16c29f00507ff0 ] + +When proxy mode is enabled the vxlan device might reply to Neighbor +Solicitation (NS) messages on behalf of remote hosts. + +In case the NS message includes the "Source link-layer address" option +[1], the vxlan device will use the specified address as the link-layer +destination address in its reply. + +To avoid an infinite loop, break out of the options parsing loop when +encountering an option with length zero and disregard the NS message. + +This is consistent with the IPv6 ndisc code and RFC 4886 which states +that "Nodes MUST silently discard an ND packet that contains an option +with length zero" [2]. + +[1] https://tools.ietf.org/html/rfc4861#section-4.3 +[2] https://tools.ietf.org/html/rfc4861#section-4.6 + +Fixes: 4b29dba9c085 ("vxlan: fix nonfunctional neigh_reduce()") +Signed-off-by: Ido Schimmel +Acked-by: Nikolay Aleksandrov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/vxlan.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/net/vxlan.c ++++ b/drivers/net/vxlan.c +@@ -1924,6 +1924,10 @@ static struct sk_buff *vxlan_na_create(s + ns_olen = request->len - skb_network_offset(request) - + sizeof(struct ipv6hdr) - sizeof(*ns); + for (i = 0; i < ns_olen-1; i += (ns->opt[i+1]<<3)) { ++ if (!ns->opt[i + 1]) { ++ kfree_skb(reply); ++ return NULL; ++ } + if (ns->opt[i] == ND_OPT_SOURCE_LL_ADDR) { + daddr = ns->opt + i + sizeof(struct nd_opt_hdr); + break;