From: Greg Kroah-Hartman Date: Wed, 26 Sep 2018 09:29:28 +0000 (+0200) Subject: 4.18-stable patches X-Git-Tag: v4.18.11~29 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a81a45e9b09d851fc3ab79638d182d7e5b167997;p=thirdparty%2Fkernel%2Fstable-queue.git 4.18-stable patches added patches: bnxt_en-fix-vf-mac-address-regression.patch gso_segment-reset-skb-mac_len-after-modifying-network-header.patch hv_netvsc-fix-schedule-in-rcu-context.patch ipv6-fix-possible-use-after-free-in-ip6_xmit.patch ipv6-use-rt6_info-members-when-dst-is-set-in-rt6_fill_node.patch neighbour-confirm-neigh-entries-when-arp-packet-is-received.patch net-appletalk-fix-minor-pointer-leak-to-userspace-in-siocfindipddprt.patch net-dsa-mv88e6xxx-fix-atu-miss-violation.patch net-hp100-fix-always-true-check-for-link-up-state.patch net-ipv6-do-not-copy-dst-flags-on-rt-init.patch net-mvpp2-let-phylink-manage-the-carrier-state.patch net-rtnl_configure_link-fix-dev-flags-changes-arg-to-__dev_notify_flags.patch net-sched-act_sample-fix-null-dereference-in-the-data-path.patch pppoe-fix-reception-of-frames-with-no-mac-header.patch qmi_wwan-set-dtr-for-modems-in-forced-usb2-mode.patch socket-fix-struct-ifreq-size-in-compat-ioctl.patch tls-clear-key-material-from-kernel-memory-when-do_tls_setsockopt_conf-fails.patch tls-don-t-copy-the-key-out-of-tls12_crypto_info_aes_gcm_128.patch tls-fix-currently-broken-msg_peek-behavior.patch tls-zero-the-crypto-information-from-tls_context-before-freeing.patch udp4-fix-ip_cmsg_checksum-for-connected-sockets.patch udp6-add-missing-checks-on-edumux-packet-processing.patch --- diff --git a/queue-4.18/bnxt_en-fix-vf-mac-address-regression.patch b/queue-4.18/bnxt_en-fix-vf-mac-address-regression.patch new file mode 100644 index 00000000000..f5849fa1d48 --- /dev/null +++ b/queue-4.18/bnxt_en-fix-vf-mac-address-regression.patch @@ -0,0 +1,110 @@ +From foo@baz Wed Sep 26 11:27:32 CEST 2018 +From: Michael Chan +Date: Fri, 14 Sep 2018 15:41:29 -0400 +Subject: bnxt_en: Fix VF mac address regression. + +From: Michael Chan + +[ Upstream commit 28ea334bd1657f3c43485b4a8592672fc6835fac ] + +The recent commit to always forward the VF MAC address to the PF for +approval may not work if the PF driver or the firmware is older. This +will cause the VF driver to fail during probe: + + bnxt_en 0000:00:03.0 (unnamed net_device) (uninitialized): hwrm req_type 0xf seq id 0x5 error 0xffff + bnxt_en 0000:00:03.0 (unnamed net_device) (uninitialized): VF MAC address 00:00:17:02:05:d0 not approved by the PF + bnxt_en 0000:00:03.0: Unable to initialize mac address. + bnxt_en: probe of 0000:00:03.0 failed with error -99 + +We fix it by treating the error as fatal only if the VF MAC address is +locally generated by the VF. + +Fixes: 707e7e966026 ("bnxt_en: Always forward VF MAC address to the PF.") +Reported-by: Seth Forshee +Reported-by: Siwei Liu +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 9 +++++++-- + drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c | 9 +++++---- + drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h | 2 +- + 3 files changed, 13 insertions(+), 7 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -7888,7 +7888,7 @@ static int bnxt_change_mac_addr(struct n + if (ether_addr_equal(addr->sa_data, dev->dev_addr)) + return 0; + +- rc = bnxt_approve_mac(bp, addr->sa_data); ++ rc = bnxt_approve_mac(bp, addr->sa_data, true); + if (rc) + return rc; + +@@ -8683,14 +8683,19 @@ static int bnxt_init_mac_addr(struct bnx + } else { + #ifdef CONFIG_BNXT_SRIOV + struct bnxt_vf_info *vf = &bp->vf; ++ bool strict_approval = true; + + if (is_valid_ether_addr(vf->mac_addr)) { + /* overwrite netdev dev_addr with admin VF MAC */ + memcpy(bp->dev->dev_addr, vf->mac_addr, ETH_ALEN); ++ /* Older PF driver or firmware may not approve this ++ * correctly. ++ */ ++ strict_approval = false; + } else { + eth_hw_addr_random(bp->dev); + } +- rc = bnxt_approve_mac(bp, bp->dev->dev_addr); ++ rc = bnxt_approve_mac(bp, bp->dev->dev_addr, strict_approval); + #endif + } + return rc; +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c +@@ -1095,7 +1095,7 @@ update_vf_mac_exit: + mutex_unlock(&bp->hwrm_cmd_lock); + } + +-int bnxt_approve_mac(struct bnxt *bp, u8 *mac) ++int bnxt_approve_mac(struct bnxt *bp, u8 *mac, bool strict) + { + struct hwrm_func_vf_cfg_input req = {0}; + int rc = 0; +@@ -1113,12 +1113,13 @@ int bnxt_approve_mac(struct bnxt *bp, u8 + memcpy(req.dflt_mac_addr, mac, ETH_ALEN); + rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); + mac_done: +- if (rc) { ++ if (rc && strict) { + rc = -EADDRNOTAVAIL; + netdev_warn(bp->dev, "VF MAC address %pM not approved by the PF\n", + mac); ++ return rc; + } +- return rc; ++ return 0; + } + #else + +@@ -1135,7 +1136,7 @@ void bnxt_update_vf_mac(struct bnxt *bp) + { + } + +-int bnxt_approve_mac(struct bnxt *bp, u8 *mac) ++int bnxt_approve_mac(struct bnxt *bp, u8 *mac, bool strict) + { + return 0; + } +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h +@@ -39,5 +39,5 @@ int bnxt_sriov_configure(struct pci_dev + void bnxt_sriov_disable(struct bnxt *); + void bnxt_hwrm_exec_fwd_req(struct bnxt *); + void bnxt_update_vf_mac(struct bnxt *); +-int bnxt_approve_mac(struct bnxt *, u8 *); ++int bnxt_approve_mac(struct bnxt *, u8 *, bool); + #endif diff --git a/queue-4.18/gso_segment-reset-skb-mac_len-after-modifying-network-header.patch b/queue-4.18/gso_segment-reset-skb-mac_len-after-modifying-network-header.patch new file mode 100644 index 00000000000..431b79f2158 --- /dev/null +++ b/queue-4.18/gso_segment-reset-skb-mac_len-after-modifying-network-header.patch @@ -0,0 +1,55 @@ +From foo@baz Wed Sep 26 11:27:32 CEST 2018 +From: "Toke Høiland-Jørgensen" +Date: Thu, 13 Sep 2018 16:43:07 +0200 +Subject: gso_segment: Reset skb->mac_len after modifying network header + +From: "Toke Høiland-Jørgensen" + +[ Upstream commit c56cae23c6b167acc68043c683c4573b80cbcc2c ] + +When splitting a GSO segment that consists of encapsulated packets, the +skb->mac_len of the segments can end up being set wrong, causing packet +drops in particular when using act_mirred and ifb interfaces in +combination with a qdisc that splits GSO packets. + +This happens because at the time skb_segment() is called, network_header +will point to the inner header, throwing off the calculation in +skb_reset_mac_len(). The network_header is subsequently adjust by the +outer IP gso_segment handlers, but they don't set the mac_len. + +Fix this by adding skb_reset_mac_len() calls to both the IPv4 and IPv6 +gso_segment handlers, after they modify the network_header. + +Many thanks to Eric Dumazet for his help in identifying the cause of +the bug. + +Acked-by: Dave Taht +Reviewed-by: Eric Dumazet +Signed-off-by: Toke Høiland-Jørgensen +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/af_inet.c | 1 + + net/ipv6/ip6_offload.c | 1 + + 2 files changed, 2 insertions(+) + +--- a/net/ipv4/af_inet.c ++++ b/net/ipv4/af_inet.c +@@ -1377,6 +1377,7 @@ struct sk_buff *inet_gso_segment(struct + if (encap) + skb_reset_inner_headers(skb); + skb->network_header = (u8 *)iph - skb->head; ++ skb_reset_mac_len(skb); + } while ((skb = skb->next)); + + out: +--- a/net/ipv6/ip6_offload.c ++++ b/net/ipv6/ip6_offload.c +@@ -115,6 +115,7 @@ static struct sk_buff *ipv6_gso_segment( + payload_len = skb->len - nhoff - sizeof(*ipv6h); + ipv6h->payload_len = htons(payload_len); + skb->network_header = (u8 *)ipv6h - skb->head; ++ skb_reset_mac_len(skb); + + if (udpfrag) { + int err = ip6_find_1stfragopt(skb, &prevhdr); diff --git a/queue-4.18/hv_netvsc-fix-schedule-in-rcu-context.patch b/queue-4.18/hv_netvsc-fix-schedule-in-rcu-context.patch new file mode 100644 index 00000000000..5ba87bd60e6 --- /dev/null +++ b/queue-4.18/hv_netvsc-fix-schedule-in-rcu-context.patch @@ -0,0 +1,106 @@ +From foo@baz Wed Sep 26 11:27:32 CEST 2018 +From: Stephen Hemminger +Date: Thu, 13 Sep 2018 08:03:43 -0700 +Subject: hv_netvsc: fix schedule in RCU context + +From: Stephen Hemminger + +[ Upstream commit 018349d70f28a78d5343b3660cb66e1667005f8a ] + +When netvsc device is removed it can call reschedule in RCU context. +This happens because canceling the subchannel setup work could (in theory) +cause a reschedule when manipulating the timer. + +To reproduce, run with lockdep enabled kernel and unbind +a network device from hv_netvsc (via sysfs). + +[ 160.682011] WARNING: suspicious RCU usage +[ 160.707466] 4.19.0-rc3-uio+ #2 Not tainted +[ 160.709937] ----------------------------- +[ 160.712352] ./include/linux/rcupdate.h:302 Illegal context switch in RCU read-side critical section! +[ 160.723691] +[ 160.723691] other info that might help us debug this: +[ 160.723691] +[ 160.730955] +[ 160.730955] rcu_scheduler_active = 2, debug_locks = 1 +[ 160.762813] 5 locks held by rebind-eth.sh/1812: +[ 160.766851] #0: 000000008befa37a (sb_writers#6){.+.+}, at: vfs_write+0x184/0x1b0 +[ 160.773416] #1: 00000000b097f236 (&of->mutex){+.+.}, at: kernfs_fop_write+0xe2/0x1a0 +[ 160.783766] #2: 0000000041ee6889 (kn->count#3){++++}, at: kernfs_fop_write+0xeb/0x1a0 +[ 160.787465] #3: 0000000056d92a74 (&dev->mutex){....}, at: device_release_driver_internal+0x39/0x250 +[ 160.816987] #4: 0000000030f6031e (rcu_read_lock){....}, at: netvsc_remove+0x1e/0x250 [hv_netvsc] +[ 160.828629] +[ 160.828629] stack backtrace: +[ 160.831966] CPU: 1 PID: 1812 Comm: rebind-eth.sh Not tainted 4.19.0-rc3-uio+ #2 +[ 160.832952] Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS Hyper-V UEFI Release v1.0 11/26/2012 +[ 160.832952] Call Trace: +[ 160.832952] dump_stack+0x85/0xcb +[ 160.832952] ___might_sleep+0x1a3/0x240 +[ 160.832952] __flush_work+0x57/0x2e0 +[ 160.832952] ? __mutex_lock+0x83/0x990 +[ 160.832952] ? __kernfs_remove+0x24f/0x2e0 +[ 160.832952] ? __kernfs_remove+0x1b2/0x2e0 +[ 160.832952] ? mark_held_locks+0x50/0x80 +[ 160.832952] ? get_work_pool+0x90/0x90 +[ 160.832952] __cancel_work_timer+0x13c/0x1e0 +[ 160.832952] ? netvsc_remove+0x1e/0x250 [hv_netvsc] +[ 160.832952] ? __lock_is_held+0x55/0x90 +[ 160.832952] netvsc_remove+0x9a/0x250 [hv_netvsc] +[ 160.832952] vmbus_remove+0x26/0x30 +[ 160.832952] device_release_driver_internal+0x18a/0x250 +[ 160.832952] unbind_store+0xb4/0x180 +[ 160.832952] kernfs_fop_write+0x113/0x1a0 +[ 160.832952] __vfs_write+0x36/0x1a0 +[ 160.832952] ? rcu_read_lock_sched_held+0x6b/0x80 +[ 160.832952] ? rcu_sync_lockdep_assert+0x2e/0x60 +[ 160.832952] ? __sb_start_write+0x141/0x1a0 +[ 160.832952] ? vfs_write+0x184/0x1b0 +[ 160.832952] vfs_write+0xbe/0x1b0 +[ 160.832952] ksys_write+0x55/0xc0 +[ 160.832952] do_syscall_64+0x60/0x1b0 +[ 160.832952] entry_SYSCALL_64_after_hwframe+0x49/0xbe +[ 160.832952] RIP: 0033:0x7fe48f4c8154 + +Resolve this by getting RTNL earlier. This is safe because the subchannel +work queue does trylock on RTNL and will detect the race. + +Fixes: 7b2ee50c0cd5 ("hv_netvsc: common detach logic") +Signed-off-by: Stephen Hemminger +Reviewed-by: Haiyang Zhang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/hyperv/netvsc_drv.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +--- a/drivers/net/hyperv/netvsc_drv.c ++++ b/drivers/net/hyperv/netvsc_drv.c +@@ -2172,17 +2172,15 @@ static int netvsc_remove(struct hv_devic + + cancel_delayed_work_sync(&ndev_ctx->dwork); + +- rcu_read_lock(); +- nvdev = rcu_dereference(ndev_ctx->nvdev); +- +- if (nvdev) ++ rtnl_lock(); ++ nvdev = rtnl_dereference(ndev_ctx->nvdev); ++ if (nvdev) + cancel_work_sync(&nvdev->subchan_work); + + /* + * Call to the vsc driver to let it know that the device is being + * removed. Also blocks mtu and channel changes. + */ +- rtnl_lock(); + vf_netdev = rtnl_dereference(ndev_ctx->vf_netdev); + if (vf_netdev) + netvsc_unregister_vf(vf_netdev); +@@ -2194,7 +2192,6 @@ static int netvsc_remove(struct hv_devic + list_del(&ndev_ctx->list); + + rtnl_unlock(); +- rcu_read_unlock(); + + hv_set_drvdata(dev, NULL); + diff --git a/queue-4.18/ipv6-fix-possible-use-after-free-in-ip6_xmit.patch b/queue-4.18/ipv6-fix-possible-use-after-free-in-ip6_xmit.patch new file mode 100644 index 00000000000..acbc6fe9d68 --- /dev/null +++ b/queue-4.18/ipv6-fix-possible-use-after-free-in-ip6_xmit.patch @@ -0,0 +1,41 @@ +From foo@baz Wed Sep 26 11:27:32 CEST 2018 +From: Eric Dumazet +Date: Fri, 14 Sep 2018 12:02:31 -0700 +Subject: ipv6: fix possible use-after-free in ip6_xmit() + +From: Eric Dumazet + +[ Upstream commit bbd6528d28c1b8e80832b3b018ec402b6f5c3215 ] + +In the unlikely case ip6_xmit() has to call skb_realloc_headroom(), +we need to call skb_set_owner_w() before consuming original skb, +otherwise we risk a use-after-free. + +Bring IPv6 in line with what we do in IPv4 to fix this. + +Fixes: 1da177e4c3f41 ("Linux-2.6.12-rc2") +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ip6_output.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -219,12 +219,10 @@ int ip6_xmit(const struct sock *sk, stru + kfree_skb(skb); + return -ENOBUFS; + } ++ if (skb->sk) ++ skb_set_owner_w(skb2, skb->sk); + consume_skb(skb); + skb = skb2; +- /* skb_set_owner_w() changes sk->sk_wmem_alloc atomically, +- * it is safe to call in our context (socket lock not held) +- */ +- skb_set_owner_w(skb, (struct sock *)sk); + } + if (opt->opt_flen) + ipv6_push_frag_opts(skb, opt, &proto); diff --git a/queue-4.18/ipv6-use-rt6_info-members-when-dst-is-set-in-rt6_fill_node.patch b/queue-4.18/ipv6-use-rt6_info-members-when-dst-is-set-in-rt6_fill_node.patch new file mode 100644 index 00000000000..f9a6a7fb5a0 --- /dev/null +++ b/queue-4.18/ipv6-use-rt6_info-members-when-dst-is-set-in-rt6_fill_node.patch @@ -0,0 +1,142 @@ +From foo@baz Wed Sep 26 11:27:32 CEST 2018 +From: Xin Long +Date: Tue, 11 Sep 2018 14:33:58 +0800 +Subject: ipv6: use rt6_info members when dst is set in rt6_fill_node + +From: Xin Long + +[ Upstream commit 22d0bd82cc7cec7d9ed4bd5913f3ab65643364be ] + +In inet6_rtm_getroute, since Commit 93531c674315 ("net/ipv6: separate +handling of FIB entries from dst based routes"), it has used rt->from +to dump route info instead of rt. + +However for some route like cache, some of its information like flags +or gateway is not the same as that of the 'from' one. It caused 'ip +route get' to dump the wrong route information. + +In Jianlin's testing, the output information even lost the expiration +time for a pmtu route cache due to the wrong fib6_flags. + +So change to use rt6_info members for dst addr, src addr, flags and +gateway when it tries to dump a route entry without fibmatch set. + +v1->v2: + - not use rt6i_prefsrc. + - also fix the gw dump issue. + +Fixes: 93531c674315 ("net/ipv6: separate handling of FIB entries from dst based routes") +Reported-by: Jianlin Shi +Signed-off-by: Xin Long +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/route.c | 42 ++++++++++++++++++++++++++++++------------ + 1 file changed, 30 insertions(+), 12 deletions(-) + +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -4670,20 +4670,31 @@ static int rt6_fill_node(struct net *net + int iif, int type, u32 portid, u32 seq, + unsigned int flags) + { +- struct rtmsg *rtm; ++ struct rt6_info *rt6 = (struct rt6_info *)dst; ++ struct rt6key *rt6_dst, *rt6_src; ++ u32 *pmetrics, table, rt6_flags; + struct nlmsghdr *nlh; ++ struct rtmsg *rtm; + long expires = 0; +- u32 *pmetrics; +- u32 table; + + nlh = nlmsg_put(skb, portid, seq, type, sizeof(*rtm), flags); + if (!nlh) + return -EMSGSIZE; + ++ if (rt6) { ++ rt6_dst = &rt6->rt6i_dst; ++ rt6_src = &rt6->rt6i_src; ++ rt6_flags = rt6->rt6i_flags; ++ } else { ++ rt6_dst = &rt->fib6_dst; ++ rt6_src = &rt->fib6_src; ++ rt6_flags = rt->fib6_flags; ++ } ++ + rtm = nlmsg_data(nlh); + rtm->rtm_family = AF_INET6; +- rtm->rtm_dst_len = rt->fib6_dst.plen; +- rtm->rtm_src_len = rt->fib6_src.plen; ++ rtm->rtm_dst_len = rt6_dst->plen; ++ rtm->rtm_src_len = rt6_src->plen; + rtm->rtm_tos = 0; + if (rt->fib6_table) + table = rt->fib6_table->tb6_id; +@@ -4698,7 +4709,7 @@ static int rt6_fill_node(struct net *net + rtm->rtm_scope = RT_SCOPE_UNIVERSE; + rtm->rtm_protocol = rt->fib6_protocol; + +- if (rt->fib6_flags & RTF_CACHE) ++ if (rt6_flags & RTF_CACHE) + rtm->rtm_flags |= RTM_F_CLONED; + + if (dest) { +@@ -4706,7 +4717,7 @@ static int rt6_fill_node(struct net *net + goto nla_put_failure; + rtm->rtm_dst_len = 128; + } else if (rtm->rtm_dst_len) +- if (nla_put_in6_addr(skb, RTA_DST, &rt->fib6_dst.addr)) ++ if (nla_put_in6_addr(skb, RTA_DST, &rt6_dst->addr)) + goto nla_put_failure; + #ifdef CONFIG_IPV6_SUBTREES + if (src) { +@@ -4714,12 +4725,12 @@ static int rt6_fill_node(struct net *net + goto nla_put_failure; + rtm->rtm_src_len = 128; + } else if (rtm->rtm_src_len && +- nla_put_in6_addr(skb, RTA_SRC, &rt->fib6_src.addr)) ++ nla_put_in6_addr(skb, RTA_SRC, &rt6_src->addr)) + goto nla_put_failure; + #endif + if (iif) { + #ifdef CONFIG_IPV6_MROUTE +- if (ipv6_addr_is_multicast(&rt->fib6_dst.addr)) { ++ if (ipv6_addr_is_multicast(&rt6_dst->addr)) { + int err = ip6mr_get_route(net, skb, rtm, portid); + + if (err == 0) +@@ -4754,7 +4765,14 @@ static int rt6_fill_node(struct net *net + /* For multipath routes, walk the siblings list and add + * each as a nexthop within RTA_MULTIPATH. + */ +- if (rt->fib6_nsiblings) { ++ if (rt6) { ++ if (rt6_flags & RTF_GATEWAY && ++ nla_put_in6_addr(skb, RTA_GATEWAY, &rt6->rt6i_gateway)) ++ goto nla_put_failure; ++ ++ if (dst->dev && nla_put_u32(skb, RTA_OIF, dst->dev->ifindex)) ++ goto nla_put_failure; ++ } else if (rt->fib6_nsiblings) { + struct fib6_info *sibling, *next_sibling; + struct nlattr *mp; + +@@ -4777,7 +4795,7 @@ static int rt6_fill_node(struct net *net + goto nla_put_failure; + } + +- if (rt->fib6_flags & RTF_EXPIRES) { ++ if (rt6_flags & RTF_EXPIRES) { + expires = dst ? dst->expires : rt->expires; + expires -= jiffies; + } +@@ -4785,7 +4803,7 @@ static int rt6_fill_node(struct net *net + if (rtnl_put_cacheinfo(skb, dst, 0, expires, dst ? dst->error : 0) < 0) + goto nla_put_failure; + +- if (nla_put_u8(skb, RTA_PREF, IPV6_EXTRACT_PREF(rt->fib6_flags))) ++ if (nla_put_u8(skb, RTA_PREF, IPV6_EXTRACT_PREF(rt6_flags))) + goto nla_put_failure; + + diff --git a/queue-4.18/neighbour-confirm-neigh-entries-when-arp-packet-is-received.patch b/queue-4.18/neighbour-confirm-neigh-entries-when-arp-packet-is-received.patch new file mode 100644 index 00000000000..c18cdb25757 --- /dev/null +++ b/queue-4.18/neighbour-confirm-neigh-entries-when-arp-packet-is-received.patch @@ -0,0 +1,54 @@ +From foo@baz Wed Sep 26 11:27:32 CEST 2018 +From: Vasily Khoruzhick +Date: Thu, 13 Sep 2018 11:12:03 -0700 +Subject: neighbour: confirm neigh entries when ARP packet is received + +From: Vasily Khoruzhick + +[ Upstream commit f0e0d04413fcce9bc76388839099aee93cd0d33b ] + +Update 'confirmed' timestamp when ARP packet is received. It shouldn't +affect locktime logic and anyway entry can be confirmed by any higher-layer +protocol. Thus it makes sense to confirm it when ARP packet is received. + +Fixes: 77d7123342dc ("neighbour: update neigh timestamps iff update is effective") +Signed-off-by: Vasily Khoruzhick +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/neighbour.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -1179,6 +1179,12 @@ int neigh_update(struct neighbour *neigh + lladdr = neigh->ha; + } + ++ /* Update confirmed timestamp for neighbour entry after we ++ * received ARP packet even if it doesn't change IP to MAC binding. ++ */ ++ if (new & NUD_CONNECTED) ++ neigh->confirmed = jiffies; ++ + /* If entry was valid and address is not changed, + do not change entry state, if new one is STALE. + */ +@@ -1200,15 +1206,12 @@ int neigh_update(struct neighbour *neigh + } + } + +- /* Update timestamps only once we know we will make a change to the ++ /* Update timestamp only once we know we will make a change to the + * neighbour entry. Otherwise we risk to move the locktime window with + * noop updates and ignore relevant ARP updates. + */ +- if (new != old || lladdr != neigh->ha) { +- if (new & NUD_CONNECTED) +- neigh->confirmed = jiffies; ++ if (new != old || lladdr != neigh->ha) + neigh->updated = jiffies; +- } + + if (new != old) { + neigh_del_timer(neigh); diff --git a/queue-4.18/net-appletalk-fix-minor-pointer-leak-to-userspace-in-siocfindipddprt.patch b/queue-4.18/net-appletalk-fix-minor-pointer-leak-to-userspace-in-siocfindipddprt.patch new file mode 100644 index 00000000000..347ba228a0a --- /dev/null +++ b/queue-4.18/net-appletalk-fix-minor-pointer-leak-to-userspace-in-siocfindipddprt.patch @@ -0,0 +1,40 @@ +From foo@baz Wed Sep 26 11:27:32 CEST 2018 +From: Willy Tarreau +Date: Wed, 12 Sep 2018 07:36:35 +0200 +Subject: net/appletalk: fix minor pointer leak to userspace in SIOCFINDIPDDPRT + +From: Willy Tarreau + +[ Upstream commit 9824dfae5741275473a23a7ed5756c7b6efacc9d ] + +Fields ->dev and ->next of struct ipddp_route may be copied to +userspace on the SIOCFINDIPDDPRT ioctl. This is only accessible +to CAP_NET_ADMIN though. Let's manually copy the relevant fields +instead of using memcpy(). + +BugLink: http://blog.infosectcbr.com.au/2018/09/linux-kernel-infoleaks.html +Cc: Jann Horn +Signed-off-by: Willy Tarreau +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/appletalk/ipddp.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/net/appletalk/ipddp.c ++++ b/drivers/net/appletalk/ipddp.c +@@ -283,8 +283,12 @@ static int ipddp_ioctl(struct net_device + case SIOCFINDIPDDPRT: + spin_lock_bh(&ipddp_route_lock); + rp = __ipddp_find_route(&rcp); +- if (rp) +- memcpy(&rcp2, rp, sizeof(rcp2)); ++ if (rp) { ++ memset(&rcp2, 0, sizeof(rcp2)); ++ rcp2.ip = rp->ip; ++ rcp2.at = rp->at; ++ rcp2.flags = rp->flags; ++ } + spin_unlock_bh(&ipddp_route_lock); + + if (rp) { diff --git a/queue-4.18/net-dsa-mv88e6xxx-fix-atu-miss-violation.patch b/queue-4.18/net-dsa-mv88e6xxx-fix-atu-miss-violation.patch new file mode 100644 index 00000000000..f6accc137d7 --- /dev/null +++ b/queue-4.18/net-dsa-mv88e6xxx-fix-atu-miss-violation.patch @@ -0,0 +1,43 @@ +From foo@baz Wed Sep 26 11:27:32 CEST 2018 +From: Andrew Lunn +Date: Fri, 14 Sep 2018 23:46:12 +0200 +Subject: net: dsa: mv88e6xxx: Fix ATU Miss Violation + +From: Andrew Lunn + +[ Upstream commit ddca24dfcf1bec608668dd44c45d49397b70f520 ] + +Fix a cut/paste error and a typo which results in ATU miss violations +not being reported. + +Fixes: 0977644c5005 ("net: dsa: mv88e6xxx: Decode ATU problem interrupt") +Signed-off-by: Andrew Lunn +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/dsa/mv88e6xxx/global1.h | 2 +- + drivers/net/dsa/mv88e6xxx/global1_atu.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/dsa/mv88e6xxx/global1.h ++++ b/drivers/net/dsa/mv88e6xxx/global1.h +@@ -128,7 +128,7 @@ + #define MV88E6XXX_G1_ATU_OP_GET_CLR_VIOLATION 0x7000 + #define MV88E6XXX_G1_ATU_OP_AGE_OUT_VIOLATION BIT(7) + #define MV88E6XXX_G1_ATU_OP_MEMBER_VIOLATION BIT(6) +-#define MV88E6XXX_G1_ATU_OP_MISS_VIOLTATION BIT(5) ++#define MV88E6XXX_G1_ATU_OP_MISS_VIOLATION BIT(5) + #define MV88E6XXX_G1_ATU_OP_FULL_VIOLATION BIT(4) + + /* Offset 0x0C: ATU Data Register */ +--- a/drivers/net/dsa/mv88e6xxx/global1_atu.c ++++ b/drivers/net/dsa/mv88e6xxx/global1_atu.c +@@ -349,7 +349,7 @@ static irqreturn_t mv88e6xxx_g1_atu_prob + chip->ports[entry.portvec].atu_member_violation++; + } + +- if (val & MV88E6XXX_G1_ATU_OP_MEMBER_VIOLATION) { ++ if (val & MV88E6XXX_G1_ATU_OP_MISS_VIOLATION) { + dev_err_ratelimited(chip->dev, + "ATU miss violation for %pM portvec %x\n", + entry.mac, entry.portvec); diff --git a/queue-4.18/net-hp100-fix-always-true-check-for-link-up-state.patch b/queue-4.18/net-hp100-fix-always-true-check-for-link-up-state.patch new file mode 100644 index 00000000000..e78964db7d4 --- /dev/null +++ b/queue-4.18/net-hp100-fix-always-true-check-for-link-up-state.patch @@ -0,0 +1,35 @@ +From foo@baz Wed Sep 26 11:27:32 CEST 2018 +From: Colin Ian King +Date: Fri, 14 Sep 2018 17:39:53 +0100 +Subject: net: hp100: fix always-true check for link up state + +From: Colin Ian King + +[ Upstream commit a7f38002fb69b44f8fc622ecb838665d0b8666af ] + +The operation ~(p100_inb(VG_LAN_CFG_1) & HP100_LINK_UP) returns a value +that is always non-zero and hence the wait for the link to drop always +terminates prematurely. Fix this by using a logical not operator instead +of a bitwise complement. This issue has been in the driver since +pre-2.6.12-rc2. + +Detected by CoverityScan, CID#114157 ("Logical vs. bitwise operator") + +Signed-off-by: Colin Ian King +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/hp/hp100.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/hp/hp100.c ++++ b/drivers/net/ethernet/hp/hp100.c +@@ -2634,7 +2634,7 @@ static int hp100_login_to_vg_hub(struct + /* Wait for link to drop */ + time = jiffies + (HZ / 10); + do { +- if (~(hp100_inb(VG_LAN_CFG_1) & HP100_LINK_UP_ST)) ++ if (!(hp100_inb(VG_LAN_CFG_1) & HP100_LINK_UP_ST)) + break; + if (!in_interrupt()) + schedule_timeout_interruptible(1); diff --git a/queue-4.18/net-ipv6-do-not-copy-dst-flags-on-rt-init.patch b/queue-4.18/net-ipv6-do-not-copy-dst-flags-on-rt-init.patch new file mode 100644 index 00000000000..028e856f2ba --- /dev/null +++ b/queue-4.18/net-ipv6-do-not-copy-dst-flags-on-rt-init.patch @@ -0,0 +1,43 @@ +From foo@baz Wed Sep 26 11:27:32 CEST 2018 +From: Peter Oskolkov +Date: Mon, 17 Sep 2018 10:20:53 -0700 +Subject: net/ipv6: do not copy dst flags on rt init + +From: Peter Oskolkov + +[ Upstream commit 30bfd93062814d6767e452a8f5ddcd97f7e38c7e ] + +DST_NOCOUNT in dst_entry::flags tracks whether the entry counts +toward route cache size (net->ipv6.sysctl.ip6_rt_max_size). + +If the flag is NOT set, dst_ops::pcpuc_entries counter is incremented +in dist_init() and decremented in dst_destroy(). + +This flag is tied to allocation/deallocation of dst_entry and +should not be copied from another dst/route. Otherwise it can happen +that dst_ops::pcpuc_entries counter grows until no new routes can +be allocated because the counter reached ip6_rt_max_size due to +DST_NOCOUNT not set and thus no counter decrements on gc-ed routes. + +Fixes: 3b6761d18bc1 ("net/ipv6: Move dst flags to booleans in fib entries") +Cc: David Ahern +Acked-by: Wei Wang +Signed-off-by: Peter Oskolkov +Reviewed-by: David Ahern +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/route.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -946,8 +946,6 @@ static void ip6_rt_init_dst_reject(struc + + static void ip6_rt_init_dst(struct rt6_info *rt, struct fib6_info *ort) + { +- rt->dst.flags |= fib6_info_dst_flags(ort); +- + if (ort->fib6_flags & RTF_REJECT) { + ip6_rt_init_dst_reject(rt, ort); + return; diff --git a/queue-4.18/net-mvpp2-let-phylink-manage-the-carrier-state.patch b/queue-4.18/net-mvpp2-let-phylink-manage-the-carrier-state.patch new file mode 100644 index 00000000000..41b501721db --- /dev/null +++ b/queue-4.18/net-mvpp2-let-phylink-manage-the-carrier-state.patch @@ -0,0 +1,96 @@ +From foo@baz Wed Sep 26 11:27:32 CEST 2018 +From: Antoine Tenart +Date: Fri, 14 Sep 2018 16:56:35 +0200 +Subject: net: mvpp2: let phylink manage the carrier state + +From: Antoine Tenart + +[ Upstream commit 41948ccb4a856dddacfbd4d789d4fa8663fe41bb ] + +Net drivers using phylink shouldn't mess with the link carrier +themselves and should let phylink manage it. The mvpp2 driver wasn't +following this best practice as the mac_config() function made calls to +change the link carrier state. This led to wrongly reported carrier link +state which then triggered other issues. This patch fixes this +behaviour. + +But the PPv2 driver relied on this misbehaviour in two cases: for fixed +links and when not using phylink (ACPI mode). The later was fixed by +adding an explicit call to link_up(), which when the ACPI mode will use +phylink should be removed. + +The fixed link case was relying on the mac_config() function to set the +link up, as we found an issue in phylink_start() which assumes the +carrier is off. If not, the link_up() function is never called. To fix +this, a call to netif_carrier_off() is added just before phylink_start() +so that we do not introduce a regression in the driver. + +Fixes: 4bb043262878 ("net: mvpp2: phylink support") +Reported-by: Russell King +Signed-off-by: Antoine Tenart +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 21 ++++++--------------- + 1 file changed, 6 insertions(+), 15 deletions(-) + +--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c ++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +@@ -61,6 +61,8 @@ static struct { + */ + static void mvpp2_mac_config(struct net_device *dev, unsigned int mode, + const struct phylink_link_state *state); ++static void mvpp2_mac_link_up(struct net_device *dev, unsigned int mode, ++ phy_interface_t interface, struct phy_device *phy); + + /* Queue modes */ + #define MVPP2_QDIST_SINGLE_MODE 0 +@@ -3142,6 +3144,7 @@ static void mvpp2_start_dev(struct mvpp2 + mvpp22_mode_reconfigure(port); + + if (port->phylink) { ++ netif_carrier_off(port->dev); + phylink_start(port->phylink); + } else { + /* Phylink isn't used as of now for ACPI, so the MAC has to be +@@ -3150,9 +3153,10 @@ static void mvpp2_start_dev(struct mvpp2 + */ + struct phylink_link_state state = { + .interface = port->phy_interface, +- .link = 1, + }; + mvpp2_mac_config(port->dev, MLO_AN_INBAND, &state); ++ mvpp2_mac_link_up(port->dev, MLO_AN_INBAND, port->phy_interface, ++ NULL); + } + + netif_tx_start_all_queues(port->dev); +@@ -4389,10 +4393,6 @@ static void mvpp2_mac_config(struct net_ + return; + } + +- netif_tx_stop_all_queues(port->dev); +- if (!port->has_phy) +- netif_carrier_off(port->dev); +- + /* Make sure the port is disabled when reconfiguring the mode */ + mvpp2_port_disable(port); + +@@ -4417,16 +4417,7 @@ static void mvpp2_mac_config(struct net_ + if (port->priv->hw_version == MVPP21 && port->flags & MVPP2_F_LOOPBACK) + mvpp2_port_loopback_set(port, state); + +- /* If the port already was up, make sure it's still in the same state */ +- if (state->link || !port->has_phy) { +- mvpp2_port_enable(port); +- +- mvpp2_egress_enable(port); +- mvpp2_ingress_enable(port); +- if (!port->has_phy) +- netif_carrier_on(dev); +- netif_tx_wake_all_queues(dev); +- } ++ mvpp2_port_enable(port); + } + + static void mvpp2_mac_link_up(struct net_device *dev, unsigned int mode, diff --git a/queue-4.18/net-rtnl_configure_link-fix-dev-flags-changes-arg-to-__dev_notify_flags.patch b/queue-4.18/net-rtnl_configure_link-fix-dev-flags-changes-arg-to-__dev_notify_flags.patch new file mode 100644 index 00000000000..61fc415b1db --- /dev/null +++ b/queue-4.18/net-rtnl_configure_link-fix-dev-flags-changes-arg-to-__dev_notify_flags.patch @@ -0,0 +1,35 @@ +From foo@baz Wed Sep 26 11:27:32 CEST 2018 +From: Roopa Prabhu +Date: Wed, 12 Sep 2018 13:21:48 -0700 +Subject: net: rtnl_configure_link: fix dev flags changes arg to __dev_notify_flags + +From: Roopa Prabhu + +[ Upstream commit 56a49d7048703f5ffdb84d3a0ee034108fba6850 ] + +This fix addresses https://bugzilla.kernel.org/show_bug.cgi?id=201071 + +Commit 5025f7f7d506 wrongly relied on __dev_change_flags to notify users of +dev flag changes in the case when dev->rtnl_link_state = RTNL_LINK_INITIALIZED. +Fix it by indicating flag changes explicitly to __dev_notify_flags. + +Fixes: 5025f7f7d506 ("rtnetlink: add rtnl_link_state check in rtnl_configure_link") +Reported-By: Liam mcbirnie +Signed-off-by: Roopa Prabhu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/rtnetlink.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -2760,7 +2760,7 @@ int rtnl_configure_link(struct net_devic + } + + if (dev->rtnl_link_state == RTNL_LINK_INITIALIZED) { +- __dev_notify_flags(dev, old_flags, 0U); ++ __dev_notify_flags(dev, old_flags, (old_flags ^ dev->flags)); + } else { + dev->rtnl_link_state = RTNL_LINK_INITIALIZED; + __dev_notify_flags(dev, old_flags, ~0U); diff --git a/queue-4.18/net-sched-act_sample-fix-null-dereference-in-the-data-path.patch b/queue-4.18/net-sched-act_sample-fix-null-dereference-in-the-data-path.patch new file mode 100644 index 00000000000..c26985bc766 --- /dev/null +++ b/queue-4.18/net-sched-act_sample-fix-null-dereference-in-the-data-path.patch @@ -0,0 +1,110 @@ +From foo@baz Wed Sep 26 11:27:32 CEST 2018 +From: Davide Caratti +Date: Fri, 14 Sep 2018 12:03:18 +0200 +Subject: net/sched: act_sample: fix NULL dereference in the data path + +From: Davide Caratti + +[ Upstream commit 34043d250f51368f214aed7f54c2dc29c819a8c7 ] + +Matteo reported the following splat, testing the datapath of TC 'sample': + + BUG: KASAN: null-ptr-deref in tcf_sample_act+0xc4/0x310 + Read of size 8 at addr 0000000000000000 by task nc/433 + + CPU: 0 PID: 433 Comm: nc Not tainted 4.19.0-rc3-kvm #17 + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS ?-20180531_142017-buildhw-08.phx2.fedoraproject.org-1.fc28 04/01/2014 + Call Trace: + kasan_report.cold.6+0x6c/0x2fa + tcf_sample_act+0xc4/0x310 + ? dev_hard_start_xmit+0x117/0x180 + tcf_action_exec+0xa3/0x160 + tcf_classify+0xdd/0x1d0 + htb_enqueue+0x18e/0x6b0 + ? deref_stack_reg+0x7a/0xb0 + ? htb_delete+0x4b0/0x4b0 + ? unwind_next_frame+0x819/0x8f0 + ? entry_SYSCALL_64_after_hwframe+0x44/0xa9 + __dev_queue_xmit+0x722/0xca0 + ? unwind_get_return_address_ptr+0x50/0x50 + ? netdev_pick_tx+0xe0/0xe0 + ? save_stack+0x8c/0xb0 + ? kasan_kmalloc+0xbe/0xd0 + ? __kmalloc_track_caller+0xe4/0x1c0 + ? __kmalloc_reserve.isra.45+0x24/0x70 + ? __alloc_skb+0xdd/0x2e0 + ? sk_stream_alloc_skb+0x91/0x3b0 + ? tcp_sendmsg_locked+0x71b/0x15a0 + ? tcp_sendmsg+0x22/0x40 + ? __sys_sendto+0x1b0/0x250 + ? __x64_sys_sendto+0x6f/0x80 + ? do_syscall_64+0x5d/0x150 + ? entry_SYSCALL_64_after_hwframe+0x44/0xa9 + ? __sys_sendto+0x1b0/0x250 + ? __x64_sys_sendto+0x6f/0x80 + ? do_syscall_64+0x5d/0x150 + ? entry_SYSCALL_64_after_hwframe+0x44/0xa9 + ip_finish_output2+0x495/0x590 + ? ip_copy_metadata+0x2e0/0x2e0 + ? skb_gso_validate_network_len+0x6f/0x110 + ? ip_finish_output+0x174/0x280 + __tcp_transmit_skb+0xb17/0x12b0 + ? __tcp_select_window+0x380/0x380 + tcp_write_xmit+0x913/0x1de0 + ? __sk_mem_schedule+0x50/0x80 + tcp_sendmsg_locked+0x49d/0x15a0 + ? tcp_rcv_established+0x8da/0xa30 + ? tcp_set_state+0x220/0x220 + ? clear_user+0x1f/0x50 + ? iov_iter_zero+0x1ae/0x590 + ? __fget_light+0xa0/0xe0 + tcp_sendmsg+0x22/0x40 + __sys_sendto+0x1b0/0x250 + ? __ia32_sys_getpeername+0x40/0x40 + ? _copy_to_user+0x58/0x70 + ? poll_select_copy_remaining+0x176/0x200 + ? __pollwait+0x1c0/0x1c0 + ? ktime_get_ts64+0x11f/0x140 + ? kern_select+0x108/0x150 + ? core_sys_select+0x360/0x360 + ? vfs_read+0x127/0x150 + ? kernel_write+0x90/0x90 + __x64_sys_sendto+0x6f/0x80 + do_syscall_64+0x5d/0x150 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + RIP: 0033:0x7fefef2b129d + Code: ff ff ff ff eb b6 0f 1f 80 00 00 00 00 48 8d 05 51 37 0c 00 41 89 ca 8b 00 85 c0 75 20 45 31 c9 45 31 c0 b8 2c 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 6b f3 c3 66 0f 1f 84 00 00 00 00 00 41 56 41 + RSP: 002b:00007fff2f5350c8 EFLAGS: 00000246 ORIG_RAX: 000000000000002c + RAX: ffffffffffffffda RBX: 000056118d60c120 RCX: 00007fefef2b129d + RDX: 0000000000002000 RSI: 000056118d629320 RDI: 0000000000000003 + RBP: 000056118d530370 R08: 0000000000000000 R09: 0000000000000000 + R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000002000 + R13: 000056118d5c2a10 R14: 000056118d5c2a10 R15: 000056118d5303b8 + +tcf_sample_act() tried to update its per-cpu stats, but tcf_sample_init() +forgot to allocate them, because tcf_idr_create() was called with a wrong +value of 'cpustats'. Setting it to true proved to fix the reported crash. + +Reported-by: Matteo Croce +Fixes: 65a206c01e8e ("net/sched: Change act_api and act_xxx modules to use IDR") +Fixes: 5c5670fae430 ("net/sched: Introduce sample tc action") +Tested-by: Matteo Croce +Signed-off-by: Davide Caratti +Acked-by: Jiri Pirko +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sched/act_sample.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/sched/act_sample.c ++++ b/net/sched/act_sample.c +@@ -64,7 +64,7 @@ static int tcf_sample_init(struct net *n + + if (!exists) { + ret = tcf_idr_create(tn, parm->index, est, a, +- &act_sample_ops, bind, false); ++ &act_sample_ops, bind, true); + if (ret) + return ret; + ret = ACT_P_CREATED; diff --git a/queue-4.18/pppoe-fix-reception-of-frames-with-no-mac-header.patch b/queue-4.18/pppoe-fix-reception-of-frames-with-no-mac-header.patch new file mode 100644 index 00000000000..bd7b805b728 --- /dev/null +++ b/queue-4.18/pppoe-fix-reception-of-frames-with-no-mac-header.patch @@ -0,0 +1,99 @@ +From foo@baz Wed Sep 26 11:27:32 CEST 2018 +From: Guillaume Nault +Date: Fri, 14 Sep 2018 16:28:05 +0200 +Subject: pppoe: fix reception of frames with no mac header + +From: Guillaume Nault + +[ Upstream commit 8540827ebac6b654ab2f69c8fbce9e4fbd6304a0 ] + +pppoe_rcv() needs to look back at the Ethernet header in order to +lookup the PPPoE session. Therefore we need to ensure that the mac +header is big enough to contain an Ethernet header. Otherwise +eth_hdr(skb)->h_source might access invalid data. + +================================================================== +BUG: KMSAN: uninit-value in __get_item drivers/net/ppp/pppoe.c:172 [inline] +BUG: KMSAN: uninit-value in get_item drivers/net/ppp/pppoe.c:236 [inline] +BUG: KMSAN: uninit-value in pppoe_rcv+0xcef/0x10e0 drivers/net/ppp/pppoe.c:450 +CPU: 0 PID: 4543 Comm: syz-executor355 Not tainted 4.16.0+ #87 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google +01/01/2011 +Call Trace: + __dump_stack lib/dump_stack.c:17 [inline] + dump_stack+0x185/0x1d0 lib/dump_stack.c:53 + kmsan_report+0x142/0x240 mm/kmsan/kmsan.c:1067 + __msan_warning_32+0x6c/0xb0 mm/kmsan/kmsan_instr.c:683 + __get_item drivers/net/ppp/pppoe.c:172 [inline] + get_item drivers/net/ppp/pppoe.c:236 [inline] + pppoe_rcv+0xcef/0x10e0 drivers/net/ppp/pppoe.c:450 + __netif_receive_skb_core+0x47df/0x4a90 net/core/dev.c:4562 + __netif_receive_skb net/core/dev.c:4627 [inline] + netif_receive_skb_internal+0x49d/0x630 net/core/dev.c:4701 + netif_receive_skb+0x230/0x240 net/core/dev.c:4725 + tun_rx_batched drivers/net/tun.c:1555 [inline] + tun_get_user+0x740f/0x7c60 drivers/net/tun.c:1962 + tun_chr_write_iter+0x1d4/0x330 drivers/net/tun.c:1990 + call_write_iter include/linux/fs.h:1782 [inline] + new_sync_write fs/read_write.c:469 [inline] + __vfs_write+0x7fb/0x9f0 fs/read_write.c:482 + vfs_write+0x463/0x8d0 fs/read_write.c:544 + SYSC_write+0x172/0x360 fs/read_write.c:589 + SyS_write+0x55/0x80 fs/read_write.c:581 + do_syscall_64+0x309/0x430 arch/x86/entry/common.c:287 + entry_SYSCALL_64_after_hwframe+0x3d/0xa2 +RIP: 0033:0x4447c9 +RSP: 002b:00007fff64c8fc28 EFLAGS: 00000297 ORIG_RAX: 0000000000000001 +RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00000000004447c9 +RDX: 000000000000fd87 RSI: 0000000020000600 RDI: 0000000000000004 +RBP: 00000000006cf018 R08: 00007fff64c8fda8 R09: 00007fff00006bda +R10: 0000000000005fe7 R11: 0000000000000297 R12: 00000000004020d0 +R13: 0000000000402160 R14: 0000000000000000 R15: 0000000000000000 + +Uninit was created at: + kmsan_save_stack_with_flags mm/kmsan/kmsan.c:278 [inline] + kmsan_internal_poison_shadow+0xb8/0x1b0 mm/kmsan/kmsan.c:188 + kmsan_kmalloc+0x94/0x100 mm/kmsan/kmsan.c:314 + kmsan_slab_alloc+0x11/0x20 mm/kmsan/kmsan.c:321 + slab_post_alloc_hook mm/slab.h:445 [inline] + slab_alloc_node mm/slub.c:2737 [inline] + __kmalloc_node_track_caller+0xaed/0x11c0 mm/slub.c:4369 + __kmalloc_reserve net/core/skbuff.c:138 [inline] + __alloc_skb+0x2cf/0x9f0 net/core/skbuff.c:206 + alloc_skb include/linux/skbuff.h:984 [inline] + alloc_skb_with_frags+0x1d4/0xb20 net/core/skbuff.c:5234 + sock_alloc_send_pskb+0xb56/0x1190 net/core/sock.c:2085 + tun_alloc_skb drivers/net/tun.c:1532 [inline] + tun_get_user+0x2242/0x7c60 drivers/net/tun.c:1829 + tun_chr_write_iter+0x1d4/0x330 drivers/net/tun.c:1990 + call_write_iter include/linux/fs.h:1782 [inline] + new_sync_write fs/read_write.c:469 [inline] + __vfs_write+0x7fb/0x9f0 fs/read_write.c:482 + vfs_write+0x463/0x8d0 fs/read_write.c:544 + SYSC_write+0x172/0x360 fs/read_write.c:589 + SyS_write+0x55/0x80 fs/read_write.c:581 + do_syscall_64+0x309/0x430 arch/x86/entry/common.c:287 + entry_SYSCALL_64_after_hwframe+0x3d/0xa2 +================================================================== + +Fixes: 224cf5ad14c0 ("ppp: Move the PPP drivers") +Reported-by: syzbot+f5f6080811c849739212@syzkaller.appspotmail.com +Signed-off-by: Guillaume Nault +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ppp/pppoe.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/net/ppp/pppoe.c ++++ b/drivers/net/ppp/pppoe.c +@@ -429,6 +429,9 @@ static int pppoe_rcv(struct sk_buff *skb + if (!skb) + goto out; + ++ if (skb_mac_header_len(skb) < ETH_HLEN) ++ goto drop; ++ + if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr))) + goto drop; + diff --git a/queue-4.18/qmi_wwan-set-dtr-for-modems-in-forced-usb2-mode.patch b/queue-4.18/qmi_wwan-set-dtr-for-modems-in-forced-usb2-mode.patch new file mode 100644 index 00000000000..f501773752e --- /dev/null +++ b/queue-4.18/qmi_wwan-set-dtr-for-modems-in-forced-usb2-mode.patch @@ -0,0 +1,55 @@ +From foo@baz Wed Sep 26 11:27:32 CEST 2018 +From: "Bjørn Mork" +Date: Mon, 17 Sep 2018 22:00:24 +0200 +Subject: qmi_wwan: set DTR for modems in forced USB2 mode + +From: "Bjørn Mork" + +[ Upstream commit 922005c7f50e7f4b2a6dbc182e9c575b4f92396b ] + +Recent firmware revisions have added the ability to force +these modems to USB2 mode, hiding their SuperSpeed +capabilities from the host. The driver has been using the +SuperSpeed capability, as shown by the bcdUSB field of the +device descriptor, to detect the need to enable the DTR +quirk. This method fails when the modems are forced to +USB2 mode by the modem firmware. + +Fix by unconditionally enabling the DTR quirk for the +affected device IDs. + +Reported-by: Fred Veldini +Reported-by: Deshu Wen +Signed-off-by: Bjørn Mork +Reported-by: Fred Veldini +Reported-by: Deshu Wen +Signed-off-by: Bjørn Mork +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/qmi_wwan.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -1206,13 +1206,13 @@ static const struct usb_device_id produc + {QMI_FIXED_INTF(0x1199, 0x9061, 8)}, /* Sierra Wireless Modem */ + {QMI_FIXED_INTF(0x1199, 0x9063, 8)}, /* Sierra Wireless EM7305 */ + {QMI_FIXED_INTF(0x1199, 0x9063, 10)}, /* Sierra Wireless EM7305 */ +- {QMI_FIXED_INTF(0x1199, 0x9071, 8)}, /* Sierra Wireless MC74xx */ +- {QMI_FIXED_INTF(0x1199, 0x9071, 10)}, /* Sierra Wireless MC74xx */ +- {QMI_FIXED_INTF(0x1199, 0x9079, 8)}, /* Sierra Wireless EM74xx */ +- {QMI_FIXED_INTF(0x1199, 0x9079, 10)}, /* Sierra Wireless EM74xx */ +- {QMI_FIXED_INTF(0x1199, 0x907b, 8)}, /* Sierra Wireless EM74xx */ +- {QMI_FIXED_INTF(0x1199, 0x907b, 10)}, /* Sierra Wireless EM74xx */ +- {QMI_FIXED_INTF(0x1199, 0x9091, 8)}, /* Sierra Wireless EM7565 */ ++ {QMI_QUIRK_SET_DTR(0x1199, 0x9071, 8)}, /* Sierra Wireless MC74xx */ ++ {QMI_QUIRK_SET_DTR(0x1199, 0x9071, 10)},/* Sierra Wireless MC74xx */ ++ {QMI_QUIRK_SET_DTR(0x1199, 0x9079, 8)}, /* Sierra Wireless EM74xx */ ++ {QMI_QUIRK_SET_DTR(0x1199, 0x9079, 10)},/* Sierra Wireless EM74xx */ ++ {QMI_QUIRK_SET_DTR(0x1199, 0x907b, 8)}, /* Sierra Wireless EM74xx */ ++ {QMI_QUIRK_SET_DTR(0x1199, 0x907b, 10)},/* Sierra Wireless EM74xx */ ++ {QMI_QUIRK_SET_DTR(0x1199, 0x9091, 8)}, /* Sierra Wireless EM7565 */ + {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ + {QMI_FIXED_INTF(0x1bbb, 0x0203, 2)}, /* Alcatel L800MA */ + {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ diff --git a/queue-4.18/socket-fix-struct-ifreq-size-in-compat-ioctl.patch b/queue-4.18/socket-fix-struct-ifreq-size-in-compat-ioctl.patch new file mode 100644 index 00000000000..a55fc7429dd --- /dev/null +++ b/queue-4.18/socket-fix-struct-ifreq-size-in-compat-ioctl.patch @@ -0,0 +1,108 @@ +From foo@baz Wed Sep 26 11:27:32 CEST 2018 +From: Johannes Berg +Date: Thu, 13 Sep 2018 14:40:55 +0200 +Subject: socket: fix struct ifreq size in compat ioctl + +From: Johannes Berg + +[ Upstream commit 1cebf8f143c21eb422cd0f4e27ab2ae366eb4d04 ] + +As reported by Reobert O'Callahan, since Viro's commit to kill +dev_ifsioc() we attempt to copy too much data in compat mode, +which may lead to EFAULT when the 32-bit version of struct ifreq +sits at/near the end of a page boundary, and the next page isn't +mapped. + +Fix this by passing the approprate compat/non-compat size to copy +and using that, as before the dev_ifsioc() removal. This works +because only the embedded "struct ifmap" has different size, and +this is only used in SIOCGIFMAP/SIOCSIFMAP which has a different +handler. All other parts of the union are naturally compatible. + +This fixes https://bugzilla.kernel.org/show_bug.cgi?id=199469. + +Fixes: bf4405737f9f ("kill dev_ifsioc()") +Reported-by: Robert O'Callahan +Signed-off-by: Johannes Berg +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/socket.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +--- a/net/socket.c ++++ b/net/socket.c +@@ -962,7 +962,8 @@ void dlci_ioctl_set(int (*hook) (unsigne + EXPORT_SYMBOL(dlci_ioctl_set); + + static long sock_do_ioctl(struct net *net, struct socket *sock, +- unsigned int cmd, unsigned long arg) ++ unsigned int cmd, unsigned long arg, ++ unsigned int ifreq_size) + { + int err; + void __user *argp = (void __user *)arg; +@@ -988,11 +989,11 @@ static long sock_do_ioctl(struct net *ne + } else { + struct ifreq ifr; + bool need_copyout; +- if (copy_from_user(&ifr, argp, sizeof(struct ifreq))) ++ if (copy_from_user(&ifr, argp, ifreq_size)) + return -EFAULT; + err = dev_ioctl(net, cmd, &ifr, &need_copyout); + if (!err && need_copyout) +- if (copy_to_user(argp, &ifr, sizeof(struct ifreq))) ++ if (copy_to_user(argp, &ifr, ifreq_size)) + return -EFAULT; + } + return err; +@@ -1091,7 +1092,8 @@ static long sock_ioctl(struct file *file + err = open_related_ns(&net->ns, get_net_ns); + break; + default: +- err = sock_do_ioctl(net, sock, cmd, arg); ++ err = sock_do_ioctl(net, sock, cmd, arg, ++ sizeof(struct ifreq)); + break; + } + return err; +@@ -2762,7 +2764,8 @@ static int do_siocgstamp(struct net *net + int err; + + set_fs(KERNEL_DS); +- err = sock_do_ioctl(net, sock, cmd, (unsigned long)&ktv); ++ err = sock_do_ioctl(net, sock, cmd, (unsigned long)&ktv, ++ sizeof(struct compat_ifreq)); + set_fs(old_fs); + if (!err) + err = compat_put_timeval(&ktv, up); +@@ -2778,7 +2781,8 @@ static int do_siocgstampns(struct net *n + int err; + + set_fs(KERNEL_DS); +- err = sock_do_ioctl(net, sock, cmd, (unsigned long)&kts); ++ err = sock_do_ioctl(net, sock, cmd, (unsigned long)&kts, ++ sizeof(struct compat_ifreq)); + set_fs(old_fs); + if (!err) + err = compat_put_timespec(&kts, up); +@@ -3084,7 +3088,8 @@ static int routing_ioctl(struct net *net + } + + set_fs(KERNEL_DS); +- ret = sock_do_ioctl(net, sock, cmd, (unsigned long) r); ++ ret = sock_do_ioctl(net, sock, cmd, (unsigned long) r, ++ sizeof(struct compat_ifreq)); + set_fs(old_fs); + + out: +@@ -3197,7 +3202,8 @@ static int compat_sock_ioctl_trans(struc + case SIOCBONDSETHWADDR: + case SIOCBONDCHANGEACTIVE: + case SIOCGIFNAME: +- return sock_do_ioctl(net, sock, cmd, arg); ++ return sock_do_ioctl(net, sock, cmd, arg, ++ sizeof(struct compat_ifreq)); + } + + return -ENOIOCTLCMD; diff --git a/queue-4.18/tls-clear-key-material-from-kernel-memory-when-do_tls_setsockopt_conf-fails.patch b/queue-4.18/tls-clear-key-material-from-kernel-memory-when-do_tls_setsockopt_conf-fails.patch new file mode 100644 index 00000000000..7e92be96777 --- /dev/null +++ b/queue-4.18/tls-clear-key-material-from-kernel-memory-when-do_tls_setsockopt_conf-fails.patch @@ -0,0 +1,29 @@ +From foo@baz Wed Sep 26 11:27:32 CEST 2018 +From: Sabrina Dubroca +Date: Wed, 12 Sep 2018 17:44:43 +0200 +Subject: tls: clear key material from kernel memory when do_tls_setsockopt_conf fails + +From: Sabrina Dubroca + +[ Upstream commit c844eb46b7d43c2cf760169df5ae1d5b033af338 ] + +Fixes: 3c4d7559159b ("tls: kernel TLS support") +Signed-off-by: Sabrina Dubroca +Signed-off-by: Sabrina Dubroca +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/tls/tls_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/tls/tls_main.c ++++ b/net/tls/tls_main.c +@@ -502,7 +502,7 @@ static int do_tls_setsockopt_conf(struct + goto out; + + err_crypto_info: +- memset(crypto_info, 0, sizeof(*crypto_info)); ++ memzero_explicit(crypto_info, sizeof(union tls_crypto_context)); + out: + return rc; + } diff --git a/queue-4.18/tls-don-t-copy-the-key-out-of-tls12_crypto_info_aes_gcm_128.patch b/queue-4.18/tls-don-t-copy-the-key-out-of-tls12_crypto_info_aes_gcm_128.patch new file mode 100644 index 00000000000..fb0144fe9e4 --- /dev/null +++ b/queue-4.18/tls-don-t-copy-the-key-out-of-tls12_crypto_info_aes_gcm_128.patch @@ -0,0 +1,41 @@ +From foo@baz Wed Sep 26 11:27:32 CEST 2018 +From: Sabrina Dubroca +Date: Wed, 12 Sep 2018 17:44:41 +0200 +Subject: tls: don't copy the key out of tls12_crypto_info_aes_gcm_128 + +From: Sabrina Dubroca + +[ Upstream commit 7cba09c6d5bc73ebbd25a353742d9ddb7a713b95 ] + +There's no need to copy the key to an on-stack buffer before calling +crypto_aead_setkey(). + +Fixes: 3c4d7559159b ("tls: kernel TLS support") +Signed-off-by: Sabrina Dubroca +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/tls/tls_sw.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +--- a/net/tls/tls_sw.c ++++ b/net/tls/tls_sw.c +@@ -1064,7 +1064,6 @@ void tls_sw_free_resources_rx(struct soc + + int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx) + { +- char keyval[TLS_CIPHER_AES_GCM_128_KEY_SIZE]; + struct tls_crypto_info *crypto_info; + struct tls12_crypto_info_aes_gcm_128 *gcm_128_info; + struct tls_sw_context_tx *sw_ctx_tx = NULL; +@@ -1184,9 +1183,7 @@ int tls_set_sw_offload(struct sock *sk, + + ctx->push_pending_record = tls_sw_push_pending_record; + +- memcpy(keyval, gcm_128_info->key, TLS_CIPHER_AES_GCM_128_KEY_SIZE); +- +- rc = crypto_aead_setkey(*aead, keyval, ++ rc = crypto_aead_setkey(*aead, gcm_128_info->key, + TLS_CIPHER_AES_GCM_128_KEY_SIZE); + if (rc) + goto free_aead; diff --git a/queue-4.18/tls-fix-currently-broken-msg_peek-behavior.patch b/queue-4.18/tls-fix-currently-broken-msg_peek-behavior.patch new file mode 100644 index 00000000000..55638080da6 --- /dev/null +++ b/queue-4.18/tls-fix-currently-broken-msg_peek-behavior.patch @@ -0,0 +1,88 @@ +From foo@baz Wed Sep 26 11:27:32 CEST 2018 +From: Daniel Borkmann +Date: Fri, 14 Sep 2018 23:00:55 +0200 +Subject: tls: fix currently broken MSG_PEEK behavior + +From: Daniel Borkmann + +[ Upstream commit 50c6b58a814d86a93c0f6964570f839632854044 ] + +In kTLS MSG_PEEK behavior is currently failing, strace example: + + [pid 2430] socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 3 + [pid 2430] socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 4 + [pid 2430] bind(4, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("0.0.0.0")}, 16) = 0 + [pid 2430] listen(4, 10) = 0 + [pid 2430] getsockname(4, {sa_family=AF_INET, sin_port=htons(38855), sin_addr=inet_addr("0.0.0.0")}, [16]) = 0 + [pid 2430] connect(3, {sa_family=AF_INET, sin_port=htons(38855), sin_addr=inet_addr("0.0.0.0")}, 16) = 0 + [pid 2430] setsockopt(3, SOL_TCP, 0x1f /* TCP_??? */, [7564404], 4) = 0 + [pid 2430] setsockopt(3, 0x11a /* SOL_?? */, 1, "\3\0033\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 40) = 0 + [pid 2430] accept(4, {sa_family=AF_INET, sin_port=htons(49636), sin_addr=inet_addr("127.0.0.1")}, [16]) = 5 + [pid 2430] setsockopt(5, SOL_TCP, 0x1f /* TCP_??? */, [7564404], 4) = 0 + [pid 2430] setsockopt(5, 0x11a /* SOL_?? */, 2, "\3\0033\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 40) = 0 + [pid 2430] close(4) = 0 + [pid 2430] sendto(3, "test_read_peek", 14, 0, NULL, 0) = 14 + [pid 2430] sendto(3, "_mult_recs\0", 11, 0, NULL, 0) = 11 + [pid 2430] recvfrom(5, "test_read_peektest_read_peektest"..., 64, MSG_PEEK, NULL, NULL) = 64 + +As can be seen from strace, there are two TLS records sent, +i) 'test_read_peek' and ii) '_mult_recs\0' where we end up +peeking 'test_read_peektest_read_peektest'. This is clearly +wrong, and what happens is that given peek cannot call into +tls_sw_advance_skb() to unpause strparser and proceed with +the next skb, we end up looping over the current one, copying +the 'test_read_peek' over and over into the user provided +buffer. + +Here, we can only peek into the currently held skb (current, +full TLS record) as otherwise we would end up having to hold +all the original skb(s) (depending on the peek depth) in a +separate queue when unpausing strparser to process next +records, minimally intrusive is to return only up to the +current record's size (which likely was what c46234ebb4d1 +("tls: RX path for ktls") originally intended as well). Thus, +after patch we properly peek the first record: + + [pid 2046] wait4(2075, + [pid 2075] socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 3 + [pid 2075] socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 4 + [pid 2075] bind(4, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("0.0.0.0")}, 16) = 0 + [pid 2075] listen(4, 10) = 0 + [pid 2075] getsockname(4, {sa_family=AF_INET, sin_port=htons(55115), sin_addr=inet_addr("0.0.0.0")}, [16]) = 0 + [pid 2075] connect(3, {sa_family=AF_INET, sin_port=htons(55115), sin_addr=inet_addr("0.0.0.0")}, 16) = 0 + [pid 2075] setsockopt(3, SOL_TCP, 0x1f /* TCP_??? */, [7564404], 4) = 0 + [pid 2075] setsockopt(3, 0x11a /* SOL_?? */, 1, "\3\0033\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 40) = 0 + [pid 2075] accept(4, {sa_family=AF_INET, sin_port=htons(45732), sin_addr=inet_addr("127.0.0.1")}, [16]) = 5 + [pid 2075] setsockopt(5, SOL_TCP, 0x1f /* TCP_??? */, [7564404], 4) = 0 + [pid 2075] setsockopt(5, 0x11a /* SOL_?? */, 2, "\3\0033\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 40) = 0 + [pid 2075] close(4) = 0 + [pid 2075] sendto(3, "test_read_peek", 14, 0, NULL, 0) = 14 + [pid 2075] sendto(3, "_mult_recs\0", 11, 0, NULL, 0) = 11 + [pid 2075] recvfrom(5, "test_read_peek", 64, MSG_PEEK, NULL, NULL) = 14 + +Fixes: c46234ebb4d1 ("tls: RX path for ktls") +Signed-off-by: Daniel Borkmann +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/tls/tls_sw.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/net/tls/tls_sw.c ++++ b/net/tls/tls_sw.c +@@ -872,7 +872,15 @@ fallback_to_reg_recv: + if (control != TLS_RECORD_TYPE_DATA) + goto recv_end; + } ++ } else { ++ /* MSG_PEEK right now cannot look beyond current skb ++ * from strparser, meaning we cannot advance skb here ++ * and thus unpause strparser since we'd loose original ++ * one. ++ */ ++ break; + } ++ + /* If we have a new message from strparser, continue now. */ + if (copied >= target && !ctx->recv_pkt) + break; diff --git a/queue-4.18/tls-zero-the-crypto-information-from-tls_context-before-freeing.patch b/queue-4.18/tls-zero-the-crypto-information-from-tls_context-before-freeing.patch new file mode 100644 index 00000000000..b5345c2ae26 --- /dev/null +++ b/queue-4.18/tls-zero-the-crypto-information-from-tls_context-before-freeing.patch @@ -0,0 +1,181 @@ +From foo@baz Wed Sep 26 11:27:32 CEST 2018 +From: Sabrina Dubroca +Date: Wed, 12 Sep 2018 17:44:42 +0200 +Subject: tls: zero the crypto information from tls_context before freeing + +From: Sabrina Dubroca + +[ Upstream commit 86029d10af18381814881d6cce2dd6872163b59f ] + +This contains key material in crypto_send_aes_gcm_128 and +crypto_recv_aes_gcm_128. + +Introduce union tls_crypto_context, and replace the two identical +unions directly embedded in struct tls_context with it. We can then +use this union to clean up the memory in the new tls_ctx_free() +function. + +Fixes: 3c4d7559159b ("tls: kernel TLS support") +Signed-off-by: Sabrina Dubroca +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/tls.h | 19 +++++++++---------- + net/tls/tls_device.c | 4 ++-- + net/tls/tls_device_fallback.c | 2 +- + net/tls/tls_main.c | 20 +++++++++++++++----- + net/tls/tls_sw.c | 8 ++++---- + 5 files changed, 31 insertions(+), 22 deletions(-) + +--- a/include/net/tls.h ++++ b/include/net/tls.h +@@ -165,15 +165,14 @@ struct cipher_context { + char *rec_seq; + }; + ++union tls_crypto_context { ++ struct tls_crypto_info info; ++ struct tls12_crypto_info_aes_gcm_128 aes_gcm_128; ++}; ++ + struct tls_context { +- union { +- struct tls_crypto_info crypto_send; +- struct tls12_crypto_info_aes_gcm_128 crypto_send_aes_gcm_128; +- }; +- union { +- struct tls_crypto_info crypto_recv; +- struct tls12_crypto_info_aes_gcm_128 crypto_recv_aes_gcm_128; +- }; ++ union tls_crypto_context crypto_send; ++ union tls_crypto_context crypto_recv; + + struct list_head list; + struct net_device *netdev; +@@ -337,8 +336,8 @@ static inline void tls_fill_prepend(stru + * size KTLS_DTLS_HEADER_SIZE + KTLS_DTLS_NONCE_EXPLICIT_SIZE + */ + buf[0] = record_type; +- buf[1] = TLS_VERSION_MINOR(ctx->crypto_send.version); +- buf[2] = TLS_VERSION_MAJOR(ctx->crypto_send.version); ++ buf[1] = TLS_VERSION_MINOR(ctx->crypto_send.info.version); ++ buf[2] = TLS_VERSION_MAJOR(ctx->crypto_send.info.version); + /* we can use IV for nonce explicit according to spec */ + buf[3] = pkt_len >> 8; + buf[4] = pkt_len & 0xFF; +--- a/net/tls/tls_device.c ++++ b/net/tls/tls_device.c +@@ -552,7 +552,7 @@ int tls_set_device_offload(struct sock * + goto free_marker_record; + } + +- crypto_info = &ctx->crypto_send; ++ crypto_info = &ctx->crypto_send.info; + switch (crypto_info->cipher_type) { + case TLS_CIPHER_AES_GCM_128: + nonce_size = TLS_CIPHER_AES_GCM_128_IV_SIZE; +@@ -650,7 +650,7 @@ int tls_set_device_offload(struct sock * + + ctx->priv_ctx_tx = offload_ctx; + rc = netdev->tlsdev_ops->tls_dev_add(netdev, sk, TLS_OFFLOAD_CTX_DIR_TX, +- &ctx->crypto_send, ++ &ctx->crypto_send.info, + tcp_sk(sk)->write_seq); + if (rc) + goto release_netdev; +--- a/net/tls/tls_device_fallback.c ++++ b/net/tls/tls_device_fallback.c +@@ -320,7 +320,7 @@ static struct sk_buff *tls_enc_skb(struc + goto free_req; + + iv = buf; +- memcpy(iv, tls_ctx->crypto_send_aes_gcm_128.salt, ++ memcpy(iv, tls_ctx->crypto_send.aes_gcm_128.salt, + TLS_CIPHER_AES_GCM_128_SALT_SIZE); + aad = buf + TLS_CIPHER_AES_GCM_128_SALT_SIZE + + TLS_CIPHER_AES_GCM_128_IV_SIZE; +--- a/net/tls/tls_main.c ++++ b/net/tls/tls_main.c +@@ -245,6 +245,16 @@ static void tls_write_space(struct sock + ctx->sk_write_space(sk); + } + ++static void tls_ctx_free(struct tls_context *ctx) ++{ ++ if (!ctx) ++ return; ++ ++ memzero_explicit(&ctx->crypto_send, sizeof(ctx->crypto_send)); ++ memzero_explicit(&ctx->crypto_recv, sizeof(ctx->crypto_recv)); ++ kfree(ctx); ++} ++ + static void tls_sk_proto_close(struct sock *sk, long timeout) + { + struct tls_context *ctx = tls_get_ctx(sk); +@@ -295,7 +305,7 @@ static void tls_sk_proto_close(struct so + #else + { + #endif +- kfree(ctx); ++ tls_ctx_free(ctx); + ctx = NULL; + } + +@@ -306,7 +316,7 @@ skip_tx_cleanup: + * for sk->sk_prot->unhash [tls_hw_unhash] + */ + if (free_ctx) +- kfree(ctx); ++ tls_ctx_free(ctx); + } + + static int do_tls_getsockopt_tx(struct sock *sk, char __user *optval, +@@ -331,7 +341,7 @@ static int do_tls_getsockopt_tx(struct s + } + + /* get user crypto info */ +- crypto_info = &ctx->crypto_send; ++ crypto_info = &ctx->crypto_send.info; + + if (!TLS_CRYPTO_INFO_READY(crypto_info)) { + rc = -EBUSY; +@@ -418,9 +428,9 @@ static int do_tls_setsockopt_conf(struct + } + + if (tx) +- crypto_info = &ctx->crypto_send; ++ crypto_info = &ctx->crypto_send.info; + else +- crypto_info = &ctx->crypto_recv; ++ crypto_info = &ctx->crypto_recv.info; + + /* Currently we don't support set crypto info more than one time */ + if (TLS_CRYPTO_INFO_READY(crypto_info)) { +--- a/net/tls/tls_sw.c ++++ b/net/tls/tls_sw.c +@@ -989,8 +989,8 @@ static int tls_read_size(struct strparse + goto read_failure; + } + +- if (header[1] != TLS_VERSION_MINOR(tls_ctx->crypto_recv.version) || +- header[2] != TLS_VERSION_MAJOR(tls_ctx->crypto_recv.version)) { ++ if (header[1] != TLS_VERSION_MINOR(tls_ctx->crypto_recv.info.version) || ++ header[2] != TLS_VERSION_MAJOR(tls_ctx->crypto_recv.info.version)) { + ret = -EINVAL; + goto read_failure; + } +@@ -1099,11 +1099,11 @@ int tls_set_sw_offload(struct sock *sk, + } + + if (tx) { +- crypto_info = &ctx->crypto_send; ++ crypto_info = &ctx->crypto_send.info; + cctx = &ctx->tx; + aead = &sw_ctx_tx->aead_send; + } else { +- crypto_info = &ctx->crypto_recv; ++ crypto_info = &ctx->crypto_recv.info; + cctx = &ctx->rx; + aead = &sw_ctx_rx->aead_recv; + } diff --git a/queue-4.18/udp4-fix-ip_cmsg_checksum-for-connected-sockets.patch b/queue-4.18/udp4-fix-ip_cmsg_checksum-for-connected-sockets.patch new file mode 100644 index 00000000000..c70c285041e --- /dev/null +++ b/queue-4.18/udp4-fix-ip_cmsg_checksum-for-connected-sockets.patch @@ -0,0 +1,99 @@ +From foo@baz Wed Sep 26 11:27:32 CEST 2018 +From: Paolo Abeni +Date: Thu, 13 Sep 2018 16:27:20 +0200 +Subject: udp4: fix IP_CMSG_CHECKSUM for connected sockets + +From: Paolo Abeni + +[ Upstream commit 2b5a921740a55c00223a797d075b9c77c42cb171 ] + +commit 2abb7cdc0dc8 ("udp: Add support for doing checksum +unnecessary conversion") left out the early demux path for +connected sockets. As a result IP_CMSG_CHECKSUM gives wrong +values for such socket when GRO is not enabled/available. + +This change addresses the issue by moving the csum conversion to a +common helper and using such helper in both the default and the +early demux rx path. + +Fixes: 2abb7cdc0dc8 ("udp: Add support for doing checksum unnecessary conversion") +Signed-off-by: Paolo Abeni +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/udp.c | 49 ++++++++++++++++++++++++++----------------------- + 1 file changed, 26 insertions(+), 23 deletions(-) + +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -2128,6 +2128,28 @@ static inline int udp4_csum_init(struct + inet_compute_pseudo); + } + ++/* wrapper for udp_queue_rcv_skb tacking care of csum conversion and ++ * return code conversion for ip layer consumption ++ */ ++static int udp_unicast_rcv_skb(struct sock *sk, struct sk_buff *skb, ++ struct udphdr *uh) ++{ ++ int ret; ++ ++ if (inet_get_convert_csum(sk) && uh->check && !IS_UDPLITE(sk)) ++ skb_checksum_try_convert(skb, IPPROTO_UDP, uh->check, ++ inet_compute_pseudo); ++ ++ ret = udp_queue_rcv_skb(sk, skb); ++ ++ /* a return value > 0 means to resubmit the input, but ++ * it wants the return to be -protocol, or 0 ++ */ ++ if (ret > 0) ++ return -ret; ++ return 0; ++} ++ + /* + * All we need to do is get the socket, and then do a checksum. + */ +@@ -2174,14 +2196,9 @@ int __udp4_lib_rcv(struct sk_buff *skb, + if (unlikely(sk->sk_rx_dst != dst)) + udp_sk_rx_dst_set(sk, dst); + +- ret = udp_queue_rcv_skb(sk, skb); ++ ret = udp_unicast_rcv_skb(sk, skb, uh); + sock_put(sk); +- /* a return value > 0 means to resubmit the input, but +- * it wants the return to be -protocol, or 0 +- */ +- if (ret > 0) +- return -ret; +- return 0; ++ return ret; + } + + if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST)) +@@ -2189,22 +2206,8 @@ int __udp4_lib_rcv(struct sk_buff *skb, + saddr, daddr, udptable, proto); + + sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable); +- if (sk) { +- int ret; +- +- if (inet_get_convert_csum(sk) && uh->check && !IS_UDPLITE(sk)) +- skb_checksum_try_convert(skb, IPPROTO_UDP, uh->check, +- inet_compute_pseudo); +- +- ret = udp_queue_rcv_skb(sk, skb); +- +- /* a return value > 0 means to resubmit the input, but +- * it wants the return to be -protocol, or 0 +- */ +- if (ret > 0) +- return -ret; +- return 0; +- } ++ if (sk) ++ return udp_unicast_rcv_skb(sk, skb, uh); + + if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) + goto drop; diff --git a/queue-4.18/udp6-add-missing-checks-on-edumux-packet-processing.patch b/queue-4.18/udp6-add-missing-checks-on-edumux-packet-processing.patch new file mode 100644 index 00000000000..27100834776 --- /dev/null +++ b/queue-4.18/udp6-add-missing-checks-on-edumux-packet-processing.patch @@ -0,0 +1,127 @@ +From foo@baz Wed Sep 26 11:27:32 CEST 2018 +From: Paolo Abeni +Date: Thu, 13 Sep 2018 16:27:21 +0200 +Subject: udp6: add missing checks on edumux packet processing + +From: Paolo Abeni + +[ Upstream commit eb63f2964dbe36f26deac77d3016791675821ded ] + +Currently the UDPv6 early demux rx code path lacks some mandatory +checks, already implemented into the normal RX code path - namely +the checksum conversion and no_check6_rx check. + +Similar to the previous commit, we move the common processing to +an UDPv6 specific helper and call it from both edemux code path +and normal code path. In respect to the UDPv4, we need to add an +explicit check for non zero csum according to no_check6_rx value. + +Reported-by: Jianlin Shi +Suggested-by: Xin Long +Fixes: c9f2c1ae123a ("udp6: fix socket leak on early demux") +Fixes: 2abb7cdc0dc8 ("udp: Add support for doing checksum unnecessary conversion") +Signed-off-by: Paolo Abeni +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/udp.c | 65 ++++++++++++++++++++++++++++++++------------------------- + 1 file changed, 37 insertions(+), 28 deletions(-) + +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -748,6 +748,28 @@ static void udp6_sk_rx_dst_set(struct so + } + } + ++/* wrapper for udp_queue_rcv_skb tacking care of csum conversion and ++ * return code conversion for ip layer consumption ++ */ ++static int udp6_unicast_rcv_skb(struct sock *sk, struct sk_buff *skb, ++ struct udphdr *uh) ++{ ++ int ret; ++ ++ if (inet_get_convert_csum(sk) && uh->check && !IS_UDPLITE(sk)) ++ skb_checksum_try_convert(skb, IPPROTO_UDP, uh->check, ++ ip6_compute_pseudo); ++ ++ ret = udpv6_queue_rcv_skb(sk, skb); ++ ++ /* a return value > 0 means to resubmit the input, but ++ * it wants the return to be -protocol, or 0 ++ */ ++ if (ret > 0) ++ return -ret; ++ return 0; ++} ++ + int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, + int proto) + { +@@ -799,13 +821,14 @@ int __udp6_lib_rcv(struct sk_buff *skb, + if (unlikely(sk->sk_rx_dst != dst)) + udp6_sk_rx_dst_set(sk, dst); + +- ret = udpv6_queue_rcv_skb(sk, skb); +- sock_put(sk); ++ if (!uh->check && !udp_sk(sk)->no_check6_rx) { ++ sock_put(sk); ++ goto report_csum_error; ++ } + +- /* a return value > 0 means to resubmit the input */ +- if (ret > 0) +- return ret; +- return 0; ++ ret = udp6_unicast_rcv_skb(sk, skb, uh); ++ sock_put(sk); ++ return ret; + } + + /* +@@ -818,30 +841,13 @@ int __udp6_lib_rcv(struct sk_buff *skb, + /* Unicast */ + sk = __udp6_lib_lookup_skb(skb, uh->source, uh->dest, udptable); + if (sk) { +- int ret; +- +- if (!uh->check && !udp_sk(sk)->no_check6_rx) { +- udp6_csum_zero_error(skb); +- goto csum_error; +- } +- +- if (inet_get_convert_csum(sk) && uh->check && !IS_UDPLITE(sk)) +- skb_checksum_try_convert(skb, IPPROTO_UDP, uh->check, +- ip6_compute_pseudo); +- +- ret = udpv6_queue_rcv_skb(sk, skb); +- +- /* a return value > 0 means to resubmit the input */ +- if (ret > 0) +- return ret; +- +- return 0; ++ if (!uh->check && !udp_sk(sk)->no_check6_rx) ++ goto report_csum_error; ++ return udp6_unicast_rcv_skb(sk, skb, uh); + } + +- if (!uh->check) { +- udp6_csum_zero_error(skb); +- goto csum_error; +- } ++ if (!uh->check) ++ goto report_csum_error; + + if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) + goto discard; +@@ -862,6 +868,9 @@ short_packet: + ulen, skb->len, + daddr, ntohs(uh->dest)); + goto discard; ++ ++report_csum_error: ++ udp6_csum_zero_error(skb); + csum_error: + __UDP6_INC_STATS(net, UDP_MIB_CSUMERRORS, proto == IPPROTO_UDPLITE); + discard: