From: Greg Kroah-Hartman Date: Mon, 2 Sep 2019 16:30:12 +0000 (+0200) Subject: 5.2-stable patches X-Git-Tag: v4.4.191~50 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8e60272ede63d967e0ca40cc854ca156b0c43865;p=thirdparty%2Fkernel%2Fstable-queue.git 5.2-stable patches added patches: ipv4-icmp-fix-rt-dst-dev-null-pointer-dereference.patch ipv4-mpls-fix-mpls_xmit-for-iptunnel.patch ipv6-addrconf-allow-adding-multicast-addr-if-ifa_f_mcautojoin-is-set.patch ipv6-fix-return-value-of-ipv6_mc_may_pull-for-malformed-packets.patch net-cpsw-fix-null-pointer-exception-in-the-probe-error-path.patch net-fix-__ip_mc_inc_group-usage.patch net-smc-make-sure-epollout-is-raised.patch openvswitch-fix-conntrack-cache-with-timeout.patch tcp-make-sure-epollout-wont-be-missed.patch xfrm-xfrm_policy-fix-dst-dev-null-pointer-dereference-in-collect_md-mode.patch --- diff --git a/queue-5.2/ipv4-icmp-fix-rt-dst-dev-null-pointer-dereference.patch b/queue-5.2/ipv4-icmp-fix-rt-dst-dev-null-pointer-dereference.patch new file mode 100644 index 00000000000..b48464079f7 --- /dev/null +++ b/queue-5.2/ipv4-icmp-fix-rt-dst-dev-null-pointer-dereference.patch @@ -0,0 +1,61 @@ +From foo@baz Mon 02 Sep 2019 06:29:06 PM CEST +From: Hangbin Liu +Date: Thu, 22 Aug 2019 22:19:48 +0800 +Subject: ipv4/icmp: fix rt dst dev null pointer dereference + +From: Hangbin Liu + +[ Upstream commit e2c693934194fd3b4e795635934883354c06ebc9 ] + +In __icmp_send() there is a possibility that the rt->dst.dev is NULL, +e,g, with tunnel collect_md mode, which will cause kernel crash. +Here is what the code path looks like, for GRE: + +- ip6gre_tunnel_xmit + - ip6gre_xmit_ipv4 + - __gre6_xmit + - ip6_tnl_xmit + - if skb->len - t->tun_hlen - eth_hlen > mtu; return -EMSGSIZE + - icmp_send + - net = dev_net(rt->dst.dev); <-- here + +The reason is __metadata_dst_init() init dst->dev to NULL by default. +We could not fix it in __metadata_dst_init() as there is no dev supplied. +On the other hand, the reason we need rt->dst.dev is to get the net. +So we can just try get it from skb->dev when rt->dst.dev is NULL. + +v4: Julian Anastasov remind skb->dev also could be NULL. We'd better +still use dst.dev and do a check to avoid crash. + +v3: No changes. + +v2: fix the issue in __icmp_send() instead of updating shared dst dev +in {ip_md, ip6}_tunnel_xmit. + +Fixes: c8b34e680a09 ("ip_tunnel: Add tnl_update_pmtu in ip_md_tunnel_xmit") +Signed-off-by: Hangbin Liu +Reviewed-by: Julian Anastasov +Acked-by: Jonathan Lemon +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/icmp.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/net/ipv4/icmp.c ++++ b/net/ipv4/icmp.c +@@ -582,7 +582,13 @@ void __icmp_send(struct sk_buff *skb_in, + + if (!rt) + goto out; +- net = dev_net(rt->dst.dev); ++ ++ if (rt->dst.dev) ++ net = dev_net(rt->dst.dev); ++ else if (skb_in->dev) ++ net = dev_net(skb_in->dev); ++ else ++ goto out; + + /* + * Find the original header. It is expected to be valid, of course. diff --git a/queue-5.2/ipv4-mpls-fix-mpls_xmit-for-iptunnel.patch b/queue-5.2/ipv4-mpls-fix-mpls_xmit-for-iptunnel.patch new file mode 100644 index 00000000000..2fb5a748920 --- /dev/null +++ b/queue-5.2/ipv4-mpls-fix-mpls_xmit-for-iptunnel.patch @@ -0,0 +1,44 @@ +From foo@baz Mon 02 Sep 2019 06:29:06 PM CEST +From: Alexey Kodanev +Date: Fri, 23 Aug 2019 20:51:43 +0300 +Subject: ipv4: mpls: fix mpls_xmit for iptunnel + +From: Alexey Kodanev + +[ Upstream commit 803f3e22ae10003a83c781498c0ac34cfe3463ff ] + +When using mpls over gre/gre6 setup, rt->rt_gw4 address is not set, the +same for rt->rt_gw_family. Therefore, when rt->rt_gw_family is checked +in mpls_xmit(), neigh_xmit() call is skipped. As a result, such setup +doesn't work anymore. + +This issue was found with LTP mpls03 tests. + +Fixes: 1550c171935d ("ipv4: Prepare rtable for IPv6 gateway") +Signed-off-by: Alexey Kodanev +Reviewed-by: David Ahern +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/mpls/mpls_iptunnel.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/net/mpls/mpls_iptunnel.c ++++ b/net/mpls/mpls_iptunnel.c +@@ -133,12 +133,12 @@ static int mpls_xmit(struct sk_buff *skb + mpls_stats_inc_outucastpkts(out_dev, skb); + + if (rt) { +- if (rt->rt_gw_family == AF_INET) +- err = neigh_xmit(NEIGH_ARP_TABLE, out_dev, &rt->rt_gw4, +- skb); +- else if (rt->rt_gw_family == AF_INET6) ++ if (rt->rt_gw_family == AF_INET6) + err = neigh_xmit(NEIGH_ND_TABLE, out_dev, &rt->rt_gw6, + skb); ++ else ++ err = neigh_xmit(NEIGH_ARP_TABLE, out_dev, &rt->rt_gw4, ++ skb); + } else if (rt6) { + if (ipv6_addr_v4mapped(&rt6->rt6i_gateway)) { + /* 6PE (RFC 4798) */ diff --git a/queue-5.2/ipv6-addrconf-allow-adding-multicast-addr-if-ifa_f_mcautojoin-is-set.patch b/queue-5.2/ipv6-addrconf-allow-adding-multicast-addr-if-ifa_f_mcautojoin-is-set.patch new file mode 100644 index 00000000000..ebd03138bc6 --- /dev/null +++ b/queue-5.2/ipv6-addrconf-allow-adding-multicast-addr-if-ifa_f_mcautojoin-is-set.patch @@ -0,0 +1,59 @@ +From foo@baz Mon 02 Sep 2019 06:29:06 PM CEST +From: Hangbin Liu +Date: Tue, 20 Aug 2019 10:19:47 +0800 +Subject: ipv6/addrconf: allow adding multicast addr if IFA_F_MCAUTOJOIN is set + +From: Hangbin Liu + +[ Upstream commit f17f7648a49aa6728649ddf79bdbcac4f1970ce4 ] + +In commit 93a714d6b53d ("multicast: Extend ip address command to enable +multicast group join/leave on") we added a new flag IFA_F_MCAUTOJOIN +to make user able to add multicast address on ethernet interface. + +This works for IPv4, but not for IPv6. See the inet6_addr_add code. + +static int inet6_addr_add() +{ + ... + if (cfg->ifa_flags & IFA_F_MCAUTOJOIN) { + ipv6_mc_config(net->ipv6.mc_autojoin_sk, true...) + } + + ifp = ipv6_add_addr(idev, cfg, true, extack); <- always fail with maddr + if (!IS_ERR(ifp)) { + ... + } else if (cfg->ifa_flags & IFA_F_MCAUTOJOIN) { + ipv6_mc_config(net->ipv6.mc_autojoin_sk, false...) + } +} + +But in ipv6_add_addr() it will check the address type and reject multicast +address directly. So this feature is never worked for IPv6. + +We should not remove the multicast address check totally in ipv6_add_addr(), +but could accept multicast address only when IFA_F_MCAUTOJOIN flag supplied. + +v2: update commit description + +Fixes: 93a714d6b53d ("multicast: Extend ip address command to enable multicast group join/leave on") +Reported-by: Jianlin Shi +Signed-off-by: Hangbin Liu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/addrconf.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -1045,7 +1045,8 @@ ipv6_add_addr(struct inet6_dev *idev, st + int err = 0; + + if (addr_type == IPV6_ADDR_ANY || +- addr_type & IPV6_ADDR_MULTICAST || ++ (addr_type & IPV6_ADDR_MULTICAST && ++ !(cfg->ifa_flags & IFA_F_MCAUTOJOIN)) || + (!(idev->dev->flags & IFF_LOOPBACK) && + !netif_is_l3_master(idev->dev) && + addr_type & IPV6_ADDR_LOOPBACK)) diff --git a/queue-5.2/ipv6-fix-return-value-of-ipv6_mc_may_pull-for-malformed-packets.patch b/queue-5.2/ipv6-fix-return-value-of-ipv6_mc_may_pull-for-malformed-packets.patch new file mode 100644 index 00000000000..ef80205b80f --- /dev/null +++ b/queue-5.2/ipv6-fix-return-value-of-ipv6_mc_may_pull-for-malformed-packets.patch @@ -0,0 +1,44 @@ +From foo@baz Mon 02 Sep 2019 06:29:06 PM CEST +From: Stefano Brivio +Date: Tue, 13 Aug 2019 00:46:01 +0200 +Subject: ipv6: Fix return value of ipv6_mc_may_pull() for malformed packets + +From: Stefano Brivio + +Commit ba5ea614622d ("bridge: simplify ip_mc_check_igmp() and +ipv6_mc_check_mld() calls") replaces direct calls to pskb_may_pull() +in br_ipv6_multicast_mld2_report() with calls to ipv6_mc_may_pull(), +that returns -EINVAL on buffers too short to be valid IPv6 packets, +while maintaining the previous handling of the return code. + +This leads to the direct opposite of the intended effect: if the +packet is malformed, -EINVAL evaluates as true, and we'll happily +proceed with the processing. + +Return 0 if the packet is too short, in the same way as this was +fixed for IPv4 by commit 083b78a9ed64 ("ip: fix ip_mc_may_pull() +return value"). + +I don't have a reproducer for this, unlike the one referred to by +the IPv4 commit, but this is clearly broken. + +Fixes: ba5ea614622d ("bridge: simplify ip_mc_check_igmp() and ipv6_mc_check_mld() calls") +Signed-off-by: Stefano Brivio +Acked-by: Guillaume Nault +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/addrconf.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/net/addrconf.h ++++ b/include/net/addrconf.h +@@ -206,7 +206,7 @@ static inline int ipv6_mc_may_pull(struc + unsigned int len) + { + if (skb_transport_offset(skb) + ipv6_transport_len(skb) < len) +- return -EINVAL; ++ return 0; + + return pskb_may_pull(skb, len); + } diff --git a/queue-5.2/net-cpsw-fix-null-pointer-exception-in-the-probe-error-path.patch b/queue-5.2/net-cpsw-fix-null-pointer-exception-in-the-probe-error-path.patch new file mode 100644 index 00000000000..7687165865f --- /dev/null +++ b/queue-5.2/net-cpsw-fix-null-pointer-exception-in-the-probe-error-path.patch @@ -0,0 +1,43 @@ +From foo@baz Mon 02 Sep 2019 06:29:06 PM CEST +From: Antoine Tenart +Date: Wed, 21 Aug 2019 16:41:23 +0200 +Subject: net: cpsw: fix NULL pointer exception in the probe error path + +From: Antoine Tenart + +[ Upstream commit 2d683eaaeeb9d33d23674ae635e0ef1448523d18 ] + +In certain cases when the probe function fails the error path calls +cpsw_remove_dt() before calling platform_set_drvdata(). This is an +issue as cpsw_remove_dt() uses platform_get_drvdata() to retrieve the +cpsw_common data and leds to a NULL pointer exception. This patches +fixes it by calling platform_set_drvdata() earlier in the probe. + +Fixes: 83a8471ba255 ("net: ethernet: ti: cpsw: refactor probe to group common hw initialization") +Reported-by: Maxime Chevallier +Signed-off-by: Antoine Tenart +Reviewed-by: Grygorii Strashko +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/ti/cpsw.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/ti/cpsw.c ++++ b/drivers/net/ethernet/ti/cpsw.c +@@ -2372,6 +2372,7 @@ static int cpsw_probe(struct platform_de + if (!cpsw) + return -ENOMEM; + ++ platform_set_drvdata(pdev, cpsw); + cpsw->dev = dev; + + mode = devm_gpiod_get_array_optional(dev, "mode", GPIOD_OUT_LOW); +@@ -2476,7 +2477,6 @@ static int cpsw_probe(struct platform_de + goto clean_cpts; + } + +- platform_set_drvdata(pdev, ndev); + priv = netdev_priv(ndev); + priv->cpsw = cpsw; + priv->ndev = ndev; diff --git a/queue-5.2/net-fix-__ip_mc_inc_group-usage.patch b/queue-5.2/net-fix-__ip_mc_inc_group-usage.patch new file mode 100644 index 00000000000..da7de38fcba --- /dev/null +++ b/queue-5.2/net-fix-__ip_mc_inc_group-usage.patch @@ -0,0 +1,45 @@ +From foo@baz Mon 02 Sep 2019 06:29:06 PM CEST +From: Li RongQing +Date: Tue, 20 Aug 2019 13:52:47 +0800 +Subject: net: fix __ip_mc_inc_group usage + +From: Li RongQing + +[ Upstream commit a1c4cd67840ef80f6ca5f73326fa9a6719303a95 ] + +in ip_mc_inc_group, memory allocation flag, not mcast mode, is expected +by __ip_mc_inc_group + +similar issue in __ip_mc_join_group, both mcase mode and gfp_t are needed +here, so use ____ip_mc_inc_group(...) + +Fixes: 9fb20801dab4 ("net: Fix ip_mc_{dec,inc}_group allocation context") +Signed-off-by: Li RongQing +Signed-off-by: Florian Fainelli +Signed-off-by: Zhang Yu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/igmp.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/ipv4/igmp.c ++++ b/net/ipv4/igmp.c +@@ -1474,7 +1474,7 @@ EXPORT_SYMBOL(__ip_mc_inc_group); + + void ip_mc_inc_group(struct in_device *in_dev, __be32 addr) + { +- __ip_mc_inc_group(in_dev, addr, MCAST_EXCLUDE); ++ __ip_mc_inc_group(in_dev, addr, GFP_KERNEL); + } + EXPORT_SYMBOL(ip_mc_inc_group); + +@@ -2196,7 +2196,7 @@ static int __ip_mc_join_group(struct soc + iml->sflist = NULL; + iml->sfmode = mode; + rcu_assign_pointer(inet->mc_list, iml); +- __ip_mc_inc_group(in_dev, addr, mode); ++ ____ip_mc_inc_group(in_dev, addr, mode, GFP_KERNEL); + err = 0; + done: + return err; diff --git a/queue-5.2/net-smc-make-sure-epollout-is-raised.patch b/queue-5.2/net-smc-make-sure-epollout-is-raised.patch new file mode 100644 index 00000000000..8d11a566be0 --- /dev/null +++ b/queue-5.2/net-smc-make-sure-epollout-is-raised.patch @@ -0,0 +1,53 @@ +From foo@baz Mon 02 Sep 2019 06:29:06 PM CEST +From: Jason Baron +Date: Mon, 19 Aug 2019 14:36:01 -0400 +Subject: net/smc: make sure EPOLLOUT is raised + +From: Jason Baron + +[ Upstream commit 4651d1802f7063e4d8c0bcad957f46ece0c04024 ] + +Currently, we are only explicitly setting SOCK_NOSPACE on a write timeout +for non-blocking sockets. Epoll() edge-trigger mode relies on SOCK_NOSPACE +being set when -EAGAIN is returned to ensure that EPOLLOUT is raised. +Expand the setting of SOCK_NOSPACE to non-blocking sockets as well that can +use SO_SNDTIMEO to adjust their write timeout. This mirrors the behavior +that Eric Dumazet introduced for tcp sockets. + +Signed-off-by: Jason Baron +Cc: Eric Dumazet +Cc: Ursula Braun +Cc: Karsten Graul +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/smc/smc_tx.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/net/smc/smc_tx.c ++++ b/net/smc/smc_tx.c +@@ -76,13 +76,11 @@ static int smc_tx_wait(struct smc_sock * + DEFINE_WAIT_FUNC(wait, woken_wake_function); + struct smc_connection *conn = &smc->conn; + struct sock *sk = &smc->sk; +- bool noblock; + long timeo; + int rc = 0; + + /* similar to sk_stream_wait_memory */ + timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT); +- noblock = timeo ? false : true; + add_wait_queue(sk_sleep(sk), &wait); + while (1) { + sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk); +@@ -97,8 +95,8 @@ static int smc_tx_wait(struct smc_sock * + break; + } + if (!timeo) { +- if (noblock) +- set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); ++ /* ensure EPOLLOUT is subsequently generated */ ++ set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); + rc = -EAGAIN; + break; + } diff --git a/queue-5.2/openvswitch-fix-conntrack-cache-with-timeout.patch b/queue-5.2/openvswitch-fix-conntrack-cache-with-timeout.patch new file mode 100644 index 00000000000..a4407876af3 --- /dev/null +++ b/queue-5.2/openvswitch-fix-conntrack-cache-with-timeout.patch @@ -0,0 +1,61 @@ +From foo@baz Mon 02 Sep 2019 06:29:06 PM CEST +From: Yi-Hung Wei +Date: Thu, 22 Aug 2019 13:17:50 -0700 +Subject: openvswitch: Fix conntrack cache with timeout + +From: Yi-Hung Wei + +[ Upstream commit 7177895154e6a35179d332f4a584d396c50d0612 ] + +This patch addresses a conntrack cache issue with timeout policy. +Currently, we do not check if the timeout extension is set properly in the +cached conntrack entry. Thus, after packet recirculate from conntrack +action, the timeout policy is not applied properly. This patch fixes the +aforementioned issue. + +Fixes: 06bd2bdf19d2 ("openvswitch: Add timeout support to ct action") +Reported-by: kbuild test robot +Signed-off-by: Yi-Hung Wei +Acked-by: Pravin B Shelar +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/openvswitch/conntrack.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/net/openvswitch/conntrack.c ++++ b/net/openvswitch/conntrack.c +@@ -67,6 +67,7 @@ struct ovs_conntrack_info { + struct md_mark mark; + struct md_labels labels; + char timeout[CTNL_TIMEOUT_NAME_MAX]; ++ struct nf_ct_timeout *nf_ct_timeout; + #if IS_ENABLED(CONFIG_NF_NAT) + struct nf_nat_range2 range; /* Only present for SRC NAT and DST NAT. */ + #endif +@@ -697,6 +698,14 @@ static bool skb_nfct_cached(struct net * + if (help && rcu_access_pointer(help->helper) != info->helper) + return false; + } ++ if (info->nf_ct_timeout) { ++ struct nf_conn_timeout *timeout_ext; ++ ++ timeout_ext = nf_ct_timeout_find(ct); ++ if (!timeout_ext || info->nf_ct_timeout != ++ rcu_dereference(timeout_ext->timeout)) ++ return false; ++ } + /* Force conntrack entry direction to the current packet? */ + if (info->force && CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) { + /* Delete the conntrack entry if confirmed, else just release +@@ -1657,6 +1666,10 @@ int ovs_ct_copy_action(struct net *net, + ct_info.timeout)) + pr_info_ratelimited("Failed to associated timeout " + "policy `%s'\n", ct_info.timeout); ++ else ++ ct_info.nf_ct_timeout = rcu_dereference( ++ nf_ct_timeout_find(ct_info.ct)->timeout); ++ + } + + if (helper) { diff --git a/queue-5.2/series b/queue-5.2/series index c65a6ba1c93..7b956396e62 100644 --- a/queue-5.2/series +++ b/queue-5.2/series @@ -46,3 +46,13 @@ watchdog-bcm2835_wdt-fix-module-autoload.patch selftests-bpf-install-files-test_xdp_vlan.sh.patch drm-bridge-tfp410-fix-memleak-in-get_modes.patch mt76-usb-fix-rx-a-msdu-support.patch +ipv6-addrconf-allow-adding-multicast-addr-if-ifa_f_mcautojoin-is-set.patch +ipv6-fix-return-value-of-ipv6_mc_may_pull-for-malformed-packets.patch +net-cpsw-fix-null-pointer-exception-in-the-probe-error-path.patch +net-fix-__ip_mc_inc_group-usage.patch +net-smc-make-sure-epollout-is-raised.patch +tcp-make-sure-epollout-wont-be-missed.patch +ipv4-mpls-fix-mpls_xmit-for-iptunnel.patch +openvswitch-fix-conntrack-cache-with-timeout.patch +ipv4-icmp-fix-rt-dst-dev-null-pointer-dereference.patch +xfrm-xfrm_policy-fix-dst-dev-null-pointer-dereference-in-collect_md-mode.patch diff --git a/queue-5.2/tcp-make-sure-epollout-wont-be-missed.patch b/queue-5.2/tcp-make-sure-epollout-wont-be-missed.patch new file mode 100644 index 00000000000..2666f069445 --- /dev/null +++ b/queue-5.2/tcp-make-sure-epollout-wont-be-missed.patch @@ -0,0 +1,82 @@ +From foo@baz Mon 02 Sep 2019 06:29:06 PM CEST +From: Eric Dumazet +Date: Fri, 16 Aug 2019 21:26:22 -0700 +Subject: tcp: make sure EPOLLOUT wont be missed + +From: Eric Dumazet + +[ Upstream commit ef8d8ccdc216f797e66cb4a1372f5c4c285ce1e4 ] + +As Jason Baron explained in commit 790ba4566c1a ("tcp: set SOCK_NOSPACE +under memory pressure"), it is crucial we properly set SOCK_NOSPACE +when needed. + +However, Jason patch had a bug, because the 'nonblocking' status +as far as sk_stream_wait_memory() is concerned is governed +by MSG_DONTWAIT flag passed at sendmsg() time : + + long timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT); + +So it is very possible that tcp sendmsg() calls sk_stream_wait_memory(), +and that sk_stream_wait_memory() returns -EAGAIN with SOCK_NOSPACE +cleared, if sk->sk_sndtimeo has been set to a small (but not zero) +value. + +This patch removes the 'noblock' variable since we must always +set SOCK_NOSPACE if -EAGAIN is returned. + +It also renames the do_nonblock label since we might reach this +code path even if we were in blocking mode. + +Fixes: 790ba4566c1a ("tcp: set SOCK_NOSPACE under memory pressure") +Signed-off-by: Eric Dumazet +Cc: Jason Baron +Reported-by: Vladimir Rutsky +Acked-by: Soheil Hassas Yeganeh +Acked-by: Neal Cardwell +Acked-by: Jason Baron +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/stream.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +--- a/net/core/stream.c ++++ b/net/core/stream.c +@@ -120,7 +120,6 @@ int sk_stream_wait_memory(struct sock *s + int err = 0; + long vm_wait = 0; + long current_timeo = *timeo_p; +- bool noblock = (*timeo_p ? false : true); + DEFINE_WAIT_FUNC(wait, woken_wake_function); + + if (sk_stream_memory_free(sk)) +@@ -133,11 +132,8 @@ int sk_stream_wait_memory(struct sock *s + + if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) + goto do_error; +- if (!*timeo_p) { +- if (noblock) +- set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); +- goto do_nonblock; +- } ++ if (!*timeo_p) ++ goto do_eagain; + if (signal_pending(current)) + goto do_interrupted; + sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk); +@@ -169,7 +165,13 @@ out: + do_error: + err = -EPIPE; + goto out; +-do_nonblock: ++do_eagain: ++ /* Make sure that whenever EAGAIN is returned, EPOLLOUT event can ++ * be generated later. ++ * When TCP receives ACK packets that make room, tcp_check_space() ++ * only calls tcp_new_space() if SOCK_NOSPACE is set. ++ */ ++ set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); + err = -EAGAIN; + goto out; + do_interrupted: diff --git a/queue-5.2/xfrm-xfrm_policy-fix-dst-dev-null-pointer-dereference-in-collect_md-mode.patch b/queue-5.2/xfrm-xfrm_policy-fix-dst-dev-null-pointer-dereference-in-collect_md-mode.patch new file mode 100644 index 00000000000..5a25a1e568c --- /dev/null +++ b/queue-5.2/xfrm-xfrm_policy-fix-dst-dev-null-pointer-dereference-in-collect_md-mode.patch @@ -0,0 +1,70 @@ +From foo@baz Mon 02 Sep 2019 06:29:06 PM CEST +From: Hangbin Liu +Date: Thu, 22 Aug 2019 22:19:49 +0800 +Subject: xfrm/xfrm_policy: fix dst dev null pointer dereference in collect_md mode + +From: Hangbin Liu + +[ Upstream commit c3b4c3a47e05d5fecf7354d75824a9d1b37f3e84 ] + +In decode_session{4,6} there is a possibility that the skb dst dev is NULL, +e,g, with tunnel collect_md mode, which will cause kernel crash. +Here is what the code path looks like, for GRE: + +- ip6gre_tunnel_xmit + - ip6gre_xmit_ipv6 + - __gre6_xmit + - ip6_tnl_xmit + - if skb->len - t->tun_hlen - eth_hlen > mtu; return -EMSGSIZE + - icmpv6_send + - icmpv6_route_lookup + - xfrm_decode_session_reverse + - decode_session4 + - oif = skb_dst(skb)->dev->ifindex; <-- here + - decode_session6 + - oif = skb_dst(skb)->dev->ifindex; <-- here + +The reason is __metadata_dst_init() init dst->dev to NULL by default. +We could not fix it in __metadata_dst_init() as there is no dev supplied. +On the other hand, the skb_dst(skb)->dev is actually not needed as we +called decode_session{4,6} via xfrm_decode_session_reverse(), so oif is not +used by: fl4->flowi4_oif = reverse ? skb->skb_iif : oif; + +So make a dst dev check here should be clean and safe. + +v4: No changes. + +v3: No changes. + +v2: fix the issue in decode_session{4,6} instead of updating shared dst dev +in {ip_md, ip6}_tunnel_xmit. + +Fixes: 8d79266bc48c ("ip6_tunnel: add collect_md mode to IPv6 tunnels") +Signed-off-by: Hangbin Liu +Tested-by: Jonathan Lemon +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/xfrm/xfrm_policy.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/xfrm/xfrm_policy.c ++++ b/net/xfrm/xfrm_policy.c +@@ -3272,7 +3272,7 @@ decode_session4(struct sk_buff *skb, str + struct flowi4 *fl4 = &fl->u.ip4; + int oif = 0; + +- if (skb_dst(skb)) ++ if (skb_dst(skb) && skb_dst(skb)->dev) + oif = skb_dst(skb)->dev->ifindex; + + memset(fl4, 0, sizeof(struct flowi4)); +@@ -3390,7 +3390,7 @@ decode_session6(struct sk_buff *skb, str + + nexthdr = nh[nhoff]; + +- if (skb_dst(skb)) ++ if (skb_dst(skb) && skb_dst(skb)->dev) + oif = skb_dst(skb)->dev->ifindex; + + memset(fl6, 0, sizeof(struct flowi6));