From 50d5258634aee2e62832aa086d2fb0de00e72b91 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Fri, 21 Dec 2018 14:49:01 -0600 Subject: [PATCH 01/11] net: core: Fix Spectre v1 vulnerability 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 --- net/core/filter.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/core/filter.c b/net/core/filter.c index 8d2c629501e2..0c74c2f9776a 100644 --- 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 struct sock_filter *filter, 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]; From d686026b1e6ed4ea27d630d8f54f9a694db088b2 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Fri, 21 Dec 2018 15:41:17 -0600 Subject: [PATCH 02/11] phonet: af_phonet: Fix Spectre v1 vulnerability 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 --- net/phonet/af_phonet.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c index 3b0ef691f5b1..d4b2abd78858 100644 --- 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 *phonet_proto_get(unsigned int protocol) if (protocol >= PHONET_NPROTO) return NULL; + protocol = array_index_nospec(protocol, PHONET_NPROTO); rcu_read_lock(); pp = rcu_dereference(proto_tab[protocol]); From a95386f0390ab602904d11fe6bd7ea5ef9b136f8 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Fri, 21 Dec 2018 15:47:53 -0600 Subject: [PATCH 03/11] nfc: af_nfc: Fix Spectre v1 vulnerability proto 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/nfc/af_nfc.c:42 nfc_sock_create() warn: potential spectre issue 'proto_tab' [w] (local cap) Fix this by sanitizing proto 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 --- net/nfc/af_nfc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/nfc/af_nfc.c b/net/nfc/af_nfc.c index d3e594eb36d0..256f3c57059e 100644 --- a/net/nfc/af_nfc.c +++ b/net/nfc/af_nfc.c @@ -21,6 +21,7 @@ #include #include +#include #include "nfc.h" @@ -37,6 +38,7 @@ static int nfc_sock_create(struct net *net, struct socket *sock, int proto, if (proto < 0 || proto >= NFC_SOCKPROTO_MAX) return -EINVAL; + proto = array_index_nospec(proto, NFC_SOCKPROTO_MAX); read_lock(&proto_tab_lock); if (proto_tab[proto] && try_module_get(proto_tab[proto]->owner)) { From 6b8d95f1795c42161dc0984b6863e95d6acf24ed Mon Sep 17 00:00:00 2001 From: Willem de Bruijn Date: Sat, 22 Dec 2018 16:53:45 -0500 Subject: [PATCH 04/11] packet: validate address length if non-zero 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 --- net/packet/af_packet.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 5dda263b4a0a..eedacdebcd4c 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -2625,7 +2625,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) 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 *sock, struct msghdr *msg, size_t len) 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; From a3ac5817ffe8f81dbe6be1522b499b48bc322e3a Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Fri, 21 Dec 2018 15:22:29 -0600 Subject: [PATCH 05/11] can: af_can: Fix Spectre v1 vulnerability 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/can/af_can.c:115 can_get_proto() warn: potential spectre issue 'proto_tab' [w] 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 --- net/can/af_can.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/can/af_can.c b/net/can/af_can.c index 1684ba5b51eb..cade7250c6d4 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c @@ -59,6 +59,7 @@ #include #include #include +#include #include #include @@ -136,6 +137,7 @@ static int can_create(struct net *net, struct socket *sock, int protocol, if (protocol < 0 || protocol >= CAN_NPROTO) return -EINVAL; + protocol = array_index_nospec(protocol, CAN_NPROTO); cp = can_get_proto(protocol); From f2ab95814103314af3239d322e382c61c69a788d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 23 Dec 2018 16:01:35 -0800 Subject: [PATCH 06/11] net: Revert recent Spectre-v1 patches. This reverts: 50d5258634ae ("net: core: Fix Spectre v1 vulnerability") d686026b1e6e ("phonet: af_phonet: Fix Spectre v1 vulnerability") a95386f0390a ("nfc: af_nfc: Fix Spectre v1 vulnerability") a3ac5817ffe8 ("can: af_can: Fix Spectre v1 vulnerability") After some discussion with Alexei Starovoitov these all seem to be completely unnecessary. Signed-off-by: David S. Miller --- net/can/af_can.c | 2 -- net/core/filter.c | 2 -- net/nfc/af_nfc.c | 2 -- net/phonet/af_phonet.c | 3 --- 4 files changed, 9 deletions(-) diff --git a/net/can/af_can.c b/net/can/af_can.c index cade7250c6d4..1684ba5b51eb 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c @@ -59,7 +59,6 @@ #include #include #include -#include #include #include @@ -137,7 +136,6 @@ static int can_create(struct net *net, struct socket *sock, int protocol, if (protocol < 0 || protocol >= CAN_NPROTO) return -EINVAL; - protocol = array_index_nospec(protocol, CAN_NPROTO); cp = can_get_proto(protocol); diff --git a/net/core/filter.c b/net/core/filter.c index 0c74c2f9776a..8d2c629501e2 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -73,7 +73,6 @@ #include #include #include -#include /** * sk_filter_trim_cap - run a packet through a socket filter @@ -1039,7 +1038,6 @@ static int bpf_check_classic(const struct sock_filter *filter, 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/net/nfc/af_nfc.c b/net/nfc/af_nfc.c index 256f3c57059e..d3e594eb36d0 100644 --- a/net/nfc/af_nfc.c +++ b/net/nfc/af_nfc.c @@ -21,7 +21,6 @@ #include #include -#include #include "nfc.h" @@ -38,7 +37,6 @@ static int nfc_sock_create(struct net *net, struct socket *sock, int proto, if (proto < 0 || proto >= NFC_SOCKPROTO_MAX) return -EINVAL; - proto = array_index_nospec(proto, NFC_SOCKPROTO_MAX); read_lock(&proto_tab_lock); if (proto_tab[proto] && try_module_get(proto_tab[proto]->owner)) { diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c index d4b2abd78858..3b0ef691f5b1 100644 --- a/net/phonet/af_phonet.c +++ b/net/phonet/af_phonet.c @@ -34,8 +34,6 @@ #include #include -#include - /* Transport protocol registration */ static const struct phonet_protocol *proto_tab[PHONET_NPROTO] __read_mostly; @@ -45,7 +43,6 @@ static const struct phonet_protocol *phonet_proto_get(unsigned int protocol) if (protocol >= PHONET_NPROTO) return NULL; - protocol = array_index_nospec(protocol, PHONET_NPROTO); rcu_read_lock(); pp = rcu_dereference(proto_tab[protocol]); From 7bdca378b2301b1fc6a95c60d6d428408ae4e39e Mon Sep 17 00:00:00 2001 From: wenxu Date: Sun, 23 Dec 2018 16:18:39 +0800 Subject: [PATCH 07/11] iptunnel: Set tun_flags in the iptunnel_metadata_reply from src ip l add tun type gretap external ip r a 10.0.0.2 encap ip id 1000 dst 172.168.0.2 key dev tun ip a a 10.0.0.1/24 dev tun The peer arp request to 10.0.0.1 with tunnel_id, but the arp reply only set the tun_id but not the tun_flags with TUNNEL_KEY. The arp reply packet don't contain tun_id field. Signed-off-by: wenxu Signed-off-by: David S. Miller --- net/ipv4/ip_tunnel_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c index c248e0dccbe1..43f519c9b318 100644 --- a/net/ipv4/ip_tunnel_core.c +++ b/net/ipv4/ip_tunnel_core.c @@ -151,6 +151,7 @@ struct metadata_dst *iptunnel_metadata_reply(struct metadata_dst *md, sizeof(struct in6_addr)); else dst->key.u.ipv4.dst = src->key.u.ipv4.src; + dst->key.tun_flags = src->key.tun_flags; dst->mode = src->mode | IP_TUNNEL_INFO_TX; return res; From 40c3ff6d5e0809505a067dd423c110c5658c478c Mon Sep 17 00:00:00 2001 From: Willem de Bruijn Date: Sun, 23 Dec 2018 12:52:18 -0500 Subject: [PATCH 08/11] ieee802154: lowpan_header_create check must check daddr 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 --- net/ieee802154/6lowpan/tx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/ieee802154/6lowpan/tx.c b/net/ieee802154/6lowpan/tx.c index ca53efa17be1..8bec827081cd 100644 --- a/net/ieee802154/6lowpan/tx.c +++ b/net/ieee802154/6lowpan/tx.c @@ -48,6 +48,9 @@ int lowpan_header_create(struct sk_buff *skb, struct net_device *ldev, 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? */ From 89dfd0083751d00d5d7ead36f6d8b045bf89c5e1 Mon Sep 17 00:00:00 2001 From: Aditya Pakki Date: Sun, 23 Dec 2018 18:54:53 -0600 Subject: [PATCH 09/11] net/netlink_compat: Fix a missing check of nla_parse_nested In tipc_nl_compat_sk_dump(), if nla_parse_nested() fails, it could return an error. To be consistent with other invocations of the function call, on error, the fix passes the return value upstream. Signed-off-by: Aditya Pakki Signed-off-by: David S. Miller --- net/tipc/netlink_compat.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index 6376467e78f8..21f6ccc89401 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -951,8 +951,11 @@ static int tipc_nl_compat_sk_dump(struct tipc_nl_compat_msg *msg, u32 node; struct nlattr *con[TIPC_NLA_CON_MAX + 1]; - nla_parse_nested(con, TIPC_NLA_CON_MAX, - sock[TIPC_NLA_SOCK_CON], NULL, NULL); + err = nla_parse_nested(con, TIPC_NLA_CON_MAX, + sock[TIPC_NLA_SOCK_CON], NULL, NULL); + + if (err) + return err; node = nla_get_u32(con[TIPC_NLA_CON_NODE]); tipc_tlv_sprintf(msg->rep, " connected to <%u.%u.%u:%u>", From 0eb987c874dc93f9c9d85a6465dbde20fdd3884c Mon Sep 17 00:00:00 2001 From: Aditya Pakki Date: Sun, 23 Dec 2018 19:42:38 -0600 Subject: [PATCH 10/11] net/net_namespace: Check the return value of register_pernet_subsys() In net_ns_init(), register_pernet_subsys() could fail while registering network namespace subsystems. The fix checks the return value and sends a panic() on failure. Signed-off-by: Aditya Pakki Reviewed-by: Kirill Tkhai Signed-off-by: David S. Miller --- net/core/net_namespace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index fefe72774aeb..af8849a7a9c3 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -917,7 +917,8 @@ static int __init net_ns_init(void) init_net_initialized = true; up_write(&pernet_ops_rwsem); - register_pernet_subsys(&net_ns_ops); + if (register_pernet_subsys(&net_ns_ops)) + panic("Could not register network namespace subsystems"); rtnl_register(PF_UNSPEC, RTM_NEWNSID, rtnl_net_newid, NULL, RTNL_FLAG_DOIT_UNLOCKED); From 38355a5f9a22bfa5bd5b1bb79805aca39fa53729 Mon Sep 17 00:00:00 2001 From: Ivan Mironov Date: Mon, 24 Dec 2018 20:13:05 +0500 Subject: [PATCH 11/11] bnx2x: Fix NULL pointer dereference in bnx2x_del_all_vlans() on some hw 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 --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index b164f705709d..3b5b47e98c73 100644 --- 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, int unload_mode, bool keep_link) 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))