From: Greg Kroah-Hartman Date: Fri, 4 Jan 2019 18:33:36 +0000 (+0100) Subject: 4.20-stable patches X-Git-Tag: v4.9.149~71 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f0fcd8fbfe7dd84b8fa58f6db48d61143036cecd;p=thirdparty%2Fkernel%2Fstable-queue.git 4.20-stable patches added patches: ax25-fix-a-use-after-free-in-ax25_fillin_cb.patch bnx2x-fix-null-pointer-dereference-in-bnx2x_del_all_vlans-on-some-hw.patch ibmveth-fix-dma-unmap-error-in-ibmveth_xmit_start-error-path.patch ieee802154-lowpan_header_create-check-must-check-daddr.patch ip-validate-header-length-on-virtual-device-xmit.patch isdn-fix-kernel-infoleak-in-capi_unlocked_ioctl.patch net-core-fix-spectre-v1-vulnerability.patch net-hamradio-6pack-use-mod_timer-to-rearm-timers.patch net-wan-fix-a-double-free-in-x25_asy_open_tty.patch netrom-fix-locking-in-nr_find_socket.patch packet-validate-address-length-if-non-zero.patch phonet-af_phonet-fix-spectre-v1-vulnerability.patch ptr_ring-wrap-back-producer-in-__ptr_ring_swap_queue.patch sock-make-sock-sk_stamp-thread-safe.patch tap-call-skb_probe_transport_header-after-setting-skb-dev.patch tipc-fix-a-double-free-in-tipc_enable_bearer.patch --- diff --git a/queue-4.20/ax25-fix-a-use-after-free-in-ax25_fillin_cb.patch b/queue-4.20/ax25-fix-a-use-after-free-in-ax25_fillin_cb.patch new file mode 100644 index 00000000000..0b0fdb4a1a3 --- /dev/null +++ b/queue-4.20/ax25-fix-a-use-after-free-in-ax25_fillin_cb.patch @@ -0,0 +1,73 @@ +From foo@baz Fri Jan 4 19:32:29 CET 2019 +From: Cong Wang +Date: Sat, 29 Dec 2018 13:56:36 -0800 +Subject: ax25: fix a use-after-free in ax25_fillin_cb() + +From: Cong Wang + +[ Upstream commit c433570458e49bccea5c551df628d058b3526289 ] + +There are multiple issues here: + +1. After freeing dev->ax25_ptr, we need to set it to NULL otherwise + we may use a dangling pointer. + +2. There is a race between ax25_setsockopt() and device notifier as + reported by syzbot. Close it by holding RTNL lock. + +3. We need to test if dev->ax25_ptr is NULL before using it. + +Reported-and-tested-by: syzbot+ae6bb869cbed29b29040@syzkaller.appspotmail.com +Signed-off-by: Cong Wang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ax25/af_ax25.c | 11 +++++++++-- + net/ax25/ax25_dev.c | 2 ++ + 2 files changed, 11 insertions(+), 2 deletions(-) + +--- a/net/ax25/af_ax25.c ++++ b/net/ax25/af_ax25.c +@@ -653,15 +653,22 @@ static int ax25_setsockopt(struct socket + break; + } + +- dev = dev_get_by_name(&init_net, devname); ++ rtnl_lock(); ++ dev = __dev_get_by_name(&init_net, devname); + if (!dev) { ++ rtnl_unlock(); + res = -ENODEV; + break; + } + + ax25->ax25_dev = ax25_dev_ax25dev(dev); ++ if (!ax25->ax25_dev) { ++ rtnl_unlock(); ++ res = -ENODEV; ++ break; ++ } + ax25_fillin_cb(ax25, ax25->ax25_dev); +- dev_put(dev); ++ rtnl_unlock(); + break; + + default: +--- a/net/ax25/ax25_dev.c ++++ b/net/ax25/ax25_dev.c +@@ -116,6 +116,7 @@ void ax25_dev_device_down(struct net_dev + if ((s = ax25_dev_list) == ax25_dev) { + ax25_dev_list = s->next; + spin_unlock_bh(&ax25_dev_lock); ++ dev->ax25_ptr = NULL; + dev_put(dev); + kfree(ax25_dev); + return; +@@ -125,6 +126,7 @@ void ax25_dev_device_down(struct net_dev + if (s->next == ax25_dev) { + s->next = ax25_dev->next; + spin_unlock_bh(&ax25_dev_lock); ++ dev->ax25_ptr = NULL; + dev_put(dev); + kfree(ax25_dev); + return; diff --git a/queue-4.20/bnx2x-fix-null-pointer-dereference-in-bnx2x_del_all_vlans-on-some-hw.patch b/queue-4.20/bnx2x-fix-null-pointer-dereference-in-bnx2x_del_all_vlans-on-some-hw.patch new file mode 100644 index 00000000000..39e8179d34e --- /dev/null +++ b/queue-4.20/bnx2x-fix-null-pointer-dereference-in-bnx2x_del_all_vlans-on-some-hw.patch @@ -0,0 +1,103 @@ +From foo@baz Fri Jan 4 19:32:29 CET 2019 +From: Ivan Mironov +Date: Mon, 24 Dec 2018 20:13:05 +0500 +Subject: bnx2x: Fix NULL pointer dereference in bnx2x_del_all_vlans() on some hw + +From: Ivan Mironov + +[ Upstream commit 38355a5f9a22bfa5bd5b1bb79805aca39fa53729 ] + +This happened when I tried to boot normal Fedora 29 system with latest +available kernel (from fedora rawhide, plus some unrelated custom +patches): + + BUG: unable to handle kernel NULL pointer dereference at 0000000000000000 + PGD 0 P4D 0 + Oops: 0010 [#1] SMP PTI + CPU: 6 PID: 1422 Comm: libvirtd Tainted: G I 4.20.0-0.rc7.git3.hpsa2.1.fc29.x86_64 #1 + Hardware name: HP ProLiant BL460c G6, BIOS I24 05/21/2018 + RIP: 0010: (null) + Code: Bad RIP value. + RSP: 0018:ffffa47ccdc9fbe0 EFLAGS: 00010246 + RAX: 0000000000000000 RBX: 00000000000003e8 RCX: ffffa47ccdc9fbf8 + RDX: ffffa47ccdc9fc00 RSI: ffff97d9ee7b01f8 RDI: ffff97d9f0150b80 + RBP: ffff97d9f0150b80 R08: 0000000000000000 R09: 0000000000000000 + R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000003 + R13: ffff97d9ef1e53e8 R14: 0000000000000009 R15: ffff97d9f0ac6730 + FS: 00007f4d224ef700(0000) GS:ffff97d9fa200000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: ffffffffffffffd6 CR3: 00000011ece52006 CR4: 00000000000206e0 + Call Trace: + ? bnx2x_chip_cleanup+0x195/0x610 [bnx2x] + ? bnx2x_nic_unload+0x1e2/0x8f0 [bnx2x] + ? bnx2x_reload_if_running+0x24/0x40 [bnx2x] + ? bnx2x_set_features+0x79/0xa0 [bnx2x] + ? __netdev_update_features+0x244/0x9e0 + ? netlink_broadcast_filtered+0x136/0x4b0 + ? netdev_update_features+0x22/0x60 + ? dev_disable_lro+0x1c/0xe0 + ? devinet_sysctl_forward+0x1c6/0x211 + ? proc_sys_call_handler+0xab/0x100 + ? __vfs_write+0x36/0x1a0 + ? rcu_read_lock_sched_held+0x79/0x80 + ? rcu_sync_lockdep_assert+0x2e/0x60 + ? __sb_start_write+0x14c/0x1b0 + ? vfs_write+0x159/0x1c0 + ? vfs_write+0xba/0x1c0 + ? ksys_write+0x52/0xc0 + ? do_syscall_64+0x60/0x1f0 + ? entry_SYSCALL_64_after_hwframe+0x49/0xbe + +After some investigation I figured out that recently added cleanup code +tries to call VLAN filtering de-initialization function which exist only +for newer hardware. Corresponding function pointer is not +set (== 0) for older hardware, namely these chips: + + #define CHIP_NUM_57710 0x164e + #define CHIP_NUM_57711 0x164f + #define CHIP_NUM_57711E 0x1650 + +And I have one of those in my test system: + + Broadcom Inc. and subsidiaries NetXtreme II BCM57711E 10-Gigabit PCIe [14e4:1650] + +Function bnx2x_init_vlan_mac_fp_objs() from +drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h decides whether to +initialize relevant pointers in bnx2x_sp_objs.vlan_obj or not. + +This regression was introduced after v4.20-rc7, and still exists in v4.20 +release. + +Fixes: 04f05230c5c13 ("bnx2x: Remove configured vlans as part of unload sequence.") +Signed-off-by: Ivan Mironov +Signed-off-by: Ivan Mironov +Acked-by: Sudarsana Kalluru +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c ++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +@@ -9360,10 +9360,16 @@ void bnx2x_chip_cleanup(struct bnx2x *bp + BNX2X_ERR("Failed to schedule DEL commands for UC MACs list: %d\n", + rc); + +- /* Remove all currently configured VLANs */ +- rc = bnx2x_del_all_vlans(bp); +- if (rc < 0) +- BNX2X_ERR("Failed to delete all VLANs\n"); ++ /* The whole *vlan_obj structure may be not initialized if VLAN ++ * filtering offload is not supported by hardware. Currently this is ++ * true for all hardware covered by CHIP_IS_E1x(). ++ */ ++ if (!CHIP_IS_E1x(bp)) { ++ /* Remove all currently configured VLANs */ ++ rc = bnx2x_del_all_vlans(bp); ++ if (rc < 0) ++ BNX2X_ERR("Failed to delete all VLANs\n"); ++ } + + /* Disable LLH */ + if (!CHIP_IS_E1(bp)) diff --git a/queue-4.20/ibmveth-fix-dma-unmap-error-in-ibmveth_xmit_start-error-path.patch b/queue-4.20/ibmveth-fix-dma-unmap-error-in-ibmveth_xmit_start-error-path.patch new file mode 100644 index 00000000000..3119fe1d9bf --- /dev/null +++ b/queue-4.20/ibmveth-fix-dma-unmap-error-in-ibmveth_xmit_start-error-path.patch @@ -0,0 +1,60 @@ +From foo@baz Fri Jan 4 19:32:29 CET 2019 +From: Tyrel Datwyler +Date: Mon, 31 Dec 2018 15:43:01 -0600 +Subject: ibmveth: fix DMA unmap error in ibmveth_xmit_start error path + +From: Tyrel Datwyler + +[ Upstream commit 756af9c642329d54f048bac2a62f829b391f6944 ] + +Commit 33a48ab105a7 ("ibmveth: Fix DMA unmap error") fixed an issue in the +normal code path of ibmveth_xmit_start() that was originally introduced by +Commit 6e8ab30ec677 ("ibmveth: Add scatter-gather support"). This original +fix missed the error path where dma_unmap_page is wrongly called on the +header portion in descs[0] which was mapped with dma_map_single. As a +result a failure to DMA map any of the frags results in a dmesg warning +when CONFIG_DMA_API_DEBUG is enabled. + +------------[ cut here ]------------ +DMA-API: ibmveth 30000002: device driver frees DMA memory with wrong function + [device address=0x000000000a430000] [size=172 bytes] [mapped as page] [unmapped as single] +WARNING: CPU: 1 PID: 8426 at kernel/dma/debug.c:1085 check_unmap+0x4fc/0xe10 +... + +... +DMA-API: Mapped at: +ibmveth_start_xmit+0x30c/0xb60 +dev_hard_start_xmit+0x100/0x450 +sch_direct_xmit+0x224/0x490 +__qdisc_run+0x20c/0x980 +__dev_queue_xmit+0x1bc/0xf20 + +This fixes the API misuse by unampping descs[0] with dma_unmap_single. + +Fixes: 6e8ab30ec677 ("ibmveth: Add scatter-gather support") +Signed-off-by: Tyrel Datwyler +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/ibm/ibmveth.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/ibm/ibmveth.c ++++ b/drivers/net/ethernet/ibm/ibmveth.c +@@ -1171,11 +1171,15 @@ out: + + map_failed_frags: + last = i+1; +- for (i = 0; i < last; i++) ++ for (i = 1; i < last; i++) + dma_unmap_page(&adapter->vdev->dev, descs[i].fields.address, + descs[i].fields.flags_len & IBMVETH_BUF_LEN_MASK, + DMA_TO_DEVICE); + ++ dma_unmap_single(&adapter->vdev->dev, ++ descs[0].fields.address, ++ descs[0].fields.flags_len & IBMVETH_BUF_LEN_MASK, ++ DMA_TO_DEVICE); + map_failed: + if (!firmware_has_feature(FW_FEATURE_CMO)) + netdev_err(netdev, "tx: unable to map xmit buffer\n"); diff --git a/queue-4.20/ieee802154-lowpan_header_create-check-must-check-daddr.patch b/queue-4.20/ieee802154-lowpan_header_create-check-must-check-daddr.patch new file mode 100644 index 00000000000..f8df7cac454 --- /dev/null +++ b/queue-4.20/ieee802154-lowpan_header_create-check-must-check-daddr.patch @@ -0,0 +1,33 @@ +From foo@baz Fri Jan 4 19:32:29 CET 2019 +From: Willem de Bruijn +Date: Sun, 23 Dec 2018 12:52:18 -0500 +Subject: ieee802154: lowpan_header_create check must check daddr + +From: Willem de Bruijn + +[ Upstream commit 40c3ff6d5e0809505a067dd423c110c5658c478c ] + +Packet sockets may call dev_header_parse with NULL daddr. Make +lowpan_header_ops.create fail. + +Fixes: 87a93e4eceb4 ("ieee802154: change needed headroom/tailroom") +Signed-off-by: Willem de Bruijn +Acked-by: Alexander Aring +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ieee802154/6lowpan/tx.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/ieee802154/6lowpan/tx.c ++++ b/net/ieee802154/6lowpan/tx.c +@@ -48,6 +48,9 @@ int lowpan_header_create(struct sk_buff + const struct ipv6hdr *hdr = ipv6_hdr(skb); + struct neighbour *n; + ++ if (!daddr) ++ return -EINVAL; ++ + /* TODO: + * if this package isn't ipv6 one, where should it be routed? + */ diff --git a/queue-4.20/ip-validate-header-length-on-virtual-device-xmit.patch b/queue-4.20/ip-validate-header-length-on-virtual-device-xmit.patch new file mode 100644 index 00000000000..eb728289352 --- /dev/null +++ b/queue-4.20/ip-validate-header-length-on-virtual-device-xmit.patch @@ -0,0 +1,315 @@ +From foo@baz Fri Jan 4 19:32:29 CET 2019 +From: Willem de Bruijn +Date: Sun, 30 Dec 2018 17:24:36 -0500 +Subject: ip: validate header length on virtual device xmit + +From: Willem de Bruijn + +[ Upstream commit cb9f1b783850b14cbd7f87d061d784a666dfba1f ] + +KMSAN detected read beyond end of buffer in vti and sit devices when +passing truncated packets with PF_PACKET. The issue affects additional +ip tunnel devices. + +Extend commit 76c0ddd8c3a6 ("ip6_tunnel: be careful when accessing the +inner header") and commit ccfec9e5cb2d ("ip_tunnel: be careful when +accessing the inner header"). + +Move the check to a separate helper and call at the start of each +ndo_start_xmit function in net/ipv4 and net/ipv6. + +Minor changes: +- convert dev_kfree_skb to kfree_skb on error path, + as dev_kfree_skb calls consume_skb which is not for error paths. +- use pskb_network_may_pull even though that is pedantic here, + as the same as pskb_may_pull for devices without llheaders. +- do not cache ipv6 hdrs if used only once + (unsafe across pskb_may_pull, was more relevant to earlier patch) + +Reported-by: syzbot +Signed-off-by: Willem de Bruijn +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/ip_tunnels.h | 20 ++++++++++++++++++++ + net/ipv4/ip_gre.c | 9 +++++++++ + net/ipv4/ip_tunnel.c | 9 --------- + net/ipv4/ip_vti.c | 12 +++++++++--- + net/ipv6/ip6_gre.c | 10 +++++++--- + net/ipv6/ip6_tunnel.c | 10 +++------- + net/ipv6/ip6_vti.c | 8 ++++---- + net/ipv6/ip6mr.c | 17 +++++++++++------ + net/ipv6/sit.c | 3 +++ + 9 files changed, 66 insertions(+), 32 deletions(-) + +--- a/include/net/ip_tunnels.h ++++ b/include/net/ip_tunnels.h +@@ -307,6 +307,26 @@ int ip_tunnel_encap_del_ops(const struct + int ip_tunnel_encap_setup(struct ip_tunnel *t, + struct ip_tunnel_encap *ipencap); + ++static inline bool pskb_inet_may_pull(struct sk_buff *skb) ++{ ++ int nhlen; ++ ++ switch (skb->protocol) { ++#if IS_ENABLED(CONFIG_IPV6) ++ case htons(ETH_P_IPV6): ++ nhlen = sizeof(struct ipv6hdr); ++ break; ++#endif ++ case htons(ETH_P_IP): ++ nhlen = sizeof(struct iphdr); ++ break; ++ default: ++ nhlen = 0; ++ } ++ ++ return pskb_network_may_pull(skb, nhlen); ++} ++ + static inline int ip_encap_hlen(struct ip_tunnel_encap *e) + { + const struct ip_tunnel_encap_ops *ops; +--- a/net/ipv4/ip_gre.c ++++ b/net/ipv4/ip_gre.c +@@ -674,6 +674,9 @@ static netdev_tx_t ipgre_xmit(struct sk_ + struct ip_tunnel *tunnel = netdev_priv(dev); + const struct iphdr *tnl_params; + ++ if (!pskb_inet_may_pull(skb)) ++ goto free_skb; ++ + if (tunnel->collect_md) { + gre_fb_xmit(skb, dev, skb->protocol); + return NETDEV_TX_OK; +@@ -717,6 +720,9 @@ static netdev_tx_t erspan_xmit(struct sk + struct ip_tunnel *tunnel = netdev_priv(dev); + bool truncate = false; + ++ if (!pskb_inet_may_pull(skb)) ++ goto free_skb; ++ + if (tunnel->collect_md) { + erspan_fb_xmit(skb, dev, skb->protocol); + return NETDEV_TX_OK; +@@ -760,6 +766,9 @@ static netdev_tx_t gre_tap_xmit(struct s + { + struct ip_tunnel *tunnel = netdev_priv(dev); + ++ if (!pskb_inet_may_pull(skb)) ++ goto free_skb; ++ + if (tunnel->collect_md) { + gre_fb_xmit(skb, dev, htons(ETH_P_TEB)); + return NETDEV_TX_OK; +--- a/net/ipv4/ip_tunnel.c ++++ b/net/ipv4/ip_tunnel.c +@@ -627,7 +627,6 @@ void ip_tunnel_xmit(struct sk_buff *skb, + const struct iphdr *tnl_params, u8 protocol) + { + struct ip_tunnel *tunnel = netdev_priv(dev); +- unsigned int inner_nhdr_len = 0; + const struct iphdr *inner_iph; + struct flowi4 fl4; + u8 tos, ttl; +@@ -637,14 +636,6 @@ void ip_tunnel_xmit(struct sk_buff *skb, + __be32 dst; + bool connected; + +- /* ensure we can access the inner net header, for several users below */ +- if (skb->protocol == htons(ETH_P_IP)) +- inner_nhdr_len = sizeof(struct iphdr); +- else if (skb->protocol == htons(ETH_P_IPV6)) +- inner_nhdr_len = sizeof(struct ipv6hdr); +- if (unlikely(!pskb_may_pull(skb, inner_nhdr_len))) +- goto tx_error; +- + inner_iph = (const struct iphdr *)skb_inner_network_header(skb); + connected = (tunnel->parms.iph.daddr != 0); + +--- a/net/ipv4/ip_vti.c ++++ b/net/ipv4/ip_vti.c +@@ -241,6 +241,9 @@ static netdev_tx_t vti_tunnel_xmit(struc + struct ip_tunnel *tunnel = netdev_priv(dev); + struct flowi fl; + ++ if (!pskb_inet_may_pull(skb)) ++ goto tx_err; ++ + memset(&fl, 0, sizeof(fl)); + + switch (skb->protocol) { +@@ -253,15 +256,18 @@ static netdev_tx_t vti_tunnel_xmit(struc + memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); + break; + default: +- dev->stats.tx_errors++; +- dev_kfree_skb(skb); +- return NETDEV_TX_OK; ++ goto tx_err; + } + + /* override mark with tunnel output key */ + fl.flowi_mark = be32_to_cpu(tunnel->parms.o_key); + + return vti_xmit(skb, dev, &fl); ++ ++tx_err: ++ dev->stats.tx_errors++; ++ kfree_skb(skb); ++ return NETDEV_TX_OK; + } + + static int vti4_err(struct sk_buff *skb, u32 info) +--- a/net/ipv6/ip6_gre.c ++++ b/net/ipv6/ip6_gre.c +@@ -879,6 +879,9 @@ static netdev_tx_t ip6gre_tunnel_xmit(st + struct net_device_stats *stats = &t->dev->stats; + int ret; + ++ if (!pskb_inet_may_pull(skb)) ++ goto tx_err; ++ + if (!ip6_tnl_xmit_ctl(t, &t->parms.laddr, &t->parms.raddr)) + goto tx_err; + +@@ -921,6 +924,9 @@ static netdev_tx_t ip6erspan_tunnel_xmit + int nhoff; + int thoff; + ++ if (!pskb_inet_may_pull(skb)) ++ goto tx_err; ++ + if (!ip6_tnl_xmit_ctl(t, &t->parms.laddr, &t->parms.raddr)) + goto tx_err; + +@@ -993,8 +999,6 @@ static netdev_tx_t ip6erspan_tunnel_xmit + goto tx_err; + } + } else { +- struct ipv6hdr *ipv6h = ipv6_hdr(skb); +- + switch (skb->protocol) { + case htons(ETH_P_IP): + memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); +@@ -1002,7 +1006,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit + &dsfield, &encap_limit); + break; + case htons(ETH_P_IPV6): +- if (ipv6_addr_equal(&t->parms.raddr, &ipv6h->saddr)) ++ if (ipv6_addr_equal(&t->parms.raddr, &ipv6_hdr(skb)->saddr)) + goto tx_err; + if (prepare_ip6gre_xmit_ipv6(skb, dev, &fl6, + &dsfield, &encap_limit)) +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -1243,10 +1243,6 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, str + u8 tproto; + int err; + +- /* ensure we can access the full inner ip header */ +- if (!pskb_may_pull(skb, sizeof(struct iphdr))) +- return -1; +- + iph = ip_hdr(skb); + memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); + +@@ -1321,9 +1317,6 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, str + u8 tproto; + int err; + +- if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h)))) +- return -1; +- + ipv6h = ipv6_hdr(skb); + tproto = READ_ONCE(t->parms.proto); + if ((tproto != IPPROTO_IPV6 && tproto != 0) || +@@ -1405,6 +1398,9 @@ ip6_tnl_start_xmit(struct sk_buff *skb, + struct net_device_stats *stats = &t->dev->stats; + int ret; + ++ if (!pskb_inet_may_pull(skb)) ++ goto tx_err; ++ + switch (skb->protocol) { + case htons(ETH_P_IP): + ret = ip4ip6_tnl_xmit(skb, dev); +--- a/net/ipv6/ip6_vti.c ++++ b/net/ipv6/ip6_vti.c +@@ -522,18 +522,18 @@ vti6_tnl_xmit(struct sk_buff *skb, struc + { + struct ip6_tnl *t = netdev_priv(dev); + struct net_device_stats *stats = &t->dev->stats; +- struct ipv6hdr *ipv6h; + struct flowi fl; + int ret; + ++ if (!pskb_inet_may_pull(skb)) ++ goto tx_err; ++ + memset(&fl, 0, sizeof(fl)); + + switch (skb->protocol) { + case htons(ETH_P_IPV6): +- ipv6h = ipv6_hdr(skb); +- + if ((t->parms.proto != IPPROTO_IPV6 && t->parms.proto != 0) || +- vti6_addr_conflict(t, ipv6h)) ++ vti6_addr_conflict(t, ipv6_hdr(skb))) + goto tx_err; + + xfrm_decode_session(skb, &fl, AF_INET6); +--- a/net/ipv6/ip6mr.c ++++ b/net/ipv6/ip6mr.c +@@ -51,6 +51,7 @@ + #include + #include + #include ++#include + + #include + +@@ -599,13 +600,12 @@ static netdev_tx_t reg_vif_xmit(struct s + .flowi6_iif = skb->skb_iif ? : LOOPBACK_IFINDEX, + .flowi6_mark = skb->mark, + }; +- int err; + +- err = ip6mr_fib_lookup(net, &fl6, &mrt); +- if (err < 0) { +- kfree_skb(skb); +- return err; +- } ++ if (!pskb_inet_may_pull(skb)) ++ goto tx_err; ++ ++ if (ip6mr_fib_lookup(net, &fl6, &mrt) < 0) ++ goto tx_err; + + read_lock(&mrt_lock); + dev->stats.tx_bytes += skb->len; +@@ -614,6 +614,11 @@ static netdev_tx_t reg_vif_xmit(struct s + read_unlock(&mrt_lock); + kfree_skb(skb); + return NETDEV_TX_OK; ++ ++tx_err: ++ dev->stats.tx_errors++; ++ kfree_skb(skb); ++ return NETDEV_TX_OK; + } + + static int reg_vif_get_iflink(const struct net_device *dev) +--- a/net/ipv6/sit.c ++++ b/net/ipv6/sit.c +@@ -1021,6 +1021,9 @@ tx_error: + static netdev_tx_t sit_tunnel_xmit(struct sk_buff *skb, + struct net_device *dev) + { ++ if (!pskb_inet_may_pull(skb)) ++ goto tx_err; ++ + switch (skb->protocol) { + case htons(ETH_P_IP): + sit_tunnel_xmit__(skb, dev, IPPROTO_IPIP); diff --git a/queue-4.20/isdn-fix-kernel-infoleak-in-capi_unlocked_ioctl.patch b/queue-4.20/isdn-fix-kernel-infoleak-in-capi_unlocked_ioctl.patch new file mode 100644 index 00000000000..2f6eefe25c4 --- /dev/null +++ b/queue-4.20/isdn-fix-kernel-infoleak-in-capi_unlocked_ioctl.patch @@ -0,0 +1,80 @@ +From foo@baz Fri Jan 4 19:32:29 CET 2019 +From: Eric Dumazet +Date: Wed, 2 Jan 2019 09:20:27 -0800 +Subject: isdn: fix kernel-infoleak in capi_unlocked_ioctl + +From: Eric Dumazet + +[ Upstream commit d63967e475ae10f286dbd35e189cb241e0b1f284 ] + +Since capi_ioctl() copies 64 bytes after calling +capi20_get_manufacturer() we need to ensure to not leak +information to user. + +BUG: KMSAN: kernel-infoleak in _copy_to_user+0x16b/0x1f0 lib/usercopy.c:32 +CPU: 0 PID: 11245 Comm: syz-executor633 Not tainted 4.20.0-rc7+ #2 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Call Trace: + __dump_stack lib/dump_stack.c:77 [inline] + dump_stack+0x173/0x1d0 lib/dump_stack.c:113 + kmsan_report+0x12e/0x2a0 mm/kmsan/kmsan.c:613 + kmsan_internal_check_memory+0x9d4/0xb00 mm/kmsan/kmsan.c:704 + kmsan_copy_to_user+0xab/0xc0 mm/kmsan/kmsan_hooks.c:601 + _copy_to_user+0x16b/0x1f0 lib/usercopy.c:32 + capi_ioctl include/linux/uaccess.h:177 [inline] + capi_unlocked_ioctl+0x1a0b/0x1bf0 drivers/isdn/capi/capi.c:939 + do_vfs_ioctl+0xebd/0x2bf0 fs/ioctl.c:46 + ksys_ioctl fs/ioctl.c:713 [inline] + __do_sys_ioctl fs/ioctl.c:720 [inline] + __se_sys_ioctl+0x1da/0x270 fs/ioctl.c:718 + __x64_sys_ioctl+0x4a/0x70 fs/ioctl.c:718 + do_syscall_64+0xbc/0xf0 arch/x86/entry/common.c:291 + entry_SYSCALL_64_after_hwframe+0x63/0xe7 +RIP: 0033:0x440019 +Code: 18 89 d0 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 fb 13 fc ff c3 66 2e 0f 1f 84 00 00 00 00 +RSP: 002b:00007ffdd4659fb8 EFLAGS: 00000213 ORIG_RAX: 0000000000000010 +RAX: ffffffffffffffda RBX: 00000000004002c8 RCX: 0000000000440019 +RDX: 0000000020000080 RSI: 00000000c0044306 RDI: 0000000000000003 +RBP: 00000000006ca018 R08: 0000000000000000 R09: 00000000004002c8 +R10: 0000000000000000 R11: 0000000000000213 R12: 00000000004018a0 +R13: 0000000000401930 R14: 0000000000000000 R15: 0000000000000000 + +Local variable description: ----data.i@capi_unlocked_ioctl +Variable was created at: + capi_ioctl drivers/isdn/capi/capi.c:747 [inline] + capi_unlocked_ioctl+0x82/0x1bf0 drivers/isdn/capi/capi.c:939 + do_vfs_ioctl+0xebd/0x2bf0 fs/ioctl.c:46 + +Bytes 12-63 of 64 are uninitialized +Memory access of size 64 starts at ffff88807ac5fce8 +Data copied to user address 0000000020000080 + +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Cc: Karsten Keil +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/isdn/capi/kcapi.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/isdn/capi/kcapi.c ++++ b/drivers/isdn/capi/kcapi.c +@@ -852,7 +852,7 @@ u16 capi20_get_manufacturer(u32 contr, u + u16 ret; + + if (contr == 0) { +- strlcpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN); ++ strncpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN); + return CAPI_NOERROR; + } + +@@ -860,7 +860,7 @@ u16 capi20_get_manufacturer(u32 contr, u + + ctr = get_capi_ctr_by_nr(contr); + if (ctr && ctr->state == CAPI_CTR_RUNNING) { +- strlcpy(buf, ctr->manu, CAPI_MANUFACTURER_LEN); ++ strncpy(buf, ctr->manu, CAPI_MANUFACTURER_LEN); + ret = CAPI_NOERROR; + } else + ret = CAPI_REGNOTINSTALLED; diff --git a/queue-4.20/net-core-fix-spectre-v1-vulnerability.patch b/queue-4.20/net-core-fix-spectre-v1-vulnerability.patch new file mode 100644 index 00000000000..572ca93cb87 --- /dev/null +++ b/queue-4.20/net-core-fix-spectre-v1-vulnerability.patch @@ -0,0 +1,55 @@ +From foo@baz Fri Jan 4 19:32:29 CET 2019 +From: "Gustavo A. R. Silva" +Date: Fri, 21 Dec 2018 14:49:01 -0600 +Subject: net: core: Fix Spectre v1 vulnerability + +From: "Gustavo A. R. Silva" + +[ Upstream commit 50d5258634aee2e62832aa086d2fb0de00e72b91 ] + +flen is indirectly controlled by user-space, hence leading to +a potential exploitation of the Spectre variant 1 vulnerability. + +This issue was detected with the help of Smatch: + +net/core/filter.c:1101 bpf_check_classic() warn: potential spectre issue 'filter' [w] + +Fix this by sanitizing flen before using it to index filter at line 1101: + + switch (filter[flen - 1].code) { + +and through pc at line 1040: + + const struct sock_filter *ftest = &filter[pc]; + +Notice that given that speculation windows are large, the policy is +to kill the speculation on the first load and not worry if it can be +completed with a dependent load/store [1]. + +[1] https://marc.info/?l=linux-kernel&m=152449131114778&w=2 + +Signed-off-by: Gustavo A. R. Silva +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/filter.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -73,6 +73,7 @@ + #include + #include + #include ++#include + + /** + * sk_filter_trim_cap - run a packet through a socket filter +@@ -1038,6 +1039,7 @@ static int bpf_check_classic(const struc + bool anc_found; + int pc; + ++ flen = array_index_nospec(flen, BPF_MAXINSNS + 1); + /* Check the filter code now */ + for (pc = 0; pc < flen; pc++) { + const struct sock_filter *ftest = &filter[pc]; diff --git a/queue-4.20/net-hamradio-6pack-use-mod_timer-to-rearm-timers.patch b/queue-4.20/net-hamradio-6pack-use-mod_timer-to-rearm-timers.patch new file mode 100644 index 00000000000..0186bef67d0 --- /dev/null +++ b/queue-4.20/net-hamradio-6pack-use-mod_timer-to-rearm-timers.patch @@ -0,0 +1,94 @@ +From foo@baz Fri Jan 4 19:32:29 CET 2019 +From: Eric Dumazet +Date: Wed, 2 Jan 2019 04:24:20 -0800 +Subject: net/hamradio/6pack: use mod_timer() to rearm timers + +From: Eric Dumazet + +[ Upstream commit 202700e30740c6568b5a6943662f3829566dd533 ] + +Using del_timer() + add_timer() is generally unsafe on SMP, +as noticed by syzbot. Use mod_timer() instead. + +kernel BUG at kernel/time/timer.c:1136! +invalid opcode: 0000 [#1] PREEMPT SMP KASAN +CPU: 1 PID: 1026 Comm: kworker/u4:4 Not tainted 4.20.0+ #2 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Workqueue: events_unbound flush_to_ldisc +RIP: 0010:add_timer kernel/time/timer.c:1136 [inline] +RIP: 0010:add_timer+0xa81/0x1470 kernel/time/timer.c:1134 +Code: 4d 89 7d 40 48 c7 85 70 fe ff ff 00 00 00 00 c7 85 7c fe ff ff ff ff ff ff 48 89 85 90 fe ff ff e9 e6 f7 ff ff e8 cf 42 12 00 <0f> 0b e8 c8 42 12 00 0f 0b e8 c1 42 12 00 4c 89 bd 60 fe ff ff e9 +RSP: 0018:ffff8880a7fdf5a8 EFLAGS: 00010293 +RAX: ffff8880a7846340 RBX: dffffc0000000000 RCX: 0000000000000000 +RDX: 0000000000000000 RSI: ffffffff816f3ee1 RDI: ffff88808a514ff8 +RBP: ffff8880a7fdf760 R08: 0000000000000007 R09: ffff8880a7846c58 +R10: ffff8880a7846340 R11: 0000000000000000 R12: ffff88808a514ff8 +R13: ffff88808a514ff8 R14: ffff88808a514dc0 R15: 0000000000000030 +FS: 0000000000000000(0000) GS:ffff8880ae700000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 000000000061c500 CR3: 00000000994d9000 CR4: 00000000001406e0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: + decode_prio_command drivers/net/hamradio/6pack.c:903 [inline] + sixpack_decode drivers/net/hamradio/6pack.c:971 [inline] + sixpack_receive_buf drivers/net/hamradio/6pack.c:457 [inline] + sixpack_receive_buf+0xf9c/0x1470 drivers/net/hamradio/6pack.c:434 + tty_ldisc_receive_buf+0x164/0x1c0 drivers/tty/tty_buffer.c:465 + tty_port_default_receive_buf+0x114/0x190 drivers/tty/tty_port.c:38 + receive_buf drivers/tty/tty_buffer.c:481 [inline] + flush_to_ldisc+0x3b2/0x590 drivers/tty/tty_buffer.c:533 + process_one_work+0xd0c/0x1ce0 kernel/workqueue.c:2153 + worker_thread+0x143/0x14a0 kernel/workqueue.c:2296 + kthread+0x357/0x430 kernel/kthread.c:246 + ret_from_fork+0x3a/0x50 arch/x86/entry/entry_64.S:352 + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Cc: Andreas Koensgen +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/hamradio/6pack.c | 16 ++++------------ + 1 file changed, 4 insertions(+), 12 deletions(-) + +--- a/drivers/net/hamradio/6pack.c ++++ b/drivers/net/hamradio/6pack.c +@@ -523,10 +523,7 @@ static void resync_tnc(struct timer_list + + + /* Start resync timer again -- the TNC might be still absent */ +- +- del_timer(&sp->resync_t); +- sp->resync_t.expires = jiffies + SIXP_RESYNC_TIMEOUT; +- add_timer(&sp->resync_t); ++ mod_timer(&sp->resync_t, jiffies + SIXP_RESYNC_TIMEOUT); + } + + static inline int tnc_init(struct sixpack *sp) +@@ -537,9 +534,7 @@ static inline int tnc_init(struct sixpac + + sp->tty->ops->write(sp->tty, &inbyte, 1); + +- del_timer(&sp->resync_t); +- sp->resync_t.expires = jiffies + SIXP_RESYNC_TIMEOUT; +- add_timer(&sp->resync_t); ++ mod_timer(&sp->resync_t, jiffies + SIXP_RESYNC_TIMEOUT); + + return 0; + } +@@ -897,11 +892,8 @@ static void decode_prio_command(struct s + /* if the state byte has been received, the TNC is present, + so the resync timer can be reset. */ + +- if (sp->tnc_state == TNC_IN_SYNC) { +- del_timer(&sp->resync_t); +- sp->resync_t.expires = jiffies + SIXP_INIT_RESYNC_TIMEOUT; +- add_timer(&sp->resync_t); +- } ++ if (sp->tnc_state == TNC_IN_SYNC) ++ mod_timer(&sp->resync_t, jiffies + SIXP_INIT_RESYNC_TIMEOUT); + + sp->status1 = cmd & SIXP_PRIO_DATA_MASK; + } diff --git a/queue-4.20/net-wan-fix-a-double-free-in-x25_asy_open_tty.patch b/queue-4.20/net-wan-fix-a-double-free-in-x25_asy_open_tty.patch new file mode 100644 index 00000000000..7f04d9c82dc --- /dev/null +++ b/queue-4.20/net-wan-fix-a-double-free-in-x25_asy_open_tty.patch @@ -0,0 +1,37 @@ +From foo@baz Fri Jan 4 19:32:29 CET 2019 +From: Cong Wang +Date: Sat, 29 Dec 2018 13:56:37 -0800 +Subject: net/wan: fix a double free in x25_asy_open_tty() + +From: Cong Wang + +[ Upstream commit d5c7c745f254c6cb98b3b3f15fe789b8bd770c72 ] + +When x25_asy_open() fails, it already cleans up by itself, +so its caller doesn't need to free the memory again. + +It seems we still have to call x25_asy_free() to clear the SLF_INUSE +bit, so just set these pointers to NULL after kfree(). + +Reported-and-tested-by: syzbot+5e5e969e525129229052@syzkaller.appspotmail.com +Fixes: 3b780bed3138 ("x25_asy: Free x25_asy on x25_asy_open() failure.") +Signed-off-by: Cong Wang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wan/x25_asy.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/wan/x25_asy.c ++++ b/drivers/net/wan/x25_asy.c +@@ -485,8 +485,10 @@ static int x25_asy_open(struct net_devic + + /* Cleanup */ + kfree(sl->xbuff); ++ sl->xbuff = NULL; + noxbuff: + kfree(sl->rbuff); ++ sl->rbuff = NULL; + norbuff: + return -ENOMEM; + } diff --git a/queue-4.20/netrom-fix-locking-in-nr_find_socket.patch b/queue-4.20/netrom-fix-locking-in-nr_find_socket.patch new file mode 100644 index 00000000000..6807e6e2a6b --- /dev/null +++ b/queue-4.20/netrom-fix-locking-in-nr_find_socket.patch @@ -0,0 +1,101 @@ +From foo@baz Fri Jan 4 19:32:29 CET 2019 +From: Cong Wang +Date: Sat, 29 Dec 2018 13:56:38 -0800 +Subject: netrom: fix locking in nr_find_socket() + +From: Cong Wang + +[ Upstream commit 7314f5480f3e37e570104dc5e0f28823ef849e72 ] + +nr_find_socket(), nr_find_peer() and nr_find_listener() lock the +sock after finding it in the global list. However, the call path +requires BH disabled for the sock lock consistently. + +Actually the locking is unnecessary at this point, we can just hold +the sock refcnt to make sure it is not gone after we unlock the global +list, and lock it later only when needed. + +Reported-and-tested-by: syzbot+f621cda8b7e598908efa@syzkaller.appspotmail.com +Signed-off-by: Cong Wang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/netrom/af_netrom.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +--- a/net/netrom/af_netrom.c ++++ b/net/netrom/af_netrom.c +@@ -153,7 +153,7 @@ static struct sock *nr_find_listener(ax2 + sk_for_each(s, &nr_list) + if (!ax25cmp(&nr_sk(s)->source_addr, addr) && + s->sk_state == TCP_LISTEN) { +- bh_lock_sock(s); ++ sock_hold(s); + goto found; + } + s = NULL; +@@ -174,7 +174,7 @@ static struct sock *nr_find_socket(unsig + struct nr_sock *nr = nr_sk(s); + + if (nr->my_index == index && nr->my_id == id) { +- bh_lock_sock(s); ++ sock_hold(s); + goto found; + } + } +@@ -198,7 +198,7 @@ static struct sock *nr_find_peer(unsigne + + if (nr->your_index == index && nr->your_id == id && + !ax25cmp(&nr->dest_addr, dest)) { +- bh_lock_sock(s); ++ sock_hold(s); + goto found; + } + } +@@ -224,7 +224,7 @@ static unsigned short nr_find_next_circu + if (i != 0 && j != 0) { + if ((sk=nr_find_socket(i, j)) == NULL) + break; +- bh_unlock_sock(sk); ++ sock_put(sk); + } + + id++; +@@ -920,6 +920,7 @@ int nr_rx_frame(struct sk_buff *skb, str + } + + if (sk != NULL) { ++ bh_lock_sock(sk); + skb_reset_transport_header(skb); + + if (frametype == NR_CONNACK && skb->len == 22) +@@ -929,6 +930,7 @@ int nr_rx_frame(struct sk_buff *skb, str + + ret = nr_process_rx_frame(sk, skb); + bh_unlock_sock(sk); ++ sock_put(sk); + return ret; + } + +@@ -960,10 +962,12 @@ int nr_rx_frame(struct sk_buff *skb, str + (make = nr_make_new(sk)) == NULL) { + nr_transmit_refusal(skb, 0); + if (sk) +- bh_unlock_sock(sk); ++ sock_put(sk); + return 0; + } + ++ bh_lock_sock(sk); ++ + window = skb->data[20]; + + skb->sk = make; +@@ -1016,6 +1020,7 @@ int nr_rx_frame(struct sk_buff *skb, str + sk->sk_data_ready(sk); + + bh_unlock_sock(sk); ++ sock_put(sk); + + nr_insert_socket(make); + diff --git a/queue-4.20/packet-validate-address-length-if-non-zero.patch b/queue-4.20/packet-validate-address-length-if-non-zero.patch new file mode 100644 index 00000000000..4a8aeee0a02 --- /dev/null +++ b/queue-4.20/packet-validate-address-length-if-non-zero.patch @@ -0,0 +1,41 @@ +From foo@baz Fri Jan 4 19:32:29 CET 2019 +From: Willem de Bruijn +Date: Sat, 22 Dec 2018 16:53:45 -0500 +Subject: packet: validate address length if non-zero + +From: Willem de Bruijn + +[ Upstream commit 6b8d95f1795c42161dc0984b6863e95d6acf24ed ] + +Validate packet socket address length if a length is given. Zero +length is equivalent to not setting an address. + +Fixes: 99137b7888f4 ("packet: validate address length") +Reported-by: Ido Schimmel +Signed-off-by: Willem de Bruijn +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/packet/af_packet.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -2625,7 +2625,7 @@ static int tpacket_snd(struct packet_soc + sll_addr))) + goto out; + proto = saddr->sll_protocol; +- addr = saddr->sll_addr; ++ addr = saddr->sll_halen ? saddr->sll_addr : NULL; + dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex); + if (addr && dev && saddr->sll_halen < dev->addr_len) + goto out; +@@ -2825,7 +2825,7 @@ static int packet_snd(struct socket *soc + if (msg->msg_namelen < (saddr->sll_halen + offsetof(struct sockaddr_ll, sll_addr))) + goto out; + proto = saddr->sll_protocol; +- addr = saddr->sll_addr; ++ addr = saddr->sll_halen ? saddr->sll_addr : NULL; + dev = dev_get_by_index(sock_net(sk), saddr->sll_ifindex); + if (addr && dev && saddr->sll_halen < dev->addr_len) + goto out; diff --git a/queue-4.20/phonet-af_phonet-fix-spectre-v1-vulnerability.patch b/queue-4.20/phonet-af_phonet-fix-spectre-v1-vulnerability.patch new file mode 100644 index 00000000000..f21cc1557de --- /dev/null +++ b/queue-4.20/phonet-af_phonet-fix-spectre-v1-vulnerability.patch @@ -0,0 +1,50 @@ +From foo@baz Fri Jan 4 19:32:29 CET 2019 +From: "Gustavo A. R. Silva" +Date: Fri, 21 Dec 2018 15:41:17 -0600 +Subject: phonet: af_phonet: Fix Spectre v1 vulnerability + +From: "Gustavo A. R. Silva" + +[ Upstream commit d686026b1e6ed4ea27d630d8f54f9a694db088b2 ] + +protocol is indirectly controlled by user-space, hence leading to +a potential exploitation of the Spectre variant 1 vulnerability. + +This issue was detected with the help of Smatch: + +net/phonet/af_phonet.c:48 phonet_proto_get() warn: potential spectre issue 'proto_tab' [w] (local cap) + +Fix this by sanitizing protocol before using it to index proto_tab. + +Notice that given that speculation windows are large, the policy is +to kill the speculation on the first load and not worry if it can be +completed with a dependent load/store [1]. + +[1] https://marc.info/?l=linux-kernel&m=152449131114778&w=2 + +Signed-off-by: Gustavo A. R. Silva +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/phonet/af_phonet.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/phonet/af_phonet.c ++++ b/net/phonet/af_phonet.c +@@ -34,6 +34,8 @@ + #include + #include + ++#include ++ + /* Transport protocol registration */ + static const struct phonet_protocol *proto_tab[PHONET_NPROTO] __read_mostly; + +@@ -43,6 +45,7 @@ static const struct phonet_protocol *pho + + if (protocol >= PHONET_NPROTO) + return NULL; ++ protocol = array_index_nospec(protocol, PHONET_NPROTO); + + rcu_read_lock(); + pp = rcu_dereference(proto_tab[protocol]); diff --git a/queue-4.20/ptr_ring-wrap-back-producer-in-__ptr_ring_swap_queue.patch b/queue-4.20/ptr_ring-wrap-back-producer-in-__ptr_ring_swap_queue.patch new file mode 100644 index 00000000000..5aa8ff049ed --- /dev/null +++ b/queue-4.20/ptr_ring-wrap-back-producer-in-__ptr_ring_swap_queue.patch @@ -0,0 +1,39 @@ +From foo@baz Fri Jan 4 19:32:29 CET 2019 +From: Cong Wang +Date: Sun, 30 Dec 2018 12:43:42 -0800 +Subject: ptr_ring: wrap back ->producer in __ptr_ring_swap_queue() + +From: Cong Wang + +[ Upstream commit aff6db454599d62191aabc208930e891748e4322 ] + +__ptr_ring_swap_queue() tries to move pointers from the old +ring to the new one, but it forgets to check if ->producer +is beyond the new size at the end of the operation. This leads +to an out-of-bound access in __ptr_ring_produce() as reported +by syzbot. + +Reported-by: syzbot+8993c0fa96d57c399735@syzkaller.appspotmail.com +Fixes: 5d49de532002 ("ptr_ring: resize support") +Cc: "Michael S. Tsirkin" +Cc: John Fastabend +Cc: Jason Wang +Signed-off-by: Cong Wang +Acked-by: Michael S. Tsirkin +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/ptr_ring.h | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/include/linux/ptr_ring.h ++++ b/include/linux/ptr_ring.h +@@ -573,6 +573,8 @@ static inline void **__ptr_ring_swap_que + else if (destroy) + destroy(ptr); + ++ if (producer >= size) ++ producer = 0; + __ptr_ring_set_size(r, size); + r->producer = producer; + r->consumer_head = 0; diff --git a/queue-4.20/series b/queue-4.20/series index e2f2ff9dce4..b7093b8a8ff 100644 --- a/queue-4.20/series +++ b/queue-4.20/series @@ -1,3 +1,19 @@ panic-avoid-deadlocks-in-re-entrant-console-drivers.patch iwlwifi-add-new-cards-for-9560-9462-9461-and-killer-series.patch media-ov5640-fix-set-format-regression.patch +bnx2x-fix-null-pointer-dereference-in-bnx2x_del_all_vlans-on-some-hw.patch +tap-call-skb_probe_transport_header-after-setting-skb-dev.patch +ax25-fix-a-use-after-free-in-ax25_fillin_cb.patch +ibmveth-fix-dma-unmap-error-in-ibmveth_xmit_start-error-path.patch +ieee802154-lowpan_header_create-check-must-check-daddr.patch +ip-validate-header-length-on-virtual-device-xmit.patch +net-core-fix-spectre-v1-vulnerability.patch +net-hamradio-6pack-use-mod_timer-to-rearm-timers.patch +isdn-fix-kernel-infoleak-in-capi_unlocked_ioctl.patch +netrom-fix-locking-in-nr_find_socket.patch +net-wan-fix-a-double-free-in-x25_asy_open_tty.patch +packet-validate-address-length-if-non-zero.patch +phonet-af_phonet-fix-spectre-v1-vulnerability.patch +ptr_ring-wrap-back-producer-in-__ptr_ring_swap_queue.patch +sock-make-sock-sk_stamp-thread-safe.patch +tipc-fix-a-double-free-in-tipc_enable_bearer.patch diff --git a/queue-4.20/sock-make-sock-sk_stamp-thread-safe.patch b/queue-4.20/sock-make-sock-sk_stamp-thread-safe.patch new file mode 100644 index 00000000000..3eb54c88913 --- /dev/null +++ b/queue-4.20/sock-make-sock-sk_stamp-thread-safe.patch @@ -0,0 +1,215 @@ +From foo@baz Fri Jan 4 19:32:29 CET 2019 +From: Deepa Dinamani +Date: Thu, 27 Dec 2018 18:55:09 -0800 +Subject: sock: Make sock->sk_stamp thread-safe + +From: Deepa Dinamani + +[ Upstream commit 3a0ed3e9619738067214871e9cb826fa23b2ddb9 ] + +Al Viro mentioned (Message-ID +<20170626041334.GZ10672@ZenIV.linux.org.uk>) +that there is probably a race condition +lurking in accesses of sk_stamp on 32-bit machines. + +sock->sk_stamp is of type ktime_t which is always an s64. +On a 32 bit architecture, we might run into situations of +unsafe access as the access to the field becomes non atomic. + +Use seqlocks for synchronization. +This allows us to avoid using spinlocks for readers as +readers do not need mutual exclusion. + +Another approach to solve this is to require sk_lock for all +modifications of the timestamps. The current approach allows +for timestamps to have their own lock: sk_stamp_lock. +This allows for the patch to not compete with already +existing critical sections, and side effects are limited +to the paths in the patch. + +The addition of the new field maintains the data locality +optimizations from +commit 9115e8cd2a0c ("net: reorganize struct sock for better data +locality") + +Note that all the instances of the sk_stamp accesses +are either through the ioctl or the syscall recvmsg. + +Signed-off-by: Deepa Dinamani +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/sock.h | 38 +++++++++++++++++++++++++++++++++++--- + net/compat.c | 15 +++++++++------ + net/core/sock.c | 15 ++++++++++----- + net/sunrpc/svcsock.c | 2 +- + 4 files changed, 55 insertions(+), 15 deletions(-) + +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -298,6 +298,7 @@ struct sock_common { + * @sk_filter: socket filtering instructions + * @sk_timer: sock cleanup timer + * @sk_stamp: time stamp of last packet received ++ * @sk_stamp_seq: lock for accessing sk_stamp on 32 bit architectures only + * @sk_tsflags: SO_TIMESTAMPING socket options + * @sk_tskey: counter to disambiguate concurrent tstamp requests + * @sk_zckey: counter to order MSG_ZEROCOPY notifications +@@ -474,6 +475,9 @@ struct sock { + const struct cred *sk_peer_cred; + long sk_rcvtimeo; + ktime_t sk_stamp; ++#if BITS_PER_LONG==32 ++ seqlock_t sk_stamp_seq; ++#endif + u16 sk_tsflags; + u8 sk_shutdown; + u32 sk_tskey; +@@ -2287,6 +2291,34 @@ static inline void sk_drops_add(struct s + atomic_add(segs, &sk->sk_drops); + } + ++static inline ktime_t sock_read_timestamp(struct sock *sk) ++{ ++#if BITS_PER_LONG==32 ++ unsigned int seq; ++ ktime_t kt; ++ ++ do { ++ seq = read_seqbegin(&sk->sk_stamp_seq); ++ kt = sk->sk_stamp; ++ } while (read_seqretry(&sk->sk_stamp_seq, seq)); ++ ++ return kt; ++#else ++ return sk->sk_stamp; ++#endif ++} ++ ++static inline void sock_write_timestamp(struct sock *sk, ktime_t kt) ++{ ++#if BITS_PER_LONG==32 ++ write_seqlock(&sk->sk_stamp_seq); ++ sk->sk_stamp = kt; ++ write_sequnlock(&sk->sk_stamp_seq); ++#else ++ sk->sk_stamp = kt; ++#endif ++} ++ + void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, + struct sk_buff *skb); + void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk, +@@ -2311,7 +2343,7 @@ sock_recv_timestamp(struct msghdr *msg, + (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE))) + __sock_recv_timestamp(msg, sk, skb); + else +- sk->sk_stamp = kt; ++ sock_write_timestamp(sk, kt); + + if (sock_flag(sk, SOCK_WIFI_STATUS) && skb->wifi_acked_valid) + __sock_recv_wifi_status(msg, sk, skb); +@@ -2332,9 +2364,9 @@ static inline void sock_recv_ts_and_drop + if (sk->sk_flags & FLAGS_TS_OR_DROPS || sk->sk_tsflags & TSFLAGS_ANY) + __sock_recv_ts_and_drops(msg, sk, skb); + else if (unlikely(sock_flag(sk, SOCK_TIMESTAMP))) +- sk->sk_stamp = skb->tstamp; ++ sock_write_timestamp(sk, skb->tstamp); + else if (unlikely(sk->sk_stamp == SK_DEFAULT_STAMP)) +- sk->sk_stamp = 0; ++ sock_write_timestamp(sk, 0); + } + + void __sock_tx_timestamp(__u16 tsflags, __u8 *tx_flags); +--- a/net/compat.c ++++ b/net/compat.c +@@ -467,12 +467,14 @@ int compat_sock_get_timestamp(struct soc + ctv = (struct compat_timeval __user *) userstamp; + err = -ENOENT; + sock_enable_timestamp(sk, SOCK_TIMESTAMP); +- tv = ktime_to_timeval(sk->sk_stamp); ++ tv = ktime_to_timeval(sock_read_timestamp(sk)); ++ + if (tv.tv_sec == -1) + return err; + if (tv.tv_sec == 0) { +- sk->sk_stamp = ktime_get_real(); +- tv = ktime_to_timeval(sk->sk_stamp); ++ ktime_t kt = ktime_get_real(); ++ sock_write_timestamp(sk, kt); ++ tv = ktime_to_timeval(kt); + } + err = 0; + if (put_user(tv.tv_sec, &ctv->tv_sec) || +@@ -494,12 +496,13 @@ int compat_sock_get_timestampns(struct s + ctv = (struct compat_timespec __user *) userstamp; + err = -ENOENT; + sock_enable_timestamp(sk, SOCK_TIMESTAMP); +- ts = ktime_to_timespec(sk->sk_stamp); ++ ts = ktime_to_timespec(sock_read_timestamp(sk)); + if (ts.tv_sec == -1) + return err; + if (ts.tv_sec == 0) { +- sk->sk_stamp = ktime_get_real(); +- ts = ktime_to_timespec(sk->sk_stamp); ++ ktime_t kt = ktime_get_real(); ++ sock_write_timestamp(sk, kt); ++ ts = ktime_to_timespec(kt); + } + err = 0; + if (put_user(ts.tv_sec, &ctv->tv_sec) || +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -2743,6 +2743,9 @@ void sock_init_data(struct socket *sock, + sk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT; + + sk->sk_stamp = SK_DEFAULT_STAMP; ++#if BITS_PER_LONG==32 ++ seqlock_init(&sk->sk_stamp_seq); ++#endif + atomic_set(&sk->sk_zckey, 0); + + #ifdef CONFIG_NET_RX_BUSY_POLL +@@ -2842,12 +2845,13 @@ int sock_get_timestamp(struct sock *sk, + struct timeval tv; + + sock_enable_timestamp(sk, SOCK_TIMESTAMP); +- tv = ktime_to_timeval(sk->sk_stamp); ++ tv = ktime_to_timeval(sock_read_timestamp(sk)); + if (tv.tv_sec == -1) + return -ENOENT; + if (tv.tv_sec == 0) { +- sk->sk_stamp = ktime_get_real(); +- tv = ktime_to_timeval(sk->sk_stamp); ++ ktime_t kt = ktime_get_real(); ++ sock_write_timestamp(sk, kt); ++ tv = ktime_to_timeval(kt); + } + return copy_to_user(userstamp, &tv, sizeof(tv)) ? -EFAULT : 0; + } +@@ -2858,11 +2862,12 @@ int sock_get_timestampns(struct sock *sk + struct timespec ts; + + sock_enable_timestamp(sk, SOCK_TIMESTAMP); +- ts = ktime_to_timespec(sk->sk_stamp); ++ ts = ktime_to_timespec(sock_read_timestamp(sk)); + if (ts.tv_sec == -1) + return -ENOENT; + if (ts.tv_sec == 0) { +- sk->sk_stamp = ktime_get_real(); ++ ktime_t kt = ktime_get_real(); ++ sock_write_timestamp(sk, kt); + ts = ktime_to_timespec(sk->sk_stamp); + } + return copy_to_user(userstamp, &ts, sizeof(ts)) ? -EFAULT : 0; +--- a/net/sunrpc/svcsock.c ++++ b/net/sunrpc/svcsock.c +@@ -549,7 +549,7 @@ static int svc_udp_recvfrom(struct svc_r + /* Don't enable netstamp, sunrpc doesn't + need that much accuracy */ + } +- svsk->sk_sk->sk_stamp = skb->tstamp; ++ sock_write_timestamp(svsk->sk_sk, skb->tstamp); + set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); /* there may be more data... */ + + len = skb->len; diff --git a/queue-4.20/tap-call-skb_probe_transport_header-after-setting-skb-dev.patch b/queue-4.20/tap-call-skb_probe_transport_header-after-setting-skb-dev.patch new file mode 100644 index 00000000000..7c9fc7f1e3c --- /dev/null +++ b/queue-4.20/tap-call-skb_probe_transport_header-after-setting-skb-dev.patch @@ -0,0 +1,43 @@ +From foo@baz Fri Jan 4 19:32:29 CET 2019 +From: Willem de Bruijn +Date: Sun, 30 Dec 2018 17:21:05 -0500 +Subject: tap: call skb_probe_transport_header after setting skb->dev + +From: Willem de Bruijn + +[ Upstream commit 8c76e77f9069f10505c08e02646c3ee11ad79038 ] + +The BPF flow dissector expects either skb->sk or skb->dev set on +all skbs. Delay flow dissection until after skb->dev is set. + +This requires calling from within an rcu read-side critical section. +That is fine, see also the call from tun_xdp_one. + +Fixes: d0e13a1488ad ("flow_dissector: lookup netns by skb->sk if skb->dev is NULL") +Reported-by: Christian Borntraeger +Signed-off-by: Willem de Bruijn +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/tap.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/net/tap.c ++++ b/drivers/net/tap.c +@@ -1177,8 +1177,6 @@ static int tap_get_user_xdp(struct tap_q + goto err_kfree; + } + +- skb_probe_transport_header(skb, ETH_HLEN); +- + /* Move network header to the right position for VLAN tagged packets */ + if ((skb->protocol == htons(ETH_P_8021Q) || + skb->protocol == htons(ETH_P_8021AD)) && +@@ -1189,6 +1187,7 @@ static int tap_get_user_xdp(struct tap_q + tap = rcu_dereference(q->tap); + if (tap) { + skb->dev = tap->dev; ++ skb_probe_transport_header(skb, ETH_HLEN); + dev_queue_xmit(skb); + } else { + kfree_skb(skb); diff --git a/queue-4.20/tipc-fix-a-double-free-in-tipc_enable_bearer.patch b/queue-4.20/tipc-fix-a-double-free-in-tipc_enable_bearer.patch new file mode 100644 index 00000000000..6271e299b6e --- /dev/null +++ b/queue-4.20/tipc-fix-a-double-free-in-tipc_enable_bearer.patch @@ -0,0 +1,33 @@ +From foo@baz Fri Jan 4 19:32:29 CET 2019 +From: Cong Wang +Date: Sun, 23 Dec 2018 21:45:56 -0800 +Subject: tipc: fix a double free in tipc_enable_bearer() + +From: Cong Wang + +[ Upstream commit dc4501ff287547dea7ca10f1c580c741291a8760 ] + +bearer_disable() already calls kfree_rcu() to free struct tipc_bearer, +we don't need to call kfree() again. + +Fixes: cb30a63384bc ("tipc: refactor function tipc_enable_bearer()") +Reported-by: syzbot+b981acf1fb240c0c128b@syzkaller.appspotmail.com +Cc: Ying Xue +Cc: Jon Maloy +Signed-off-by: Cong Wang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/tipc/bearer.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/net/tipc/bearer.c ++++ b/net/tipc/bearer.c +@@ -317,7 +317,6 @@ static int tipc_enable_bearer(struct net + res = tipc_disc_create(net, b, &b->bcast_addr, &skb); + if (res) { + bearer_disable(net, b); +- kfree(b); + errstr = "failed to create discoverer"; + goto rejected; + }