From 13bf1f563693f02d508df04250d745b7ec202c10 Mon Sep 17 00:00:00 2001 From: Rodrigo Rivas Costa Date: Tue, 7 Jan 2020 20:48:13 +0100 Subject: [PATCH 001/387] UPSTREAM: HID: steam: Fix input device disappearing The `connected` value for wired devices was not properly initialized, it must be set to `true` upon creation, because wired devices do not generate connection events. When a raw client (the Steam Client) uses the device, the input device is destroyed. Then, when the raw client finishes, it must be recreated. But since the `connected` variable was false this never happended. Signed-off-by: Rodrigo Rivas Costa Signed-off-by: Jiri Kosina Bug: 147434575 (cherry picked from commit 20eee6e5af35d9586774e80b6e0b1850e7cc9899) Signed-off-by: Siarhei Vishniakou Change-Id: Ib362e0dec7d53dfc4fcfdca45824cf90358240e2 --- drivers/hid/hid-steam.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/hid/hid-steam.c b/drivers/hid/hid-steam.c index 44e1eefc5b24..a4a6c90c8134 100644 --- a/drivers/hid/hid-steam.c +++ b/drivers/hid/hid-steam.c @@ -768,8 +768,12 @@ static int steam_probe(struct hid_device *hdev, if (steam->quirks & STEAM_QUIRK_WIRELESS) { hid_info(hdev, "Steam wireless receiver connected"); + /* If using a wireless adaptor ask for connection status */ + steam->connected = false; steam_request_conn_status(steam); } else { + /* A wired connection is always present */ + steam->connected = true; ret = steam_register(steam); if (ret) { hid_err(hdev, From 22f5ff27909964ee51ffb593c668717c993e7de7 Mon Sep 17 00:00:00 2001 From: Siarhei Vishniakou Date: Mon, 11 May 2020 09:37:10 -0700 Subject: [PATCH 002/387] ANDROID: hid: steam: remove BT controller matching The driver hid-steam is only meant to support the USB mode and the wireless dongle mode. It was never meant to work over the BT using the beta version of the firmware of the steam controller. In the BT mode, the controller works as a "lizard-mode" device by default. It probably needs to have a special command to activate the controller mode, but for simplicity, we just revert to the upstream state of having the hid-generic driver take care of it. The lizard mode can probably be worked around in the BT stack. Bug: 147434575 Test: connect Steam controller over BT (press steam button and "Y" key simultaneously) and make sure that the mouse device shows up as a cursor. You can use the trigger buttons to generate left and right mouse clicks. Test: compare against the upstream version, and check that it's missing the define for STEAM_CONTROLLER_BT and the matching for the product ID 1106. Signed-off-by: Siarhei Vishniakou Change-Id: Id4f6c866a7e14e20c5e633889833f3708ec6b235 (cherry picked from commit 25849e1066e869f10a1bdfa43d5fb1b685b76480) --- drivers/hid/hid-core.c | 1 - drivers/hid/hid-ids.h | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 28b297e96839..6863a8756e1c 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2175,7 +2175,6 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_UGTIZER, USB_DEVICE_ID_UGTIZER_TABLET_GP0610) }, { HID_USB_DEVICE(USB_VENDOR_ID_VALVE, USB_DEVICE_ID_STEAM_CONTROLLER) }, { HID_USB_DEVICE(USB_VENDOR_ID_VALVE, USB_DEVICE_ID_STEAM_CONTROLLER_WIRELESS) }, - { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_VALVE, USB_DEVICE_ID_STEAM_CONTROLLER_BT) }, { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) }, { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SUPER_JOY_BOX_3) }, { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 1d442329ef9c..8f13fab038cb 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -960,7 +960,6 @@ #define USB_VENDOR_ID_VALVE 0x28de #define USB_DEVICE_ID_STEAM_CONTROLLER 0x1102 #define USB_DEVICE_ID_STEAM_CONTROLLER_WIRELESS 0x1142 -#define USB_DEVICE_ID_STEAM_CONTROLLER_BT 0x1106 #define USB_VENDOR_ID_STEELSERIES 0x1038 #define USB_DEVICE_ID_STEELSERIES_SRWS1 0x1410 From 851ad197da60e453253525c2335bc3045ece17a0 Mon Sep 17 00:00:00 2001 From: Matt Jolly Date: Sun, 3 May 2020 01:03:47 +1000 Subject: [PATCH 003/387] USB: serial: qcserial: Add DW5816e support commit 78d6de3cfbd342918d31cf68d0d2eda401338aef upstream. Add support for Dell Wireless 5816e to drivers/usb/serial/qcserial.c Signed-off-by: Matt Jolly Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/qcserial.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index fb6dc16c754a..06916ddc3159 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -177,6 +177,7 @@ static const struct usb_device_id id_table[] = { {DEVICE_SWI(0x413c, 0x81b3)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */ {DEVICE_SWI(0x413c, 0x81b5)}, /* Dell Wireless 5811e QDL */ {DEVICE_SWI(0x413c, 0x81b6)}, /* Dell Wireless 5811e QDL */ + {DEVICE_SWI(0x413c, 0x81cc)}, /* Dell Wireless 5816e */ {DEVICE_SWI(0x413c, 0x81cf)}, /* Dell Wireless 5819 */ {DEVICE_SWI(0x413c, 0x81d0)}, /* Dell Wireless 5819 */ {DEVICE_SWI(0x413c, 0x81d1)}, /* Dell Wireless 5818 */ From c510cc4b377539b37942fa8e864b478d3f5ebd0a Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 30 Apr 2020 21:51:32 +0200 Subject: [PATCH 004/387] dp83640: reverse arguments to list_add_tail [ Upstream commit 865308373ed49c9fb05720d14cbf1315349b32a9 ] In this code, it appears that phyter_clocks is a list head, based on the previous list_for_each, and that clock->list is intended to be a list element, given that it has just been initialized in dp83640_clock_init. Accordingly, switch the arguments to list_add_tail, which takes the list head as the second argument. Fixes: cb646e2b02b27 ("ptp: Added a clock driver for the National Semiconductor PHYTER.") Signed-off-by: Julia Lawall Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/phy/dp83640.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index 557f6510bad7..7e94526de51c 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c @@ -1108,7 +1108,7 @@ static struct dp83640_clock *dp83640_clock_get_bus(struct mii_bus *bus) goto out; } dp83640_clock_init(clock, bus); - list_add_tail(&phyter_clocks, &clock->list); + list_add_tail(&clock->list, &phyter_clocks); out: mutex_unlock(&phyter_clocks_lock); From ce0ca3d9fc5bc3812917d86dcf14ee88f8e34cbc Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sat, 25 Apr 2020 12:40:25 -0700 Subject: [PATCH 005/387] fq_codel: fix TCA_FQ_CODEL_DROP_BATCH_SIZE sanity checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 14695212d4cd8b0c997f6121b6df8520038ce076 ] My intent was to not let users set a zero drop_batch_size, it seems I once again messed with min()/max(). Fixes: 9d18562a2278 ("fq_codel: add batch ability to fq_codel_drop()") Signed-off-by: Eric Dumazet Acked-by: Toke Høiland-Jørgensen Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/sched/sch_fq_codel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c index 29b7465c9d8a..4f05956b9216 100644 --- a/net/sched/sch_fq_codel.c +++ b/net/sched/sch_fq_codel.c @@ -428,7 +428,7 @@ static int fq_codel_change(struct Qdisc *sch, struct nlattr *opt) q->quantum = max(256U, nla_get_u32(tb[TCA_FQ_CODEL_QUANTUM])); if (tb[TCA_FQ_CODEL_DROP_BATCH_SIZE]) - q->drop_batch_size = min(1U, nla_get_u32(tb[TCA_FQ_CODEL_DROP_BATCH_SIZE])); + q->drop_batch_size = max(1U, nla_get_u32(tb[TCA_FQ_CODEL_DROP_BATCH_SIZE])); if (tb[TCA_FQ_CODEL_MEMORY_LIMIT]) q->memory_limit = min(1U << 31, nla_get_u32(tb[TCA_FQ_CODEL_MEMORY_LIMIT])); From dc9d8659996df35ff927a3b25f2d8c3e6a5a83e2 Mon Sep 17 00:00:00 2001 From: Scott Dial Date: Fri, 24 Apr 2020 18:51:08 -0400 Subject: [PATCH 006/387] net: macsec: preserve ingress frame ordering [ Upstream commit ab046a5d4be4c90a3952a0eae75617b49c0cb01b ] MACsec decryption always occurs in a softirq context. Since the FPU may not be usable in the softirq context, the call to decrypt may be scheduled on the cryptd work queue. The cryptd work queue does not provide ordering guarantees. Therefore, preserving order requires masking out ASYNC implementations of gcm(aes). For instance, an Intel CPU with AES-NI makes available the generic-gcm-aesni driver from the aesni_intel module to implement gcm(aes). However, this implementation requires the FPU, so it is not always available to use from a softirq context, and will fallback to the cryptd work queue, which does not preserve frame ordering. With this change, such a system would select gcm_base(ctr(aes-aesni),ghash-generic). While the aes-aesni implementation prefers to use the FPU, it will fallback to the aes-asm implementation if unavailable. By using a synchronous version of gcm(aes), the decryption will complete before returning from crypto_aead_decrypt(). Therefore, the macsec_decrypt_done() callback will be called before returning from macsec_decrypt(). Thus, the order of calls to macsec_post_decrypt() for the frames is preserved. While it's presumable that the pure AES-NI version of gcm(aes) is more performant, the hybrid solution is capable of gigabit speeds on modest hardware. Regardless, preserving the order of frames is paramount for many network protocols (e.g., triggering TCP retries). Within the MACsec driver itself, the replay protection is tripped by the out-of-order frames, and can cause frames to be dropped. This bug has been present in this code since it was added in v4.6, however it may not have been noticed since not all CPUs have FPU offload available. Additionally, the bug manifests as occasional out-of-order packets that are easily misattributed to other network phenomena. When this code was added in v4.6, the crypto/gcm.c code did not restrict selection of the ghash function based on the ASYNC flag. For instance, x86 CPUs with PCLMULQDQ would select the ghash-clmulni driver instead of ghash-generic, which submits to the cryptd work queue if the FPU is busy. However, this bug was was corrected in v4.8 by commit b30bdfa86431afbafe15284a3ad5ac19b49b88e3, and was backported all the way back to the v3.14 stable branch, so this patch should be applicable back to the v4.6 stable branch. Signed-off-by: Scott Dial Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/macsec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index df2ee65a33e3..5defa29069ca 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -1315,7 +1315,8 @@ static struct crypto_aead *macsec_alloc_tfm(char *key, int key_len, int icv_len) struct crypto_aead *tfm; int ret; - tfm = crypto_alloc_aead("gcm(aes)", 0, 0); + /* Pick a sync gcm(aes) cipher to ensure order is preserved. */ + tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(tfm)) return tfm; From 4a0593e4fe3249d9f16d8419ca48c8b3a3b84cb3 Mon Sep 17 00:00:00 2001 From: Tariq Toukan Date: Mon, 4 May 2020 11:36:02 +0300 Subject: [PATCH 007/387] net/mlx4_core: Fix use of ENOSPC around mlx4_counter_alloc() [ Upstream commit 40e473071dbad04316ddc3613c3a3d1c75458299 ] When ENOSPC is set the idx is still valid and gets set to the global MLX4_SINK_COUNTER_INDEX. However gcc's static analysis cannot tell that ENOSPC is impossible from mlx4_cmd_imm() and gives this warning: drivers/net/ethernet/mellanox/mlx4/main.c:2552:28: warning: 'idx' may be used uninitialized in this function [-Wmaybe-uninitialized] 2552 | priv->def_counter[port] = idx; Also, when ENOSPC is returned mlx4_allocate_default_counters should not fail. Fixes: 6de5f7f6a1fa ("net/mlx4_core: Allocate default counter per port") Signed-off-by: Jason Gunthorpe Signed-off-by: Tariq Toukan Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mellanox/mlx4/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 781642d47133..751aac54f2d5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -2478,6 +2478,7 @@ static int mlx4_allocate_default_counters(struct mlx4_dev *dev) if (!err || err == -ENOSPC) { priv->def_counter[port] = idx; + err = 0; } else if (err == -ENOENT) { err = 0; continue; @@ -2527,7 +2528,8 @@ int mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx) MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); if (!err) *idx = get_param_l(&out_param); - + if (WARN_ON(err == -ENOSPC)) + err = -EINVAL; return err; } return __mlx4_counter_alloc(dev, idx); From fd6d7ca271d9043ae18cdf32af62f84a619f34c9 Mon Sep 17 00:00:00 2001 From: Matt Jolly Date: Sun, 3 May 2020 01:52:28 +1000 Subject: [PATCH 008/387] net: usb: qmi_wwan: add support for DW5816e MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 57c7f2bd758eed867295c81d3527fff4fab1ed74 ] Add support for Dell Wireless 5816e to drivers/net/usb/qmi_wwan.c Signed-off-by: Matt Jolly Acked-by: Bjørn Mork Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/qmi_wwan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 97f6b8130db3..5755eec00d7f 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -950,6 +950,7 @@ static const struct usb_device_id products[] = { {QMI_FIXED_INTF(0x413c, 0x81b3, 8)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */ {QMI_FIXED_INTF(0x413c, 0x81b6, 8)}, /* Dell Wireless 5811e */ {QMI_FIXED_INTF(0x413c, 0x81b6, 10)}, /* Dell Wireless 5811e */ + {QMI_FIXED_INTF(0x413c, 0x81cc, 8)}, /* Dell Wireless 5816e */ {QMI_FIXED_INTF(0x413c, 0x81d7, 0)}, /* Dell Wireless 5821e */ {QMI_FIXED_INTF(0x413c, 0x81d7, 1)}, /* Dell Wireless 5821e preproduction config */ {QMI_FIXED_INTF(0x413c, 0x81e0, 0)}, /* Dell Wireless 5821e with eSIM support*/ From 6f96cc39af5df5271bf2833a2063bedc84263afa Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sat, 25 Apr 2020 15:19:51 -0700 Subject: [PATCH 009/387] sch_choke: avoid potential panic in choke_reset() [ Upstream commit 8738c85c72b3108c9b9a369a39868ba5f8e10ae0 ] If choke_init() could not allocate q->tab, we would crash later in choke_reset(). BUG: KASAN: null-ptr-deref in memset include/linux/string.h:366 [inline] BUG: KASAN: null-ptr-deref in choke_reset+0x208/0x340 net/sched/sch_choke.c:326 Write of size 8 at addr 0000000000000000 by task syz-executor822/7022 CPU: 1 PID: 7022 Comm: syz-executor822 Not tainted 5.7.0-rc1-syzkaller #0 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+0x188/0x20d lib/dump_stack.c:118 __kasan_report.cold+0x5/0x4d mm/kasan/report.c:515 kasan_report+0x33/0x50 mm/kasan/common.c:625 check_memory_region_inline mm/kasan/generic.c:187 [inline] check_memory_region+0x141/0x190 mm/kasan/generic.c:193 memset+0x20/0x40 mm/kasan/common.c:85 memset include/linux/string.h:366 [inline] choke_reset+0x208/0x340 net/sched/sch_choke.c:326 qdisc_reset+0x6b/0x520 net/sched/sch_generic.c:910 dev_deactivate_queue.constprop.0+0x13c/0x240 net/sched/sch_generic.c:1138 netdev_for_each_tx_queue include/linux/netdevice.h:2197 [inline] dev_deactivate_many+0xe2/0xba0 net/sched/sch_generic.c:1195 dev_deactivate+0xf8/0x1c0 net/sched/sch_generic.c:1233 qdisc_graft+0xd25/0x1120 net/sched/sch_api.c:1051 tc_modify_qdisc+0xbab/0x1a00 net/sched/sch_api.c:1670 rtnetlink_rcv_msg+0x44e/0xad0 net/core/rtnetlink.c:5454 netlink_rcv_skb+0x15a/0x410 net/netlink/af_netlink.c:2469 netlink_unicast_kernel net/netlink/af_netlink.c:1303 [inline] netlink_unicast+0x537/0x740 net/netlink/af_netlink.c:1329 netlink_sendmsg+0x882/0xe10 net/netlink/af_netlink.c:1918 sock_sendmsg_nosec net/socket.c:652 [inline] sock_sendmsg+0xcf/0x120 net/socket.c:672 ____sys_sendmsg+0x6bf/0x7e0 net/socket.c:2362 ___sys_sendmsg+0x100/0x170 net/socket.c:2416 __sys_sendmsg+0xec/0x1b0 net/socket.c:2449 do_syscall_64+0xf6/0x7d0 arch/x86/entry/common.c:295 Fixes: 77e62da6e60c ("sch_choke: drop all packets in queue during reset") Signed-off-by: Eric Dumazet Reported-by: syzbot Cc: Cong Wang Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/sched/sch_choke.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c index 6125c17cffaf..d13e1de0b3a2 100644 --- a/net/sched/sch_choke.c +++ b/net/sched/sch_choke.c @@ -382,7 +382,8 @@ static void choke_reset(struct Qdisc *sch) sch->q.qlen = 0; sch->qstats.backlog = 0; - memset(q->tab, 0, (q->tab_mask + 1) * sizeof(struct sk_buff *)); + if (q->tab) + memset(q->tab, 0, (q->tab_mask + 1) * sizeof(struct sk_buff *)); q->head = q->tail = 0; red_restart(&q->vars); } From 019495fa4e5bbdeecb087a37417f9bad10da5f41 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 26 Apr 2020 18:19:07 -0700 Subject: [PATCH 010/387] sch_sfq: validate silly quantum values [ Upstream commit df4953e4e997e273501339f607b77953772e3559 ] syzbot managed to set up sfq so that q->scaled_quantum was zero, triggering an infinite loop in sfq_dequeue() More generally, we must only accept quantum between 1 and 2^18 - 7, meaning scaled_quantum must be in [1, 0x7FFF] range. Otherwise, we also could have a loop in sfq_dequeue() if scaled_quantum happens to be 0x8000, since slot->allot could indefinitely switch between 0 and 0x8000. Fixes: eeaeb068f139 ("sch_sfq: allow big packets and be fair") Signed-off-by: Eric Dumazet Reported-by: syzbot+0251e883fe39e7a0cb0a@syzkaller.appspotmail.com Cc: Jason A. Donenfeld Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/sched/sch_sfq.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index a8d82cb7f073..633e237a406c 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -635,6 +635,15 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt) if (ctl->divisor && (!is_power_of_2(ctl->divisor) || ctl->divisor > 65536)) return -EINVAL; + + /* slot->allot is a short, make sure quantum is not too big. */ + if (ctl->quantum) { + unsigned int scaled = SFQ_ALLOT_SIZE(ctl->quantum); + + if (scaled <= 0 || scaled > SHRT_MAX) + return -EINVAL; + } + if (ctl_v1 && !red_check_params(ctl_v1->qth_min, ctl_v1->qth_max, ctl_v1->Wlog)) return -EINVAL; From b081b91e6626f62fde4bd314d55d1c7201a5c1b4 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sun, 26 Apr 2020 16:24:42 -0400 Subject: [PATCH 011/387] bnxt_en: Fix VLAN acceleration handling in bnxt_fix_features(). [ Upstream commit c72cb303aa6c2ae7e4184f0081c6d11bf03fb96b ] The current logic in bnxt_fix_features() will inadvertently turn on both CTAG and STAG VLAN offload if the user tries to disable both. Fix it by checking that the user is trying to enable CTAG or STAG before enabling both. The logic is supposed to enable or disable both CTAG and STAG together. Fixes: 5a9f6b238e59 ("bnxt_en: Enable and disable RX CTAG and RX STAG VLAN acceleration together.") 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 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 736e550163e1..bbf382439a8b 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -5997,6 +5997,7 @@ static netdev_features_t bnxt_fix_features(struct net_device *dev, netdev_features_t features) { struct bnxt *bp = netdev_priv(dev); + netdev_features_t vlan_features; if ((features & NETIF_F_NTUPLE) && !bnxt_rfs_capable(bp)) features &= ~NETIF_F_NTUPLE; @@ -6004,12 +6005,14 @@ static netdev_features_t bnxt_fix_features(struct net_device *dev, /* Both CTAG and STAG VLAN accelaration on the RX side have to be * turned on or off together. */ - if ((features & (NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX)) != - (NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX)) { + vlan_features = features & (NETIF_F_HW_VLAN_CTAG_RX | + NETIF_F_HW_VLAN_STAG_RX); + if (vlan_features != (NETIF_F_HW_VLAN_CTAG_RX | + NETIF_F_HW_VLAN_STAG_RX)) { if (dev->features & NETIF_F_HW_VLAN_CTAG_RX) features &= ~(NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX); - else + else if (vlan_features) features |= NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX; } From c393b5917b18575fbd2fee7771244930e795b7da Mon Sep 17 00:00:00 2001 From: Moshe Shemesh Date: Sun, 21 Jul 2019 08:40:13 +0300 Subject: [PATCH 012/387] net/mlx5: Fix forced completion access non initialized command entry [ Upstream commit f3cb3cebe26ed4c8036adbd9448b372129d3c371 ] mlx5_cmd_flush() will trigger forced completions to all valid command entries. Triggered by an asynch event such as fast teardown it can happen at any stage of the command, including command initialization. It will trigger forced completion and that can lead to completion on an uninitialized command entry. Setting MLX5_CMD_ENT_STATE_PENDING_COMP only after command entry is initialized will ensure force completion is treated only if command entry is initialized. Fixes: 73dd3a4839c1 ("net/mlx5: Avoid using pending command interface slots") Signed-off-by: Moshe Shemesh Signed-off-by: Eran Ben Elisha Signed-off-by: Saeed Mahameed Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c index 1d5263c46eee..a1057efa2294 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c @@ -813,7 +813,6 @@ static void cmd_work_handler(struct work_struct *work) } cmd->ent_arr[ent->idx] = ent; - set_bit(MLX5_CMD_ENT_STATE_PENDING_COMP, &ent->state); lay = get_inst(cmd, ent->idx); ent->lay = lay; memset(lay, 0, sizeof(*lay)); @@ -835,6 +834,7 @@ static void cmd_work_handler(struct work_struct *work) if (ent->callback) schedule_delayed_work(&ent->cb_timeout_work, cb_timeout); + set_bit(MLX5_CMD_ENT_STATE_PENDING_COMP, &ent->state); /* Skip sending command to fw if internal error */ if (pci_channel_offline(dev->pdev) || From 7fb0515467c87a2589c3be163ed214933db8a46f Mon Sep 17 00:00:00 2001 From: Moshe Shemesh Date: Sun, 23 Feb 2020 03:27:41 +0200 Subject: [PATCH 013/387] net/mlx5: Fix command entry leak in Internal Error State [ Upstream commit cece6f432cca9f18900463ed01b97a152a03600a ] Processing commands by cmd_work_handler() while already in Internal Error State will result in entry leak, since the handler process force completion without doorbell. Forced completion doesn't release the entry and event completion will never arrive, so entry should be released. Fixes: 73dd3a4839c1 ("net/mlx5: Avoid using pending command interface slots") Signed-off-by: Moshe Shemesh Signed-off-by: Eran Ben Elisha Signed-off-by: Saeed Mahameed Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c index a1057efa2294..bb142a13d9f2 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c @@ -847,6 +847,10 @@ static void cmd_work_handler(struct work_struct *work) MLX5_SET(mbox_out, ent->out, syndrome, drv_synd); mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true); + /* no doorbell, no need to keep the entry */ + free_ent(cmd, ent->idx); + if (ent->callback) + free_cmd(ent); return; } From f4bcdb1b3f9b4d0651b38636b38955d7e7304731 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sun, 26 Apr 2020 16:24:40 -0400 Subject: [PATCH 014/387] bnxt_en: Improve AER slot reset. [ Upstream commit bae361c54fb6ac6eba3b4762f49ce14beb73ef13 ] Improve the slot reset sequence by disabling the device to prevent bad DMAs if slot reset fails. Return the proper result instead of always PCI_ERS_RESULT_RECOVERED to the caller. Fixes: 6316ea6db93d ("bnxt_en: Enable AER support.") 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 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index bbf382439a8b..421cbba9a3bc 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -7166,8 +7166,11 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev) result = PCI_ERS_RESULT_RECOVERED; } - if (result != PCI_ERS_RESULT_RECOVERED && netif_running(netdev)) - dev_close(netdev); + if (result != PCI_ERS_RESULT_RECOVERED) { + if (netif_running(netdev)) + dev_close(netdev); + pci_disable_device(pdev); + } rtnl_unlock(); @@ -7178,7 +7181,7 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev) err); /* non-fatal, continue */ } - return PCI_ERS_RESULT_RECOVERED; + return result; } /** From 37c75edf71205edcbaaca7e7f54a93f5bfc88cc9 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 22 Jan 2017 13:24:05 +0100 Subject: [PATCH 015/387] Revert "ACPI / video: Add force_native quirk for HP Pavilion dv6" commit fd25ea29093e275195d0ae8b2573021a1c98959f upstream. Revert commit 6276e53fa8c0 (ACPI / video: Add force_native quirk for HP Pavilion dv6). In the commit message for the quirk this revert removes I wrote: "Note that there are quite a few HP Pavilion dv6 variants, some woth ATI and some with NVIDIA hybrid gfx, both seem to need this quirk to have working backlight control. There are also some versions with only Intel integrated gfx, these may not need this quirk, but it should not hurt there." Unfortunately that seems wrong, I've already received 2 reports of this commit causing regressions on some dv6 variants (at least one of which actually has a nvidia GPU). So it seems that HP has made a mess here by using the same model-name both in marketing and in the DMI data for many different variants. Some of which need acpi_backlight=native for functional backlight control (as the quirk this commit reverts was doing), where as others are broken by it. So lets get back to the old sitation so as to avoid regressing on models which used to work without any kernel cmdline arguments before. Fixes: 6276e53fa8c0 (ACPI / video: Add force_native quirk for HP Pavilion dv6) Signed-off-by: Hans de Goede Signed-off-by: Rafael J. Wysocki Cc: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/video_detect.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index cdc47375178e..25f02f5fe0fd 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -314,17 +314,6 @@ static const struct dmi_system_id video_detect_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Dell System XPS L702X"), }, }, - { - /* https://bugzilla.redhat.com/show_bug.cgi?id=1204476 */ - /* https://bugs.launchpad.net/ubuntu/+source/linux-lts-trusty/+bug/1416940 */ - .callback = video_detect_force_native, - .ident = "HP Pavilion dv6", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv6 Notebook PC"), - }, - }, - { }, }; From 4e3f9b3f7c28ccfd30af8f2c07edca8131822419 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 14 May 2019 15:43:57 -0700 Subject: [PATCH 016/387] binfmt_elf: move brk out of mmap when doing direct loader exec commit bbdc6076d2e5d07db44e74c11b01a3e27ab90b32 upstream. Commmit eab09532d400 ("binfmt_elf: use ELF_ET_DYN_BASE only for PIE"), made changes in the rare case when the ELF loader was directly invoked (e.g to set a non-inheritable LD_LIBRARY_PATH, testing new versions of the loader), by moving into the mmap region to avoid both ET_EXEC and PIE binaries. This had the effect of also moving the brk region into mmap, which could lead to the stack and brk being arbitrarily close to each other. An unlucky process wouldn't get its requested stack size and stack allocations could end up scribbling on the heap. This is illustrated here. In the case of using the loader directly, brk (so helpfully identified as "[heap]") is allocated with the _loader_ not the binary. For example, with ASLR entirely disabled, you can see this more clearly: $ /bin/cat /proc/self/maps 555555554000-55555555c000 r-xp 00000000 ... /bin/cat 55555575b000-55555575c000 r--p 00007000 ... /bin/cat 55555575c000-55555575d000 rw-p 00008000 ... /bin/cat 55555575d000-55555577e000 rw-p 00000000 ... [heap] ... 7ffff7ff7000-7ffff7ffa000 r--p 00000000 ... [vvar] 7ffff7ffa000-7ffff7ffc000 r-xp 00000000 ... [vdso] 7ffff7ffc000-7ffff7ffd000 r--p 00027000 ... /lib/x86_64-linux-gnu/ld-2.27.so 7ffff7ffd000-7ffff7ffe000 rw-p 00028000 ... /lib/x86_64-linux-gnu/ld-2.27.so 7ffff7ffe000-7ffff7fff000 rw-p 00000000 ... 7ffffffde000-7ffffffff000 rw-p 00000000 ... [stack] $ /lib/x86_64-linux-gnu/ld-2.27.so /bin/cat /proc/self/maps ... 7ffff7bcc000-7ffff7bd4000 r-xp 00000000 ... /bin/cat 7ffff7bd4000-7ffff7dd3000 ---p 00008000 ... /bin/cat 7ffff7dd3000-7ffff7dd4000 r--p 00007000 ... /bin/cat 7ffff7dd4000-7ffff7dd5000 rw-p 00008000 ... /bin/cat 7ffff7dd5000-7ffff7dfc000 r-xp 00000000 ... /lib/x86_64-linux-gnu/ld-2.27.so 7ffff7fb2000-7ffff7fd6000 rw-p 00000000 ... 7ffff7ff7000-7ffff7ffa000 r--p 00000000 ... [vvar] 7ffff7ffa000-7ffff7ffc000 r-xp 00000000 ... [vdso] 7ffff7ffc000-7ffff7ffd000 r--p 00027000 ... /lib/x86_64-linux-gnu/ld-2.27.so 7ffff7ffd000-7ffff7ffe000 rw-p 00028000 ... /lib/x86_64-linux-gnu/ld-2.27.so 7ffff7ffe000-7ffff8020000 rw-p 00000000 ... [heap] 7ffffffde000-7ffffffff000 rw-p 00000000 ... [stack] The solution is to move brk out of mmap and into ELF_ET_DYN_BASE since nothing is there in the direct loader case (and ET_EXEC is still far away at 0x400000). Anything that ran before should still work (i.e. the ultimately-launched binary already had the brk very far from its text, so this should be no different from a COMPAT_BRK standpoint). The only risk I see here is that if someone started to suddenly depend on the entire memory space lower than the mmap region being available when launching binaries via a direct loader execs which seems highly unlikely, I'd hope: this would mean a binary would _not_ work when exec()ed normally. (Note that this is only done under CONFIG_ARCH_HAS_ELF_RANDOMIZATION when randomization is turned on.) Link: http://lkml.kernel.org/r/20190422225727.GA21011@beast Link: https://lkml.kernel.org/r/CAGXu5jJ5sj3emOT2QPxQkNQk0qbU6zEfu9=Omfhx_p0nCKPSjA@mail.gmail.com Fixes: eab09532d400 ("binfmt_elf: use ELF_ET_DYN_BASE only for PIE") Signed-off-by: Kees Cook Reported-by: Ali Saidi Cc: Ali Saidi Cc: Guenter Roeck Cc: Michal Hocko Cc: Matthew Wilcox Cc: Thomas Gleixner Cc: Jann Horn Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Cc: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- fs/binfmt_elf.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index e7e25a86bbff..327ebf0ff29b 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -1100,6 +1100,17 @@ static int load_elf_binary(struct linux_binprm *bprm) current->mm->start_stack = bprm->p; if ((current->flags & PF_RANDOMIZE) && (randomize_va_space > 1)) { + /* + * For architectures with ELF randomization, when executing + * a loader directly (i.e. no interpreter listed in ELF + * headers), move the brk area out of the mmap region + * (since it grows up, and may collide early with the stack + * growing down), and into the unused ELF_ET_DYN_BASE region. + */ + if (IS_ENABLED(CONFIG_ARCH_HAS_ELF_RANDOMIZE) && !interpreter) + current->mm->brk = current->mm->start_brk = + ELF_ET_DYN_BASE; + current->mm->brk = current->mm->start_brk = arch_randomize_brk(current->mm); #ifdef compat_brk_randomized From a8c9cebed0d47a0dcd7075418969e691521fa1c4 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Wed, 29 Apr 2020 17:52:18 +0200 Subject: [PATCH 017/387] USB: uas: add quirk for LaCie 2Big Quadra MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 9f04db234af691007bb785342a06abab5fb34474 upstream. This device needs US_FL_NO_REPORT_OPCODES to avoid going through prolonged error handling on enumeration. Signed-off-by: Oliver Neukum Reported-by: Julian Groß Cc: stable Link: https://lore.kernel.org/r/20200429155218.7308-1-oneukum@suse.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_uas.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h index 0eb8c67ee138..4df15faa66d7 100644 --- a/drivers/usb/storage/unusual_uas.h +++ b/drivers/usb/storage/unusual_uas.h @@ -41,6 +41,13 @@ * and don't forget to CC: the USB development list */ +/* Reported-by: Julian Groß */ +UNUSUAL_DEV(0x059f, 0x105f, 0x0000, 0x9999, + "LaCie", + "2Big Quadra USB3", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_REPORT_OPCODES), + /* * Apricorn USB3 dongle sometimes returns "USBSUSBSUSBS" in response to SCSI * commands in UAS mode. Observed with the 1.28 firmware; are there others? From 567299fef491d0d4033e5093424dc21835e1825d Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Wed, 15 Apr 2020 16:03:04 +0200 Subject: [PATCH 018/387] USB: serial: garmin_gps: add sanity checking for data length commit e9b3c610a05c1cdf8e959a6d89c38807ff758ee6 upstream. We must not process packets shorter than a packet ID Signed-off-by: Oliver Neukum Reported-and-tested-by: syzbot+d29e9263e13ce0b9f4fd@syzkaller.appspotmail.com Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/garmin_gps.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 91e7e3a166a5..c67a17faaa3c 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c @@ -1161,8 +1161,8 @@ static void garmin_read_process(struct garmin_data *garmin_data_p, send it directly to the tty port */ if (garmin_data_p->flags & FLAGS_QUEUING) { pkt_add(garmin_data_p, data, data_length); - } else if (bulk_data || - getLayerId(data) == GARMIN_LAYERID_APPL) { + } else if (bulk_data || (data_length >= sizeof(u32) && + getLayerId(data) == GARMIN_LAYERID_APPL)) { spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->flags |= APP_RESP_SEEN; From d6e55a35e9315aaafd26ff7ca838df3eb912d4c2 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (VMware)" Date: Wed, 6 May 2020 10:36:18 -0400 Subject: [PATCH 019/387] tracing: Add a vmalloc_sync_mappings() for safe measure commit 11f5efc3ab66284f7aaacc926e9351d658e2577b upstream. x86_64 lazily maps in the vmalloc pages, and the way this works with per_cpu areas can be complex, to say the least. Mappings may happen at boot up, and if nothing synchronizes the page tables, those page mappings may not be synced till they are used. This causes issues for anything that might touch one of those mappings in the path of the page fault handler. When one of those unmapped mappings is touched in the page fault handler, it will cause another page fault, which in turn will cause a page fault, and leave us in a loop of page faults. Commit 763802b53a42 ("x86/mm: split vmalloc_sync_all()") split vmalloc_sync_all() into vmalloc_sync_unmappings() and vmalloc_sync_mappings(), as on system exit, it did not need to do a full sync on x86_64 (although it still needed to be done on x86_32). By chance, the vmalloc_sync_all() would synchronize the page mappings done at boot up and prevent the per cpu area from being a problem for tracing in the page fault handler. But when that synchronization in the exit of a task became a nop, it caused the problem to appear. Link: https://lore.kernel.org/r/20200429054857.66e8e333@oasis.local.home Cc: stable@vger.kernel.org Fixes: 737223fbca3b1 ("tracing: Consolidate buffer allocation code") Reported-by: "Tzvetomir Stoyanov (VMware)" Suggested-by: Joerg Roedel Signed-off-by: Steven Rostedt (VMware) Signed-off-by: Greg Kroah-Hartman --- kernel/trace/trace.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 6a170a78b453..b2fb25aefb2f 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -7032,6 +7032,19 @@ static int allocate_trace_buffers(struct trace_array *tr, int size) */ allocate_snapshot = false; #endif + + /* + * Because of some magic with the way alloc_percpu() works on + * x86_64, we need to synchronize the pgd of all the tables, + * otherwise the trace events that happen in x86_64 page fault + * handlers can't cope with accessing the chance that a + * alloc_percpu()'d memory might be touched in the page fault trace + * event. Oh, and we need to audit all other alloc_percpu() and vmalloc() + * calls in tracing, because something might get triggered within a + * page fault trace event! + */ + vmalloc_sync_mappings(); + return 0; } From e254aa027fcf196ac3f91b8b0df417839d480974 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Thu, 7 May 2020 18:35:46 -0700 Subject: [PATCH 020/387] mm/page_alloc: fix watchdog soft lockups during set_zone_contiguous() commit e84fe99b68ce353c37ceeecc95dce9696c976556 upstream. Without CONFIG_PREEMPT, it can happen that we get soft lockups detected, e.g., while booting up. watchdog: BUG: soft lockup - CPU#0 stuck for 22s! [swapper/0:1] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.6.0-next-20200331+ #4 Hardware name: Red Hat KVM, BIOS 1.11.1-4.module+el8.1.0+4066+0f1aadab 04/01/2014 RIP: __pageblock_pfn_to_page+0x134/0x1c0 Call Trace: set_zone_contiguous+0x56/0x70 page_alloc_init_late+0x166/0x176 kernel_init_freeable+0xfa/0x255 kernel_init+0xa/0x106 ret_from_fork+0x35/0x40 The issue becomes visible when having a lot of memory (e.g., 4TB) assigned to a single NUMA node - a system that can easily be created using QEMU. Inside VMs on a hypervisor with quite some memory overcommit, this is fairly easy to trigger. Signed-off-by: David Hildenbrand Signed-off-by: Andrew Morton Reviewed-by: Pavel Tatashin Reviewed-by: Pankaj Gupta Reviewed-by: Baoquan He Reviewed-by: Shile Zhang Acked-by: Michal Hocko Cc: Kirill Tkhai Cc: Shile Zhang Cc: Pavel Tatashin Cc: Daniel Jordan Cc: Michal Hocko Cc: Alexander Duyck Cc: Baoquan He Cc: Oscar Salvador Cc: Link: http://lkml.kernel.org/r/20200416073417.5003-1-david@redhat.com Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- mm/page_alloc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index ef710e387862..de00e0fec484 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1408,6 +1408,7 @@ void set_zone_contiguous(struct zone *zone) if (!__pageblock_pfn_to_page(block_start_pfn, block_end_pfn, zone)) return; + cond_resched(); } /* We confirm that there is no hole */ From 221d9baf89150146a81883aeb4af32c6872c2459 Mon Sep 17 00:00:00 2001 From: George Spelvin Date: Sun, 8 Mar 2020 09:44:59 -0400 Subject: [PATCH 021/387] batman-adv: fix batadv_nc_random_weight_tq commit fd0c42c4dea54335967c5a86f15fc064235a2797 upstream. and change to pseudorandom numbers, as this is a traffic dithering operation that doesn't need crypto-grade. The previous code operated in 4 steps: 1. Generate a random byte 0 <= rand_tq <= 255 2. Multiply it by BATADV_TQ_MAX_VALUE - tq 3. Divide by 255 (= BATADV_TQ_MAX_VALUE) 4. Return BATADV_TQ_MAX_VALUE - rand_tq This would apperar to scale (BATADV_TQ_MAX_VALUE - tq) by a random value between 0/255 and 255/255. But! The intermediate value between steps 3 and 4 is stored in a u8 variable. So it's truncated, and most of the time, is less than 255, after which the division produces 0. Specifically, if tq is odd, the product is always even, and can never be 255. If tq is even, there's exactly one random byte value that will produce a product byte of 255. Thus, the return value is 255 (511/512 of the time) or 254 (1/512 of the time). If we assume that the truncation is a bug, and the code is meant to scale the input, a simpler way of looking at it is that it's returning a random value between tq and BATADV_TQ_MAX_VALUE, inclusive. Well, we have an optimized function for doing just that. Fixes: 3c12de9a5c75 ("batman-adv: network coding - code and transmit packets if possible") Signed-off-by: George Spelvin Signed-off-by: Sven Eckelmann Signed-off-by: Simon Wunderlich Signed-off-by: Greg Kroah-Hartman --- net/batman-adv/network-coding.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c index a7b5cf08d363..09549885cd14 100644 --- a/net/batman-adv/network-coding.c +++ b/net/batman-adv/network-coding.c @@ -1012,15 +1012,8 @@ static struct batadv_nc_path *batadv_nc_get_path(struct batadv_priv *bat_priv, */ static u8 batadv_nc_random_weight_tq(u8 tq) { - u8 rand_val, rand_tq; - - get_random_bytes(&rand_val, sizeof(rand_val)); - /* randomize the estimated packet loss (max TQ - estimated TQ) */ - rand_tq = rand_val * (BATADV_TQ_MAX_VALUE - tq); - - /* normalize the randomized packet loss */ - rand_tq /= BATADV_TQ_MAX_VALUE; + u8 rand_tq = prandom_u32_max(BATADV_TQ_MAX_VALUE + 1 - tq); /* convert to (randomized) estimated tq again */ return BATADV_TQ_MAX_VALUE - rand_tq; From f9d0df8c4c9e709c3c0b77de917e260ac0bd9f09 Mon Sep 17 00:00:00 2001 From: Xiyu Yang Date: Wed, 15 Apr 2020 16:31:50 +0800 Subject: [PATCH 022/387] batman-adv: Fix refcnt leak in batadv_show_throughput_override commit f872de8185acf1b48b954ba5bd8f9bc0a0d14016 upstream. batadv_show_throughput_override() invokes batadv_hardif_get_by_netdev(), which gets a batadv_hard_iface object from net_dev with increased refcnt and its reference is assigned to a local pointer 'hard_iface'. When batadv_show_throughput_override() returns, "hard_iface" becomes invalid, so the refcount should be decreased to keep refcount balanced. The issue happens in the normal path of batadv_show_throughput_override(), which forgets to decrease the refcnt increased by batadv_hardif_get_by_netdev() before the function returns, causing a refcnt leak. Fix this issue by calling batadv_hardif_put() before the batadv_show_throughput_override() returns in the normal path. Fixes: 0b5ecc6811bd ("batman-adv: add throughput override attribute to hard_ifaces") Signed-off-by: Xiyu Yang Signed-off-by: Xin Tan Signed-off-by: Sven Eckelmann Signed-off-by: Simon Wunderlich Signed-off-by: Greg Kroah-Hartman --- net/batman-adv/sysfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c index 31d7e239a1fd..d3fb5396f947 100644 --- a/net/batman-adv/sysfs.c +++ b/net/batman-adv/sysfs.c @@ -1120,6 +1120,7 @@ static ssize_t batadv_show_throughput_override(struct kobject *kobj, tp_override = atomic_read(&hard_iface->bat_v.throughput_override); + batadv_hardif_put(hard_iface); return sprintf(buff, "%u.%u MBit\n", tp_override / 10, tp_override % 10); } From c62006cf13a7071e40d879097bd280517e05a70e Mon Sep 17 00:00:00 2001 From: Xiyu Yang Date: Wed, 15 Apr 2020 16:35:21 +0800 Subject: [PATCH 023/387] batman-adv: Fix refcnt leak in batadv_store_throughput_override commit 6107c5da0fca8b50b4d3215e94d619d38cc4a18c upstream. batadv_show_throughput_override() invokes batadv_hardif_get_by_netdev(), which gets a batadv_hard_iface object from net_dev with increased refcnt and its reference is assigned to a local pointer 'hard_iface'. When batadv_store_throughput_override() returns, "hard_iface" becomes invalid, so the refcount should be decreased to keep refcount balanced. The issue happens in one error path of batadv_store_throughput_override(). When batadv_parse_throughput() returns NULL, the refcnt increased by batadv_hardif_get_by_netdev() is not decreased, causing a refcnt leak. Fix this issue by jumping to "out" label when batadv_parse_throughput() returns NULL. Fixes: 0b5ecc6811bd ("batman-adv: add throughput override attribute to hard_ifaces") Signed-off-by: Xiyu Yang Signed-off-by: Xin Tan Signed-off-by: Sven Eckelmann Signed-off-by: Simon Wunderlich Signed-off-by: Greg Kroah-Hartman --- net/batman-adv/sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c index d3fb5396f947..121e9e7d28cc 100644 --- a/net/batman-adv/sysfs.c +++ b/net/batman-adv/sysfs.c @@ -1087,7 +1087,7 @@ static ssize_t batadv_store_throughput_override(struct kobject *kobj, ret = batadv_parse_throughput(net_dev, buff, "throughput_override", &tp_override); if (!ret) - return count; + goto out; old_tp_override = atomic_read(&hard_iface->bat_v.throughput_override); if (old_tp_override == tp_override) From aba0fd6a16ef9a562d22b81f7f3cd365ba9bc0fa Mon Sep 17 00:00:00 2001 From: Xiyu Yang Date: Mon, 20 Apr 2020 13:37:20 +0800 Subject: [PATCH 024/387] batman-adv: Fix refcnt leak in batadv_v_ogm_process commit 6f91a3f7af4186099dd10fa530dd7e0d9c29747d upstream. batadv_v_ogm_process() invokes batadv_hardif_neigh_get(), which returns a reference of the neighbor object to "hardif_neigh" with increased refcount. When batadv_v_ogm_process() returns, "hardif_neigh" becomes invalid, so the refcount should be decreased to keep refcount balanced. The reference counting issue happens in one exception handling paths of batadv_v_ogm_process(). When batadv_v_ogm_orig_get() fails to get the orig node and returns NULL, the refcnt increased by batadv_hardif_neigh_get() is not decreased, causing a refcnt leak. Fix this issue by jumping to "out" label when batadv_v_ogm_orig_get() fails to get the orig node. Fixes: 9323158ef9f4 ("batman-adv: OGMv2 - implement originators logic") Signed-off-by: Xiyu Yang Signed-off-by: Xin Tan Signed-off-by: Sven Eckelmann Signed-off-by: Simon Wunderlich Signed-off-by: Greg Kroah-Hartman --- net/batman-adv/bat_v_ogm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c index b0cae59bd327..d2e6885479cb 100644 --- a/net/batman-adv/bat_v_ogm.c +++ b/net/batman-adv/bat_v_ogm.c @@ -709,7 +709,7 @@ static void batadv_v_ogm_process(const struct sk_buff *skb, int ogm_offset, orig_node = batadv_v_ogm_orig_get(bat_priv, ogm_packet->orig); if (!orig_node) - return; + goto out; neigh_node = batadv_neigh_node_get_or_create(orig_node, if_incoming, ethhdr->h_source); From 7c2842fe88cb2ffa9409729f7b67bf89ffebd457 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Sat, 25 Apr 2020 05:03:00 -0500 Subject: [PATCH 025/387] objtool: Fix stack offset tracking for indirect CFAs commit d8dd25a461e4eec7190cb9d66616aceacc5110ad upstream. When the current frame address (CFA) is stored on the stack (i.e., cfa->base == CFI_SP_INDIRECT), objtool neglects to adjust the stack offset when there are subsequent pushes or pops. This results in bad ORC data at the end of the ENTER_IRQ_STACK macro, when it puts the previous stack pointer on the stack and does a subsequent push. This fixes the following unwinder warning: WARNING: can't dereference registers at 00000000f0a6bdba for ip interrupt_entry+0x9f/0xa0 Fixes: 627fce14809b ("objtool: Add ORC unwind table generation") Reported-by: Vince Weaver Reported-by: Dave Jones Reported-by: Steven Rostedt Reported-by: Vegard Nossum Reported-by: Joe Mario Reviewed-by: Miroslav Benes Signed-off-by: Josh Poimboeuf Signed-off-by: Ingo Molnar Cc: Andy Lutomirski Cc: Jann Horn Cc: Peter Zijlstra Cc: Thomas Gleixner Link: https://lore.kernel.org/r/853d5d691b29e250333332f09b8e27410b2d9924.1587808742.git.jpoimboe@redhat.com Signed-off-by: Greg Kroah-Hartman --- tools/objtool/check.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 360845926f66..b0b8ba9b800c 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -1264,7 +1264,7 @@ static int update_insn_state_regs(struct instruction *insn, struct insn_state *s struct cfi_reg *cfa = &state->cfa; struct stack_op *op = &insn->stack_op; - if (cfa->base != CFI_SP) + if (cfa->base != CFI_SP && cfa->base != CFI_SP_INDIRECT) return 0; /* push */ From e03e0f1ae25fb3bb24e146b89899faa1167f5b57 Mon Sep 17 00:00:00 2001 From: Ivan Delalande Date: Thu, 7 May 2020 18:35:53 -0700 Subject: [PATCH 026/387] scripts/decodecode: fix trapping instruction formatting commit e08df079b23e2e982df15aa340bfbaf50f297504 upstream. If the trapping instruction contains a ':', for a memory access through segment registers for example, the sed substitution will insert the '*' marker in the middle of the instruction instead of the line address: 2b: 65 48 0f c7 0f cmpxchg16b %gs:*(%rdi) <-- trapping instruction I started to think I had forgotten some quirk of the assembly syntax before noticing that it was actually coming from the script. Fix it to add the address marker at the right place for these instructions: 28: 49 8b 06 mov (%r14),%rax 2b:* 65 48 0f c7 0f cmpxchg16b %gs:(%rdi) <-- trapping instruction 30: 0f 94 c0 sete %al Fixes: 18ff44b189e2 ("scripts/decodecode: make faulting insn ptr more robust") Signed-off-by: Ivan Delalande Signed-off-by: Andrew Morton Reviewed-by: Borislav Petkov Link: http://lkml.kernel.org/r/20200419223653.GA31248@visor Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- scripts/decodecode | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/decodecode b/scripts/decodecode index d8824f37acce..aae7a035242b 100755 --- a/scripts/decodecode +++ b/scripts/decodecode @@ -98,7 +98,7 @@ faultlinenum=$(( $(wc -l $T.oo | cut -d" " -f1) - \ faultline=`cat $T.dis | head -1 | cut -d":" -f2-` faultline=`echo "$faultline" | sed -e 's/\[/\\\[/g; s/\]/\\\]/g'` -cat $T.oo | sed -e "${faultlinenum}s/^\(.*:\)\(.*\)/\1\*\2\t\t<-- trapping instruction/" +cat $T.oo | sed -e "${faultlinenum}s/^\([^:]*:\)\(.*\)/\1\*\2\t\t<-- trapping instruction/" echo cat $T.aa cleanup From c7adf03146c87ad72b44bc1f57e346ed330271fa Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Thu, 26 Sep 2019 10:15:25 -0700 Subject: [PATCH 027/387] binfmt_elf: Do not move brk for INTERP-less ET_EXEC commit 7be3cb019db1cbd5fd5ffe6d64a23fefa4b6f229 upstream. When brk was moved for binaries without an interpreter, it should have been limited to ET_DYN only. In other words, the special case was an ET_DYN that lacks an INTERP, not just an executable that lacks INTERP. The bug manifested for giant static executables, where the brk would end up in the middle of the text area on 32-bit architectures. Reported-and-tested-by: Richard Kojedzinszky Fixes: bbdc6076d2e5 ("binfmt_elf: move brk out of mmap when doing direct loader exec") Cc: stable@vger.kernel.org Signed-off-by: Kees Cook Signed-off-by: Linus Torvalds Cc: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- fs/binfmt_elf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 327ebf0ff29b..e78553d51837 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -1107,7 +1107,8 @@ static int load_elf_binary(struct linux_binprm *bprm) * (since it grows up, and may collide early with the stack * growing down), and into the unused ELF_ET_DYN_BASE region. */ - if (IS_ENABLED(CONFIG_ARCH_HAS_ELF_RANDOMIZE) && !interpreter) + if (IS_ENABLED(CONFIG_ARCH_HAS_ELF_RANDOMIZE) && + loc->elf_ex.e_type == ET_DYN && !interpreter) current->mm->brk = current->mm->start_brk = ELF_ET_DYN_BASE; From e94c149b8aed0bd1035ad24354af02eee9481da9 Mon Sep 17 00:00:00 2001 From: Shijie Luo Date: Mon, 10 Feb 2020 20:17:52 -0500 Subject: [PATCH 028/387] ext4: add cond_resched() to ext4_protect_reserved_inode commit af133ade9a40794a37104ecbcc2827c0ea373a3c upstream. When journal size is set too big by "mkfs.ext4 -J size=", or when we mount a crafted image to make journal inode->i_size too big, the loop, "while (i < num)", holds cpu too long. This could cause soft lockup. [ 529.357541] Call trace: [ 529.357551] dump_backtrace+0x0/0x198 [ 529.357555] show_stack+0x24/0x30 [ 529.357562] dump_stack+0xa4/0xcc [ 529.357568] watchdog_timer_fn+0x300/0x3e8 [ 529.357574] __hrtimer_run_queues+0x114/0x358 [ 529.357576] hrtimer_interrupt+0x104/0x2d8 [ 529.357580] arch_timer_handler_virt+0x38/0x58 [ 529.357584] handle_percpu_devid_irq+0x90/0x248 [ 529.357588] generic_handle_irq+0x34/0x50 [ 529.357590] __handle_domain_irq+0x68/0xc0 [ 529.357593] gic_handle_irq+0x6c/0x150 [ 529.357595] el1_irq+0xb8/0x140 [ 529.357599] __ll_sc_atomic_add_return_acquire+0x14/0x20 [ 529.357668] ext4_map_blocks+0x64/0x5c0 [ext4] [ 529.357693] ext4_setup_system_zone+0x330/0x458 [ext4] [ 529.357717] ext4_fill_super+0x2170/0x2ba8 [ext4] [ 529.357722] mount_bdev+0x1a8/0x1e8 [ 529.357746] ext4_mount+0x44/0x58 [ext4] [ 529.357748] mount_fs+0x50/0x170 [ 529.357752] vfs_kern_mount.part.9+0x54/0x188 [ 529.357755] do_mount+0x5ac/0xd78 [ 529.357758] ksys_mount+0x9c/0x118 [ 529.357760] __arm64_sys_mount+0x28/0x38 [ 529.357764] el0_svc_common+0x78/0x130 [ 529.357766] el0_svc_handler+0x38/0x78 [ 529.357769] el0_svc+0x8/0xc [ 541.356516] watchdog: BUG: soft lockup - CPU#0 stuck for 23s! [mount:18674] Link: https://lore.kernel.org/r/20200211011752.29242-1-luoshijie1@huawei.com Reviewed-by: Jan Kara Signed-off-by: Shijie Luo Signed-off-by: Theodore Ts'o Cc: stable@kernel.org Signed-off-by: Ben Hutchings Signed-off-by: Sasha Levin --- fs/ext4/block_validity.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ext4/block_validity.c b/fs/ext4/block_validity.c index d31d93ee5e76..45c7b0f9a8e3 100644 --- a/fs/ext4/block_validity.c +++ b/fs/ext4/block_validity.c @@ -152,6 +152,7 @@ static int ext4_protect_reserved_inode(struct super_block *sb, u32 ino) return PTR_ERR(inode); num = (inode->i_size + sb->s_blocksize - 1) >> sb->s_blocksize_bits; while (i < num) { + cond_resched(); map.m_lblk = i; map.m_len = num - i; n = ext4_map_blocks(NULL, inode, &map, 0); From 5cc5fa7a8778da20941e7f78edc87090e34cb515 Mon Sep 17 00:00:00 2001 From: Sabrina Dubroca Date: Wed, 4 Dec 2019 15:35:52 +0100 Subject: [PATCH 029/387] net: ipv6: add net argument to ip6_dst_lookup_flow commit c4e85f73afb6384123e5ef1bba3315b2e3ad031e upstream. This will be used in the conversion of ipv6_stub to ip6_dst_lookup_flow, as some modules currently pass a net argument without a socket to ip6_dst_lookup. This is equivalent to commit 343d60aada5a ("ipv6: change ipv6_stub_impl.ipv6_dst_lookup to take net argument"). Signed-off-by: Sabrina Dubroca Signed-off-by: David S. Miller [bwh: Backported to 4.9: adjust context] Signed-off-by: Ben Hutchings Signed-off-by: Sasha Levin --- include/net/ipv6.h | 2 +- net/dccp/ipv6.c | 6 +++--- net/ipv6/af_inet6.c | 2 +- net/ipv6/datagram.c | 2 +- net/ipv6/inet6_connection_sock.c | 4 ++-- net/ipv6/ip6_output.c | 8 ++++---- net/ipv6/raw.c | 2 +- net/ipv6/syncookies.c | 2 +- net/ipv6/tcp_ipv6.c | 4 ++-- net/l2tp/l2tp_ip6.c | 2 +- net/sctp/ipv6.c | 4 ++-- 11 files changed, 19 insertions(+), 19 deletions(-) diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 168009eef5e4..1a48e10ec617 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -856,7 +856,7 @@ static inline struct sk_buff *ip6_finish_skb(struct sock *sk) int ip6_dst_lookup(struct net *net, struct sock *sk, struct dst_entry **dst, struct flowi6 *fl6); -struct dst_entry *ip6_dst_lookup_flow(const struct sock *sk, struct flowi6 *fl6, +struct dst_entry *ip6_dst_lookup_flow(struct net *net, const struct sock *sk, struct flowi6 *fl6, const struct in6_addr *final_dst); struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6, const struct in6_addr *final_dst); diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 87c513b5ff2e..9438873fc3c8 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -209,7 +209,7 @@ static int dccp_v6_send_response(const struct sock *sk, struct request_sock *req final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final); rcu_read_unlock(); - dst = ip6_dst_lookup_flow(sk, &fl6, final_p); + dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p); if (IS_ERR(dst)) { err = PTR_ERR(dst); dst = NULL; @@ -280,7 +280,7 @@ static void dccp_v6_ctl_send_reset(const struct sock *sk, struct sk_buff *rxskb) security_skb_classify_flow(rxskb, flowi6_to_flowi(&fl6)); /* sk = NULL, but it is safe for now. RST socket required. */ - dst = ip6_dst_lookup_flow(ctl_sk, &fl6, NULL); + dst = ip6_dst_lookup_flow(sock_net(ctl_sk), ctl_sk, &fl6, NULL); if (!IS_ERR(dst)) { skb_dst_set(skb, dst); ip6_xmit(ctl_sk, skb, &fl6, 0, NULL, 0); @@ -889,7 +889,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, opt = rcu_dereference_protected(np->opt, lockdep_sock_is_held(sk)); final_p = fl6_update_dst(&fl6, opt, &final); - dst = ip6_dst_lookup_flow(sk, &fl6, final_p); + dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p); if (IS_ERR(dst)) { err = PTR_ERR(dst); goto failure; diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 8885dbad217b..2e91637c9d49 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -702,7 +702,7 @@ int inet6_sk_rebuild_header(struct sock *sk) &final); rcu_read_unlock(); - dst = ip6_dst_lookup_flow(sk, &fl6, final_p); + dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p); if (IS_ERR(dst)) { sk->sk_route_caps = 0; sk->sk_err_soft = -PTR_ERR(dst); diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 956af11e9ba3..58929622de0e 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -87,7 +87,7 @@ int ip6_datagram_dst_update(struct sock *sk, bool fix_sk_saddr) final_p = fl6_update_dst(&fl6, opt, &final); rcu_read_unlock(); - dst = ip6_dst_lookup_flow(sk, &fl6, final_p); + dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p); if (IS_ERR(dst)) { err = PTR_ERR(dst); goto out; diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index 798a0950e9a6..b760ccec44d3 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c @@ -90,7 +90,7 @@ struct dst_entry *inet6_csk_route_req(const struct sock *sk, fl6->fl6_sport = htons(ireq->ir_num); security_req_classify_flow(req, flowi6_to_flowi(fl6)); - dst = ip6_dst_lookup_flow(sk, fl6, final_p); + dst = ip6_dst_lookup_flow(sock_net(sk), sk, fl6, final_p); if (IS_ERR(dst)) return NULL; @@ -144,7 +144,7 @@ static struct dst_entry *inet6_csk_route_socket(struct sock *sk, dst = __inet6_csk_dst_check(sk, np->dst_cookie); if (!dst) { - dst = ip6_dst_lookup_flow(sk, fl6, final_p); + dst = ip6_dst_lookup_flow(sock_net(sk), sk, fl6, final_p); if (!IS_ERR(dst)) ip6_dst_store(sk, dst, NULL, NULL); diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 11407dd6bc7c..d93a98dfe52d 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -1075,19 +1075,19 @@ EXPORT_SYMBOL_GPL(ip6_dst_lookup); * It returns a valid dst pointer on success, or a pointer encoded * error code. */ -struct dst_entry *ip6_dst_lookup_flow(const struct sock *sk, struct flowi6 *fl6, +struct dst_entry *ip6_dst_lookup_flow(struct net *net, const struct sock *sk, struct flowi6 *fl6, const struct in6_addr *final_dst) { struct dst_entry *dst = NULL; int err; - err = ip6_dst_lookup_tail(sock_net(sk), sk, &dst, fl6); + err = ip6_dst_lookup_tail(net, sk, &dst, fl6); if (err) return ERR_PTR(err); if (final_dst) fl6->daddr = *final_dst; - return xfrm_lookup_route(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0); + return xfrm_lookup_route(net, dst, flowi6_to_flowi(fl6), sk, 0); } EXPORT_SYMBOL_GPL(ip6_dst_lookup_flow); @@ -1112,7 +1112,7 @@ struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6, dst = ip6_sk_dst_check(sk, dst, fl6); if (!dst) - dst = ip6_dst_lookup_flow(sk, fl6, final_dst); + dst = ip6_dst_lookup_flow(sock_net(sk), sk, fl6, final_dst); return dst; } diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 301978df650e..47acd20d4e1f 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -920,7 +920,7 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel); - dst = ip6_dst_lookup_flow(sk, &fl6, final_p); + dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p); if (IS_ERR(dst)) { err = PTR_ERR(dst); goto out; diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index 7a86433d8896..4834015b27f4 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c @@ -230,7 +230,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) fl6.fl6_sport = inet_sk(sk)->inet_sport; security_req_classify_flow(req, flowi6_to_flowi(&fl6)); - dst = ip6_dst_lookup_flow(sk, &fl6, final_p); + dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p); if (IS_ERR(dst)) goto out_free; } diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 4953466cf98f..7b336b7803ff 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -244,7 +244,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); - dst = ip6_dst_lookup_flow(sk, &fl6, final_p); + dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p); if (IS_ERR(dst)) { err = PTR_ERR(dst); goto failure; @@ -841,7 +841,7 @@ static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32 * Underlying function will use this to retrieve the network * namespace */ - dst = ip6_dst_lookup_flow(ctl_sk, &fl6, NULL); + dst = ip6_dst_lookup_flow(sock_net(ctl_sk), ctl_sk, &fl6, NULL); if (!IS_ERR(dst)) { skb_dst_set(buff, dst); ip6_xmit(ctl_sk, buff, &fl6, fl6.flowi6_mark, NULL, tclass); diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c index 423cb095ad37..28274f397c55 100644 --- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c @@ -620,7 +620,7 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel); - dst = ip6_dst_lookup_flow(sk, &fl6, final_p); + dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl6, final_p); if (IS_ERR(dst)) { err = PTR_ERR(dst); goto out; diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 34ab7f92f064..50bc8c4ca906 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -269,7 +269,7 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final); rcu_read_unlock(); - dst = ip6_dst_lookup_flow(sk, fl6, final_p); + dst = ip6_dst_lookup_flow(sock_net(sk), sk, fl6, final_p); if (!asoc || saddr) { t->dst = dst; memcpy(fl, &_fl, sizeof(_fl)); @@ -327,7 +327,7 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, fl6->saddr = laddr->a.v6.sin6_addr; fl6->fl6_sport = laddr->a.v6.sin6_port; final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final); - bdst = ip6_dst_lookup_flow(sk, fl6, final_p); + bdst = ip6_dst_lookup_flow(sock_net(sk), sk, fl6, final_p); if (IS_ERR(bdst)) continue; From badbe56cb62faabe946fed8d7e8a25c009a95e3b Mon Sep 17 00:00:00 2001 From: Sabrina Dubroca Date: Wed, 4 Dec 2019 15:35:53 +0100 Subject: [PATCH 030/387] net: ipv6_stub: use ip6_dst_lookup_flow instead of ip6_dst_lookup commit 6c8991f41546c3c472503dff1ea9daaddf9331c2 upstream. ipv6_stub uses the ip6_dst_lookup function to allow other modules to perform IPv6 lookups. However, this function skips the XFRM layer entirely. All users of ipv6_stub->ip6_dst_lookup use ip_route_output_flow (via the ip_route_output_key and ip_route_output helpers) for their IPv4 lookups, which calls xfrm_lookup_route(). This patch fixes this inconsistent behavior by switching the stub to ip6_dst_lookup_flow, which also calls xfrm_lookup_route(). This requires some changes in all the callers, as these two functions take different arguments and have different return types. Fixes: 5f81bd2e5d80 ("ipv6: export a stub for IPv6 symbols used by vxlan") Reported-by: Xiumei Mu Signed-off-by: Sabrina Dubroca Signed-off-by: David S. Miller [bwh: Backported to 4.9: - Drop changes in lwt_bpf.c and mlx5 - Initialise "dst" in drivers/infiniband/core/addr.c:addr_resolve() to avoid introducing a spurious "may be used uninitialised" warning - Adjust filename, context, indentation] Signed-off-by: Ben Hutchings Signed-off-by: Sasha Levin --- drivers/infiniband/core/addr.c | 8 ++++---- drivers/infiniband/sw/rxe/rxe_net.c | 8 +++++--- drivers/net/geneve.c | 4 +++- drivers/net/vxlan.c | 10 ++++------ include/net/addrconf.h | 6 ++++-- net/ipv6/addrconf_core.c | 11 ++++++----- net/ipv6/af_inet6.c | 2 +- net/mpls/af_mpls.c | 7 +++---- net/tipc/udp_media.c | 9 ++++++--- 9 files changed, 36 insertions(+), 29 deletions(-) diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index f7d23c1081dc..68eed45b8600 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -453,16 +453,15 @@ static int addr6_resolve(struct sockaddr_in6 *src_in, struct flowi6 fl6; struct dst_entry *dst; struct rt6_info *rt; - int ret; memset(&fl6, 0, sizeof fl6); fl6.daddr = dst_in->sin6_addr; fl6.saddr = src_in->sin6_addr; fl6.flowi6_oif = addr->bound_dev_if; - ret = ipv6_stub->ipv6_dst_lookup(addr->net, NULL, &dst, &fl6); - if (ret < 0) - return ret; + dst = ipv6_stub->ipv6_dst_lookup_flow(addr->net, NULL, &fl6, NULL); + if (IS_ERR(dst)) + return PTR_ERR(dst); rt = (struct rt6_info *)dst; if (ipv6_addr_any(&src_in->sin6_addr)) { @@ -552,6 +551,7 @@ static int addr_resolve(struct sockaddr *src_in, const struct sockaddr_in6 *dst_in6 = (const struct sockaddr_in6 *)dst_in; + dst = NULL; ret = addr6_resolve((struct sockaddr_in6 *)src_in, dst_in6, addr, &dst); diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c index f4f3942ebbd1..d19e003e8381 100644 --- a/drivers/infiniband/sw/rxe/rxe_net.c +++ b/drivers/infiniband/sw/rxe/rxe_net.c @@ -182,10 +182,12 @@ static struct dst_entry *rxe_find_route6(struct net_device *ndev, memcpy(&fl6.daddr, daddr, sizeof(*daddr)); fl6.flowi6_proto = IPPROTO_UDP; - if (unlikely(ipv6_stub->ipv6_dst_lookup(sock_net(recv_sockets.sk6->sk), - recv_sockets.sk6->sk, &ndst, &fl6))) { + ndst = ipv6_stub->ipv6_dst_lookup_flow(sock_net(recv_sockets.sk6->sk), + recv_sockets.sk6->sk, &fl6, + NULL); + if (unlikely(IS_ERR(ndst))) { pr_err_ratelimited("no route to %pI6\n", daddr); - goto put; + return NULL; } if (unlikely(ndst->error)) { diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index 92ad43e53c72..35d8c636de12 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -835,7 +835,9 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb, return dst; } - if (ipv6_stub->ipv6_dst_lookup(geneve->net, gs6->sock->sk, &dst, fl6)) { + dst = ipv6_stub->ipv6_dst_lookup_flow(geneve->net, gs6->sock->sk, fl6, + NULL); + if (IS_ERR(dst)) { netdev_dbg(dev, "no route to %pI6\n", &fl6->daddr); return ERR_PTR(-ENETUNREACH); } diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index bc4542d9a08d..58ddb6c90418 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -1881,7 +1881,6 @@ static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan, bool use_cache = ip_tunnel_dst_cache_usable(skb, info); struct dst_entry *ndst; struct flowi6 fl6; - int err; if (!sock6) return ERR_PTR(-EIO); @@ -1902,11 +1901,10 @@ static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan, fl6.flowi6_mark = skb->mark; fl6.flowi6_proto = IPPROTO_UDP; - err = ipv6_stub->ipv6_dst_lookup(vxlan->net, - sock6->sock->sk, - &ndst, &fl6); - if (err < 0) - return ERR_PTR(err); + ndst = ipv6_stub->ipv6_dst_lookup_flow(vxlan->net, sock6->sock->sk, + &fl6, NULL); + if (unlikely(IS_ERR(ndst))) + return ERR_PTR(-ENETUNREACH); *saddr = fl6.saddr; if (use_cache) diff --git a/include/net/addrconf.h b/include/net/addrconf.h index b8ee8a113e32..019b06c035a8 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -206,8 +206,10 @@ struct ipv6_stub { const struct in6_addr *addr); int (*ipv6_sock_mc_drop)(struct sock *sk, int ifindex, const struct in6_addr *addr); - int (*ipv6_dst_lookup)(struct net *net, struct sock *sk, - struct dst_entry **dst, struct flowi6 *fl6); + struct dst_entry *(*ipv6_dst_lookup_flow)(struct net *net, + const struct sock *sk, + struct flowi6 *fl6, + const struct in6_addr *final_dst); void (*udpv6_encap_enable)(void); void (*ndisc_send_na)(struct net_device *dev, const struct in6_addr *daddr, const struct in6_addr *solicited_addr, diff --git a/net/ipv6/addrconf_core.c b/net/ipv6/addrconf_core.c index bfa941fc1165..129324b36fb6 100644 --- a/net/ipv6/addrconf_core.c +++ b/net/ipv6/addrconf_core.c @@ -107,15 +107,16 @@ int inet6addr_notifier_call_chain(unsigned long val, void *v) } EXPORT_SYMBOL(inet6addr_notifier_call_chain); -static int eafnosupport_ipv6_dst_lookup(struct net *net, struct sock *u1, - struct dst_entry **u2, - struct flowi6 *u3) +static struct dst_entry *eafnosupport_ipv6_dst_lookup_flow(struct net *net, + const struct sock *sk, + struct flowi6 *fl6, + const struct in6_addr *final_dst) { - return -EAFNOSUPPORT; + return ERR_PTR(-EAFNOSUPPORT); } const struct ipv6_stub *ipv6_stub __read_mostly = &(struct ipv6_stub) { - .ipv6_dst_lookup = eafnosupport_ipv6_dst_lookup, + .ipv6_dst_lookup_flow = eafnosupport_ipv6_dst_lookup_flow, }; EXPORT_SYMBOL_GPL(ipv6_stub); diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 2e91637c9d49..c6746aaf7fbf 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -860,7 +860,7 @@ static struct pernet_operations inet6_net_ops = { static const struct ipv6_stub ipv6_stub_impl = { .ipv6_sock_mc_join = ipv6_sock_mc_join, .ipv6_sock_mc_drop = ipv6_sock_mc_drop, - .ipv6_dst_lookup = ip6_dst_lookup, + .ipv6_dst_lookup_flow = ip6_dst_lookup_flow, .udpv6_encap_enable = udpv6_encap_enable, .ndisc_send_na = ndisc_send_na, .nd_tbl = &nd_tbl, diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index ffab94d61e1d..eab9c1d70856 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c @@ -497,16 +497,15 @@ static struct net_device *inet6_fib_lookup_dev(struct net *net, struct net_device *dev; struct dst_entry *dst; struct flowi6 fl6; - int err; if (!ipv6_stub) return ERR_PTR(-EAFNOSUPPORT); memset(&fl6, 0, sizeof(fl6)); memcpy(&fl6.daddr, addr, sizeof(struct in6_addr)); - err = ipv6_stub->ipv6_dst_lookup(net, NULL, &dst, &fl6); - if (err) - return ERR_PTR(err); + dst = ipv6_stub->ipv6_dst_lookup_flow(net, NULL, &fl6, NULL); + if (IS_ERR(dst)) + return ERR_CAST(dst); dev = dst->dev; dev_hold(dev); diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c index 05033ab05b8f..c6ff3de1de37 100644 --- a/net/tipc/udp_media.c +++ b/net/tipc/udp_media.c @@ -187,10 +187,13 @@ static int tipc_udp_xmit(struct net *net, struct sk_buff *skb, .saddr = src->ipv6, .flowi6_proto = IPPROTO_UDP }; - err = ipv6_stub->ipv6_dst_lookup(net, ub->ubsock->sk, &ndst, - &fl6); - if (err) + ndst = ipv6_stub->ipv6_dst_lookup_flow(net, + ub->ubsock->sk, + &fl6, NULL); + if (IS_ERR(ndst)) { + err = PTR_ERR(ndst); goto tx_error; + } ttl = ip6_dst_hoplimit(ndst); err = udp_tunnel6_xmit_skb(ndst, ub->ubsock->sk, skb, NULL, &src->ipv6, &dst->ipv6, 0, ttl, 0, From b4880925650b90cedc82b4044571177165448953 Mon Sep 17 00:00:00 2001 From: Waiman Long Date: Wed, 20 Sep 2017 13:12:20 -0600 Subject: [PATCH 031/387] blktrace: Fix potential deadlock between delete & sysfs ops commit 5acb3cc2c2e9d3020a4fee43763c6463767f1572 upstream. The lockdep code had reported the following unsafe locking scenario: CPU0 CPU1 ---- ---- lock(s_active#228); lock(&bdev->bd_mutex/1); lock(s_active#228); lock(&bdev->bd_mutex); *** DEADLOCK *** The deadlock may happen when one task (CPU1) is trying to delete a partition in a block device and another task (CPU0) is accessing tracing sysfs file (e.g. /sys/block/dm-1/trace/act_mask) in that partition. The s_active isn't an actual lock. It is a reference count (kn->count) on the sysfs (kernfs) file. Removal of a sysfs file, however, require a wait until all the references are gone. The reference count is treated like a rwsem using lockdep instrumentation code. The fact that a thread is in the sysfs callback method or in the ioctl call means there is a reference to the opended sysfs or device file. That should prevent the underlying block structure from being removed. Instead of using bd_mutex in the block_device structure, a new blk_trace_mutex is now added to the request_queue structure to protect access to the blk_trace structure. Suggested-by: Christoph Hellwig Signed-off-by: Waiman Long Acked-by: Steven Rostedt (VMware) Fix typo in patch subject line, and prune a comment detailing how the code used to work. Signed-off-by: Jens Axboe Signed-off-by: Ben Hutchings Signed-off-by: Sasha Levin --- block/blk-core.c | 3 +++ include/linux/blkdev.h | 1 + kernel/trace/blktrace.c | 18 ++++++++++++------ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index bdb906bbfe19..4987f312a95f 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -729,6 +729,9 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id) kobject_init(&q->kobj, &blk_queue_ktype); +#ifdef CONFIG_BLK_DEV_IO_TRACE + mutex_init(&q->blk_trace_mutex); +#endif mutex_init(&q->sysfs_lock); spin_lock_init(&q->__queue_lock); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 2fc4ba6fa07f..a8dfbad42d1b 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -446,6 +446,7 @@ struct request_queue { int node; #ifdef CONFIG_BLK_DEV_IO_TRACE struct blk_trace *blk_trace; + struct mutex blk_trace_mutex; #endif /* * for flush operations diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index bfa8bb3a6e19..ff1384c5884c 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -644,6 +644,12 @@ int blk_trace_startstop(struct request_queue *q, int start) } EXPORT_SYMBOL_GPL(blk_trace_startstop); +/* + * When reading or writing the blktrace sysfs files, the references to the + * opened sysfs or device files should prevent the underlying block device + * from being removed. So no further delete protection is really needed. + */ + /** * blk_trace_ioctl: - handle the ioctls associated with tracing * @bdev: the block device @@ -661,7 +667,7 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg) if (!q) return -ENXIO; - mutex_lock(&bdev->bd_mutex); + mutex_lock(&q->blk_trace_mutex); switch (cmd) { case BLKTRACESETUP: @@ -687,7 +693,7 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg) break; } - mutex_unlock(&bdev->bd_mutex); + mutex_unlock(&q->blk_trace_mutex); return ret; } @@ -1656,7 +1662,7 @@ static ssize_t sysfs_blk_trace_attr_show(struct device *dev, if (q == NULL) goto out_bdput; - mutex_lock(&bdev->bd_mutex); + mutex_lock(&q->blk_trace_mutex); if (attr == &dev_attr_enable) { ret = sprintf(buf, "%u\n", !!q->blk_trace); @@ -1675,7 +1681,7 @@ static ssize_t sysfs_blk_trace_attr_show(struct device *dev, ret = sprintf(buf, "%llu\n", q->blk_trace->end_lba); out_unlock_bdev: - mutex_unlock(&bdev->bd_mutex); + mutex_unlock(&q->blk_trace_mutex); out_bdput: bdput(bdev); out: @@ -1717,7 +1723,7 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev, if (q == NULL) goto out_bdput; - mutex_lock(&bdev->bd_mutex); + mutex_lock(&q->blk_trace_mutex); if (attr == &dev_attr_enable) { if (!!value == !!q->blk_trace) { @@ -1747,7 +1753,7 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev, } out_unlock_bdev: - mutex_unlock(&bdev->bd_mutex); + mutex_unlock(&q->blk_trace_mutex); out_bdput: bdput(bdev); out: From 0ef5b092bb9936584a8885201f9e712ceec4a9d2 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Sun, 5 Nov 2017 09:13:48 -0700 Subject: [PATCH 032/387] blktrace: fix unlocked access to init/start-stop/teardown commit 1f2cac107c591c24b60b115d6050adc213d10fc0 upstream. sg.c calls into the blktrace functions without holding the proper queue mutex for doing setup, start/stop, or teardown. Add internal unlocked variants, and export the ones that do the proper locking. Fixes: 6da127ad0918 ("blktrace: Add blktrace ioctls to SCSI generic devices") Tested-by: Dmitry Vyukov Signed-off-by: Jens Axboe Signed-off-by: Ben Hutchings Signed-off-by: Sasha Levin --- kernel/trace/blktrace.c | 58 ++++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index ff1384c5884c..55337d797deb 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -329,7 +329,7 @@ static void blk_trace_cleanup(struct blk_trace *bt) put_probe_ref(); } -int blk_trace_remove(struct request_queue *q) +static int __blk_trace_remove(struct request_queue *q) { struct blk_trace *bt; @@ -342,6 +342,17 @@ int blk_trace_remove(struct request_queue *q) return 0; } + +int blk_trace_remove(struct request_queue *q) +{ + int ret; + + mutex_lock(&q->blk_trace_mutex); + ret = __blk_trace_remove(q); + mutex_unlock(&q->blk_trace_mutex); + + return ret; +} EXPORT_SYMBOL_GPL(blk_trace_remove); static ssize_t blk_dropped_read(struct file *filp, char __user *buffer, @@ -546,9 +557,8 @@ err: return ret; } -int blk_trace_setup(struct request_queue *q, char *name, dev_t dev, - struct block_device *bdev, - char __user *arg) +static int __blk_trace_setup(struct request_queue *q, char *name, dev_t dev, + struct block_device *bdev, char __user *arg) { struct blk_user_trace_setup buts; int ret; @@ -567,6 +577,19 @@ int blk_trace_setup(struct request_queue *q, char *name, dev_t dev, } return 0; } + +int blk_trace_setup(struct request_queue *q, char *name, dev_t dev, + struct block_device *bdev, + char __user *arg) +{ + int ret; + + mutex_lock(&q->blk_trace_mutex); + ret = __blk_trace_setup(q, name, dev, bdev, arg); + mutex_unlock(&q->blk_trace_mutex); + + return ret; +} EXPORT_SYMBOL_GPL(blk_trace_setup); #if defined(CONFIG_COMPAT) && defined(CONFIG_X86_64) @@ -603,7 +626,7 @@ static int compat_blk_trace_setup(struct request_queue *q, char *name, } #endif -int blk_trace_startstop(struct request_queue *q, int start) +static int __blk_trace_startstop(struct request_queue *q, int start) { int ret; struct blk_trace *bt = q->blk_trace; @@ -642,6 +665,17 @@ int blk_trace_startstop(struct request_queue *q, int start) return ret; } + +int blk_trace_startstop(struct request_queue *q, int start) +{ + int ret; + + mutex_lock(&q->blk_trace_mutex); + ret = __blk_trace_startstop(q, start); + mutex_unlock(&q->blk_trace_mutex); + + return ret; +} EXPORT_SYMBOL_GPL(blk_trace_startstop); /* @@ -672,7 +706,7 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg) switch (cmd) { case BLKTRACESETUP: bdevname(bdev, b); - ret = blk_trace_setup(q, b, bdev->bd_dev, bdev, arg); + ret = __blk_trace_setup(q, b, bdev->bd_dev, bdev, arg); break; #if defined(CONFIG_COMPAT) && defined(CONFIG_X86_64) case BLKTRACESETUP32: @@ -683,10 +717,10 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg) case BLKTRACESTART: start = 1; case BLKTRACESTOP: - ret = blk_trace_startstop(q, start); + ret = __blk_trace_startstop(q, start); break; case BLKTRACETEARDOWN: - ret = blk_trace_remove(q); + ret = __blk_trace_remove(q); break; default: ret = -ENOTTY; @@ -704,10 +738,14 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg) **/ void blk_trace_shutdown(struct request_queue *q) { + mutex_lock(&q->blk_trace_mutex); + if (q->blk_trace) { - blk_trace_startstop(q, 0); - blk_trace_remove(q); + __blk_trace_startstop(q, 0); + __blk_trace_remove(q); } + + mutex_unlock(&q->blk_trace_mutex); } /* From 0f62edba7ca63ba8abd05379b812723162313608 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Sun, 19 Nov 2017 11:52:55 -0700 Subject: [PATCH 033/387] blktrace: fix trace mutex deadlock commit 2967acbb257a6a9bf912f4778b727e00972eac9b upstream. A previous commit changed the locking around registration/cleanup, but direct callers of blk_trace_remove() were missed. This means that if we hit the error path in setup, we will deadlock on attempting to re-acquire the queue trace mutex. Fixes: 1f2cac107c59 ("blktrace: fix unlocked access to init/start-stop/teardown") Signed-off-by: Jens Axboe Signed-off-by: Ben Hutchings Signed-off-by: Sasha Levin --- kernel/trace/blktrace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index 55337d797deb..a88e677c74f3 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -572,7 +572,7 @@ static int __blk_trace_setup(struct request_queue *q, char *name, dev_t dev, return ret; if (copy_to_user(arg, &buts, sizeof(buts))) { - blk_trace_remove(q); + __blk_trace_remove(q); return -EFAULT; } return 0; @@ -618,7 +618,7 @@ static int compat_blk_trace_setup(struct request_queue *q, char *name, return ret; if (copy_to_user(arg, &buts.name, ARRAY_SIZE(buts.name))) { - blk_trace_remove(q); + __blk_trace_remove(q); return -EFAULT; } From 284dba674c063ac5cab9ffc1ea07f7b199aeb62f Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 6 Feb 2020 15:28:12 +0100 Subject: [PATCH 034/387] blktrace: Protect q->blk_trace with RCU commit c780e86dd48ef6467a1146cf7d0fe1e05a635039 upstream. KASAN is reporting that __blk_add_trace() has a use-after-free issue when accessing q->blk_trace. Indeed the switching of block tracing (and thus eventual freeing of q->blk_trace) is completely unsynchronized with the currently running tracing and thus it can happen that the blk_trace structure is being freed just while __blk_add_trace() works on it. Protect accesses to q->blk_trace by RCU during tracing and make sure we wait for the end of RCU grace period when shutting down tracing. Luckily that is rare enough event that we can afford that. Note that postponing the freeing of blk_trace to an RCU callback should better be avoided as it could have unexpected user visible side-effects as debugfs files would be still existing for a short while block tracing has been shut down. Link: https://bugzilla.kernel.org/show_bug.cgi?id=205711 CC: stable@vger.kernel.org Reviewed-by: Chaitanya Kulkarni Reviewed-by: Ming Lei Tested-by: Ming Lei Reviewed-by: Bart Van Assche Reported-by: Tristan Madani Signed-off-by: Jan Kara Signed-off-by: Jens Axboe [bwh: Backported to 4.9: adjust context] Signed-off-by: Ben Hutchings Signed-off-by: Sasha Levin --- include/linux/blkdev.h | 2 +- include/linux/blktrace_api.h | 18 ++++-- kernel/trace/blktrace.c | 110 +++++++++++++++++++++++++---------- 3 files changed, 94 insertions(+), 36 deletions(-) diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index a8dfbad42d1b..060881478e59 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -445,7 +445,7 @@ struct request_queue { unsigned int sg_reserved_size; int node; #ifdef CONFIG_BLK_DEV_IO_TRACE - struct blk_trace *blk_trace; + struct blk_trace __rcu *blk_trace; struct mutex blk_trace_mutex; #endif /* diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h index cceb72f9e29f..45fb00427306 100644 --- a/include/linux/blktrace_api.h +++ b/include/linux/blktrace_api.h @@ -51,18 +51,26 @@ void __trace_note_message(struct blk_trace *, const char *fmt, ...); **/ #define blk_add_trace_msg(q, fmt, ...) \ do { \ - struct blk_trace *bt = (q)->blk_trace; \ + struct blk_trace *bt; \ + \ + rcu_read_lock(); \ + bt = rcu_dereference((q)->blk_trace); \ if (unlikely(bt)) \ __trace_note_message(bt, fmt, ##__VA_ARGS__); \ + rcu_read_unlock(); \ } while (0) #define BLK_TN_MAX_MSG 128 static inline bool blk_trace_note_message_enabled(struct request_queue *q) { - struct blk_trace *bt = q->blk_trace; - if (likely(!bt)) - return false; - return bt->act_mask & BLK_TC_NOTIFY; + struct blk_trace *bt; + bool ret; + + rcu_read_lock(); + bt = rcu_dereference(q->blk_trace); + ret = bt && (bt->act_mask & BLK_TC_NOTIFY); + rcu_read_unlock(); + return ret; } extern void blk_add_driver_data(struct request_queue *q, struct request *rq, diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index a88e677c74f3..78a896acd21a 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -325,6 +325,7 @@ static void put_probe_ref(void) static void blk_trace_cleanup(struct blk_trace *bt) { + synchronize_rcu(); blk_trace_free(bt); put_probe_ref(); } @@ -629,8 +630,10 @@ static int compat_blk_trace_setup(struct request_queue *q, char *name, static int __blk_trace_startstop(struct request_queue *q, int start) { int ret; - struct blk_trace *bt = q->blk_trace; + struct blk_trace *bt; + bt = rcu_dereference_protected(q->blk_trace, + lockdep_is_held(&q->blk_trace_mutex)); if (bt == NULL) return -EINVAL; @@ -739,8 +742,8 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg) void blk_trace_shutdown(struct request_queue *q) { mutex_lock(&q->blk_trace_mutex); - - if (q->blk_trace) { + if (rcu_dereference_protected(q->blk_trace, + lockdep_is_held(&q->blk_trace_mutex))) { __blk_trace_startstop(q, 0); __blk_trace_remove(q); } @@ -766,10 +769,14 @@ void blk_trace_shutdown(struct request_queue *q) static void blk_add_trace_rq(struct request_queue *q, struct request *rq, unsigned int nr_bytes, u32 what) { - struct blk_trace *bt = q->blk_trace; + struct blk_trace *bt; - if (likely(!bt)) + rcu_read_lock(); + bt = rcu_dereference(q->blk_trace); + if (likely(!bt)) { + rcu_read_unlock(); return; + } if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { what |= BLK_TC_ACT(BLK_TC_PC); @@ -780,6 +787,7 @@ static void blk_add_trace_rq(struct request_queue *q, struct request *rq, __blk_add_trace(bt, blk_rq_pos(rq), nr_bytes, req_op(rq), rq->cmd_flags, what, rq->errors, 0, NULL); } + rcu_read_unlock(); } static void blk_add_trace_rq_abort(void *ignore, @@ -829,13 +837,18 @@ static void blk_add_trace_rq_complete(void *ignore, static void blk_add_trace_bio(struct request_queue *q, struct bio *bio, u32 what, int error) { - struct blk_trace *bt = q->blk_trace; + struct blk_trace *bt; - if (likely(!bt)) + rcu_read_lock(); + bt = rcu_dereference(q->blk_trace); + if (likely(!bt)) { + rcu_read_unlock(); return; + } __blk_add_trace(bt, bio->bi_iter.bi_sector, bio->bi_iter.bi_size, bio_op(bio), bio->bi_opf, what, error, 0, NULL); + rcu_read_unlock(); } static void blk_add_trace_bio_bounce(void *ignore, @@ -880,11 +893,14 @@ static void blk_add_trace_getrq(void *ignore, if (bio) blk_add_trace_bio(q, bio, BLK_TA_GETRQ, 0); else { - struct blk_trace *bt = q->blk_trace; + struct blk_trace *bt; + rcu_read_lock(); + bt = rcu_dereference(q->blk_trace); if (bt) __blk_add_trace(bt, 0, 0, rw, 0, BLK_TA_GETRQ, 0, 0, NULL); + rcu_read_unlock(); } } @@ -896,27 +912,35 @@ static void blk_add_trace_sleeprq(void *ignore, if (bio) blk_add_trace_bio(q, bio, BLK_TA_SLEEPRQ, 0); else { - struct blk_trace *bt = q->blk_trace; + struct blk_trace *bt; + rcu_read_lock(); + bt = rcu_dereference(q->blk_trace); if (bt) __blk_add_trace(bt, 0, 0, rw, 0, BLK_TA_SLEEPRQ, 0, 0, NULL); + rcu_read_unlock(); } } static void blk_add_trace_plug(void *ignore, struct request_queue *q) { - struct blk_trace *bt = q->blk_trace; + struct blk_trace *bt; + rcu_read_lock(); + bt = rcu_dereference(q->blk_trace); if (bt) __blk_add_trace(bt, 0, 0, 0, 0, BLK_TA_PLUG, 0, 0, NULL); + rcu_read_unlock(); } static void blk_add_trace_unplug(void *ignore, struct request_queue *q, unsigned int depth, bool explicit) { - struct blk_trace *bt = q->blk_trace; + struct blk_trace *bt; + rcu_read_lock(); + bt = rcu_dereference(q->blk_trace); if (bt) { __be64 rpdu = cpu_to_be64(depth); u32 what; @@ -928,14 +952,17 @@ static void blk_add_trace_unplug(void *ignore, struct request_queue *q, __blk_add_trace(bt, 0, 0, 0, 0, what, 0, sizeof(rpdu), &rpdu); } + rcu_read_unlock(); } static void blk_add_trace_split(void *ignore, struct request_queue *q, struct bio *bio, unsigned int pdu) { - struct blk_trace *bt = q->blk_trace; + struct blk_trace *bt; + rcu_read_lock(); + bt = rcu_dereference(q->blk_trace); if (bt) { __be64 rpdu = cpu_to_be64(pdu); @@ -944,6 +971,7 @@ static void blk_add_trace_split(void *ignore, BLK_TA_SPLIT, bio->bi_error, sizeof(rpdu), &rpdu); } + rcu_read_unlock(); } /** @@ -963,11 +991,15 @@ static void blk_add_trace_bio_remap(void *ignore, struct request_queue *q, struct bio *bio, dev_t dev, sector_t from) { - struct blk_trace *bt = q->blk_trace; + struct blk_trace *bt; struct blk_io_trace_remap r; - if (likely(!bt)) + rcu_read_lock(); + bt = rcu_dereference(q->blk_trace); + if (likely(!bt)) { + rcu_read_unlock(); return; + } r.device_from = cpu_to_be32(dev); r.device_to = cpu_to_be32(bio->bi_bdev->bd_dev); @@ -976,6 +1008,7 @@ static void blk_add_trace_bio_remap(void *ignore, __blk_add_trace(bt, bio->bi_iter.bi_sector, bio->bi_iter.bi_size, bio_op(bio), bio->bi_opf, BLK_TA_REMAP, bio->bi_error, sizeof(r), &r); + rcu_read_unlock(); } /** @@ -996,11 +1029,15 @@ static void blk_add_trace_rq_remap(void *ignore, struct request *rq, dev_t dev, sector_t from) { - struct blk_trace *bt = q->blk_trace; + struct blk_trace *bt; struct blk_io_trace_remap r; - if (likely(!bt)) + rcu_read_lock(); + bt = rcu_dereference(q->blk_trace); + if (likely(!bt)) { + rcu_read_unlock(); return; + } r.device_from = cpu_to_be32(dev); r.device_to = cpu_to_be32(disk_devt(rq->rq_disk)); @@ -1009,6 +1046,7 @@ static void blk_add_trace_rq_remap(void *ignore, __blk_add_trace(bt, blk_rq_pos(rq), blk_rq_bytes(rq), rq_data_dir(rq), 0, BLK_TA_REMAP, !!rq->errors, sizeof(r), &r); + rcu_read_unlock(); } /** @@ -1026,10 +1064,14 @@ void blk_add_driver_data(struct request_queue *q, struct request *rq, void *data, size_t len) { - struct blk_trace *bt = q->blk_trace; + struct blk_trace *bt; - if (likely(!bt)) + rcu_read_lock(); + bt = rcu_dereference(q->blk_trace); + if (likely(!bt)) { + rcu_read_unlock(); return; + } if (rq->cmd_type == REQ_TYPE_BLOCK_PC) __blk_add_trace(bt, 0, blk_rq_bytes(rq), 0, 0, @@ -1037,6 +1079,7 @@ void blk_add_driver_data(struct request_queue *q, else __blk_add_trace(bt, blk_rq_pos(rq), blk_rq_bytes(rq), 0, 0, BLK_TA_DRV_DATA, rq->errors, len, data); + rcu_read_unlock(); } EXPORT_SYMBOL_GPL(blk_add_driver_data); @@ -1529,6 +1572,7 @@ static int blk_trace_remove_queue(struct request_queue *q) return -EINVAL; put_probe_ref(); + synchronize_rcu(); blk_trace_free(bt); return 0; } @@ -1690,6 +1734,7 @@ static ssize_t sysfs_blk_trace_attr_show(struct device *dev, struct hd_struct *p = dev_to_part(dev); struct request_queue *q; struct block_device *bdev; + struct blk_trace *bt; ssize_t ret = -ENXIO; bdev = bdget(part_devt(p)); @@ -1702,21 +1747,23 @@ static ssize_t sysfs_blk_trace_attr_show(struct device *dev, mutex_lock(&q->blk_trace_mutex); + bt = rcu_dereference_protected(q->blk_trace, + lockdep_is_held(&q->blk_trace_mutex)); if (attr == &dev_attr_enable) { - ret = sprintf(buf, "%u\n", !!q->blk_trace); + ret = sprintf(buf, "%u\n", !!bt); goto out_unlock_bdev; } - if (q->blk_trace == NULL) + if (bt == NULL) ret = sprintf(buf, "disabled\n"); else if (attr == &dev_attr_act_mask) - ret = blk_trace_mask2str(buf, q->blk_trace->act_mask); + ret = blk_trace_mask2str(buf, bt->act_mask); else if (attr == &dev_attr_pid) - ret = sprintf(buf, "%u\n", q->blk_trace->pid); + ret = sprintf(buf, "%u\n", bt->pid); else if (attr == &dev_attr_start_lba) - ret = sprintf(buf, "%llu\n", q->blk_trace->start_lba); + ret = sprintf(buf, "%llu\n", bt->start_lba); else if (attr == &dev_attr_end_lba) - ret = sprintf(buf, "%llu\n", q->blk_trace->end_lba); + ret = sprintf(buf, "%llu\n", bt->end_lba); out_unlock_bdev: mutex_unlock(&q->blk_trace_mutex); @@ -1733,6 +1780,7 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev, struct block_device *bdev; struct request_queue *q; struct hd_struct *p; + struct blk_trace *bt; u64 value; ssize_t ret = -EINVAL; @@ -1763,8 +1811,10 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev, mutex_lock(&q->blk_trace_mutex); + bt = rcu_dereference_protected(q->blk_trace, + lockdep_is_held(&q->blk_trace_mutex)); if (attr == &dev_attr_enable) { - if (!!value == !!q->blk_trace) { + if (!!value == !!bt) { ret = 0; goto out_unlock_bdev; } @@ -1776,18 +1826,18 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev, } ret = 0; - if (q->blk_trace == NULL) + if (bt == NULL) ret = blk_trace_setup_queue(q, bdev); if (ret == 0) { if (attr == &dev_attr_act_mask) - q->blk_trace->act_mask = value; + bt->act_mask = value; else if (attr == &dev_attr_pid) - q->blk_trace->pid = value; + bt->pid = value; else if (attr == &dev_attr_start_lba) - q->blk_trace->start_lba = value; + bt->start_lba = value; else if (attr == &dev_attr_end_lba) - q->blk_trace->end_lba = value; + bt->end_lba = value; } out_unlock_bdev: From a33f9c96871ed932bf28885cc708aec7b499bcad Mon Sep 17 00:00:00 2001 From: Cengiz Can Date: Wed, 4 Mar 2020 13:58:19 +0300 Subject: [PATCH 035/387] blktrace: fix dereference after null check commit 153031a301bb07194e9c37466cfce8eacb977621 upstream. There was a recent change in blktrace.c that added a RCU protection to `q->blk_trace` in order to fix a use-after-free issue during access. However the change missed an edge case that can lead to dereferencing of `bt` pointer even when it's NULL: Coverity static analyzer marked this as a FORWARD_NULL issue with CID 1460458. ``` /kernel/trace/blktrace.c: 1904 in sysfs_blk_trace_attr_store() 1898 ret = 0; 1899 if (bt == NULL) 1900 ret = blk_trace_setup_queue(q, bdev); 1901 1902 if (ret == 0) { 1903 if (attr == &dev_attr_act_mask) >>> CID 1460458: Null pointer dereferences (FORWARD_NULL) >>> Dereferencing null pointer "bt". 1904 bt->act_mask = value; 1905 else if (attr == &dev_attr_pid) 1906 bt->pid = value; 1907 else if (attr == &dev_attr_start_lba) 1908 bt->start_lba = value; 1909 else if (attr == &dev_attr_end_lba) ``` Added a reassignment with RCU annotation to fix the issue. Fixes: c780e86dd48 ("blktrace: Protect q->blk_trace with RCU") Reviewed-by: Ming Lei Reviewed-by: Bob Liu Reviewed-by: Steven Rostedt (VMware) Signed-off-by: Cengiz Can Signed-off-by: Jens Axboe Signed-off-by: Ben Hutchings Signed-off-by: Sasha Levin --- kernel/trace/blktrace.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index 78a896acd21a..6d3b432a748a 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -1826,8 +1826,11 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev, } ret = 0; - if (bt == NULL) + if (bt == NULL) { ret = blk_trace_setup_queue(q, bdev); + bt = rcu_dereference_protected(q->blk_trace, + lockdep_is_held(&q->blk_trace_mutex)); + } if (ret == 0) { if (attr == &dev_attr_act_mask) From bca173248fed7477fa607afe0c2efde61f00dbd2 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 14 Feb 2017 10:23:31 -0800 Subject: [PATCH 036/387] ptp: do not explicitly set drvdata in ptp_clock_register() commit 882f312dc0751c973db26478f07f082c584d16aa upstream. We do not need explicitly call dev_set_drvdata(), as it is done for us by device_create(). Acked-by: Richard Cochran Signed-off-by: Dmitry Torokhov Signed-off-by: David S. Miller Signed-off-by: Ben Hutchings Signed-off-by: Sasha Levin --- drivers/ptp/ptp_clock.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index 2aa5b37cc6d2..08f304b83ad1 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c @@ -220,8 +220,6 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, if (IS_ERR(ptp->dev)) goto no_device; - dev_set_drvdata(ptp->dev, ptp); - err = ptp_populate_sysfs(ptp); if (err) goto no_sysfs; From 6347abb820bbbca94074100dbd21f4cbc54d45b2 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 14 Feb 2017 10:23:33 -0800 Subject: [PATCH 037/387] ptp: use is_visible method to hide unused attributes commit af59e717d5ff9c8dbf9bcc581c0dfb3b2a9c9030 upstream. Instead of creating selected attributes after the device is created (and after userspace potentially seen uevent), lets use attribute group is_visible() method to control which attributes are shown. This will allow us to create all attributes (except "pins" group, which will be taken care of later) before userspace gets notified about new ptp class device. Signed-off-by: Dmitry Torokhov Signed-off-by: David S. Miller Signed-off-by: Ben Hutchings Signed-off-by: Sasha Levin --- drivers/ptp/ptp_sysfs.c | 125 ++++++++++++++++++---------------------- 1 file changed, 55 insertions(+), 70 deletions(-) diff --git a/drivers/ptp/ptp_sysfs.c b/drivers/ptp/ptp_sysfs.c index 302e626fe6b0..a55a6eb4dfde 100644 --- a/drivers/ptp/ptp_sysfs.c +++ b/drivers/ptp/ptp_sysfs.c @@ -46,27 +46,6 @@ PTP_SHOW_INT(n_periodic_outputs, n_per_out); PTP_SHOW_INT(n_programmable_pins, n_pins); PTP_SHOW_INT(pps_available, pps); -static struct attribute *ptp_attrs[] = { - &dev_attr_clock_name.attr, - &dev_attr_max_adjustment.attr, - &dev_attr_n_alarms.attr, - &dev_attr_n_external_timestamps.attr, - &dev_attr_n_periodic_outputs.attr, - &dev_attr_n_programmable_pins.attr, - &dev_attr_pps_available.attr, - NULL, -}; - -static const struct attribute_group ptp_group = { - .attrs = ptp_attrs, -}; - -const struct attribute_group *ptp_groups[] = { - &ptp_group, - NULL, -}; - - static ssize_t extts_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -91,6 +70,7 @@ static ssize_t extts_enable_store(struct device *dev, out: return err; } +static DEVICE_ATTR(extts_enable, 0220, NULL, extts_enable_store); static ssize_t extts_fifo_show(struct device *dev, struct device_attribute *attr, char *page) @@ -124,6 +104,7 @@ out: mutex_unlock(&ptp->tsevq_mux); return cnt; } +static DEVICE_ATTR(fifo, 0444, extts_fifo_show, NULL); static ssize_t period_store(struct device *dev, struct device_attribute *attr, @@ -151,6 +132,7 @@ static ssize_t period_store(struct device *dev, out: return err; } +static DEVICE_ATTR(period, 0220, NULL, period_store); static ssize_t pps_enable_store(struct device *dev, struct device_attribute *attr, @@ -177,6 +159,57 @@ static ssize_t pps_enable_store(struct device *dev, out: return err; } +static DEVICE_ATTR(pps_enable, 0220, NULL, pps_enable_store); + +static struct attribute *ptp_attrs[] = { + &dev_attr_clock_name.attr, + + &dev_attr_max_adjustment.attr, + &dev_attr_n_alarms.attr, + &dev_attr_n_external_timestamps.attr, + &dev_attr_n_periodic_outputs.attr, + &dev_attr_n_programmable_pins.attr, + &dev_attr_pps_available.attr, + + &dev_attr_extts_enable.attr, + &dev_attr_fifo.attr, + &dev_attr_period.attr, + &dev_attr_pps_enable.attr, + NULL +}; + +static umode_t ptp_is_attribute_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + struct device *dev = kobj_to_dev(kobj); + struct ptp_clock *ptp = dev_get_drvdata(dev); + struct ptp_clock_info *info = ptp->info; + umode_t mode = attr->mode; + + if (attr == &dev_attr_extts_enable.attr || + attr == &dev_attr_fifo.attr) { + if (!info->n_ext_ts) + mode = 0; + } else if (attr == &dev_attr_period.attr) { + if (!info->n_per_out) + mode = 0; + } else if (attr == &dev_attr_pps_enable.attr) { + if (!info->pps) + mode = 0; + } + + return mode; +} + +static const struct attribute_group ptp_group = { + .is_visible = ptp_is_attribute_visible, + .attrs = ptp_attrs, +}; + +const struct attribute_group *ptp_groups[] = { + &ptp_group, + NULL +}; static int ptp_pin_name2index(struct ptp_clock *ptp, const char *name) { @@ -235,26 +268,11 @@ static ssize_t ptp_pin_store(struct device *dev, struct device_attribute *attr, return count; } -static DEVICE_ATTR(extts_enable, 0220, NULL, extts_enable_store); -static DEVICE_ATTR(fifo, 0444, extts_fifo_show, NULL); -static DEVICE_ATTR(period, 0220, NULL, period_store); -static DEVICE_ATTR(pps_enable, 0220, NULL, pps_enable_store); - int ptp_cleanup_sysfs(struct ptp_clock *ptp) { struct device *dev = ptp->dev; struct ptp_clock_info *info = ptp->info; - if (info->n_ext_ts) { - device_remove_file(dev, &dev_attr_extts_enable); - device_remove_file(dev, &dev_attr_fifo); - } - if (info->n_per_out) - device_remove_file(dev, &dev_attr_period); - - if (info->pps) - device_remove_file(dev, &dev_attr_pps_enable); - if (info->n_pins) { sysfs_remove_group(&dev->kobj, &ptp->pin_attr_group); kfree(ptp->pin_attr); @@ -307,46 +325,13 @@ no_dev_attr: int ptp_populate_sysfs(struct ptp_clock *ptp) { - struct device *dev = ptp->dev; struct ptp_clock_info *info = ptp->info; int err; - if (info->n_ext_ts) { - err = device_create_file(dev, &dev_attr_extts_enable); - if (err) - goto out1; - err = device_create_file(dev, &dev_attr_fifo); - if (err) - goto out2; - } - if (info->n_per_out) { - err = device_create_file(dev, &dev_attr_period); - if (err) - goto out3; - } - if (info->pps) { - err = device_create_file(dev, &dev_attr_pps_enable); - if (err) - goto out4; - } if (info->n_pins) { err = ptp_populate_pins(ptp); if (err) - goto out5; + return err; } return 0; -out5: - if (info->pps) - device_remove_file(dev, &dev_attr_pps_enable); -out4: - if (info->n_per_out) - device_remove_file(dev, &dev_attr_period); -out3: - if (info->n_ext_ts) - device_remove_file(dev, &dev_attr_fifo); -out2: - if (info->n_ext_ts) - device_remove_file(dev, &dev_attr_extts_enable); -out1: - return err; } From ea053b2214271cc579e5e26b3440a271381a30b1 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 14 Feb 2017 10:23:34 -0800 Subject: [PATCH 038/387] ptp: create "pins" together with the rest of attributes commit 85a66e55019583da1e0f18706b7a8281c9f6de5b upstream. Let's switch to using device_create_with_groups(), which will allow us to create "pins" attribute group together with the rest of ptp device attributes, and before userspace gets notified about ptp device creation. Signed-off-by: Dmitry Torokhov Signed-off-by: David S. Miller [bwh: Backported to 4.9: adjust context] Signed-off-by: Ben Hutchings Signed-off-by: Sasha Levin --- drivers/ptp/ptp_clock.c | 20 +++++++++++--------- drivers/ptp/ptp_private.h | 7 ++++--- drivers/ptp/ptp_sysfs.c | 39 +++++++++------------------------------ 3 files changed, 24 insertions(+), 42 deletions(-) diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index 08f304b83ad1..d5ac33350889 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c @@ -214,16 +214,17 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, mutex_init(&ptp->pincfg_mux); init_waitqueue_head(&ptp->tsev_wq); + err = ptp_populate_pin_groups(ptp); + if (err) + goto no_pin_groups; + /* Create a new device in our class. */ - ptp->dev = device_create(ptp_class, parent, ptp->devid, ptp, - "ptp%d", ptp->index); + ptp->dev = device_create_with_groups(ptp_class, parent, ptp->devid, + ptp, ptp->pin_attr_groups, + "ptp%d", ptp->index); if (IS_ERR(ptp->dev)) goto no_device; - err = ptp_populate_sysfs(ptp); - if (err) - goto no_sysfs; - /* Register a new PPS source. */ if (info->pps) { struct pps_source_info pps; @@ -251,10 +252,10 @@ no_clock: if (ptp->pps_source) pps_unregister_source(ptp->pps_source); no_pps: - ptp_cleanup_sysfs(ptp); -no_sysfs: device_destroy(ptp_class, ptp->devid); no_device: + ptp_cleanup_pin_groups(ptp); +no_pin_groups: mutex_destroy(&ptp->tsevq_mux); mutex_destroy(&ptp->pincfg_mux); ida_simple_remove(&ptp_clocks_map, index); @@ -273,8 +274,9 @@ int ptp_clock_unregister(struct ptp_clock *ptp) /* Release the clock's resources. */ if (ptp->pps_source) pps_unregister_source(ptp->pps_source); - ptp_cleanup_sysfs(ptp); + device_destroy(ptp_class, ptp->devid); + ptp_cleanup_pin_groups(ptp); posix_clock_unregister(&ptp->clock); return 0; diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h index 9c5d41421b65..d95888974d0c 100644 --- a/drivers/ptp/ptp_private.h +++ b/drivers/ptp/ptp_private.h @@ -54,6 +54,8 @@ struct ptp_clock { struct device_attribute *pin_dev_attr; struct attribute **pin_attr; struct attribute_group pin_attr_group; + /* 1st entry is a pointer to the real group, 2nd is NULL terminator */ + const struct attribute_group *pin_attr_groups[2]; }; /* @@ -94,8 +96,7 @@ uint ptp_poll(struct posix_clock *pc, extern const struct attribute_group *ptp_groups[]; -int ptp_cleanup_sysfs(struct ptp_clock *ptp); - -int ptp_populate_sysfs(struct ptp_clock *ptp); +int ptp_populate_pin_groups(struct ptp_clock *ptp); +void ptp_cleanup_pin_groups(struct ptp_clock *ptp); #endif diff --git a/drivers/ptp/ptp_sysfs.c b/drivers/ptp/ptp_sysfs.c index a55a6eb4dfde..731d0423c8aa 100644 --- a/drivers/ptp/ptp_sysfs.c +++ b/drivers/ptp/ptp_sysfs.c @@ -268,25 +268,14 @@ static ssize_t ptp_pin_store(struct device *dev, struct device_attribute *attr, return count; } -int ptp_cleanup_sysfs(struct ptp_clock *ptp) +int ptp_populate_pin_groups(struct ptp_clock *ptp) { - struct device *dev = ptp->dev; - struct ptp_clock_info *info = ptp->info; - - if (info->n_pins) { - sysfs_remove_group(&dev->kobj, &ptp->pin_attr_group); - kfree(ptp->pin_attr); - kfree(ptp->pin_dev_attr); - } - return 0; -} - -static int ptp_populate_pins(struct ptp_clock *ptp) -{ - struct device *dev = ptp->dev; struct ptp_clock_info *info = ptp->info; int err = -ENOMEM, i, n_pins = info->n_pins; + if (!n_pins) + return 0; + ptp->pin_dev_attr = kzalloc(n_pins * sizeof(*ptp->pin_dev_attr), GFP_KERNEL); if (!ptp->pin_dev_attr) @@ -310,28 +299,18 @@ static int ptp_populate_pins(struct ptp_clock *ptp) ptp->pin_attr_group.name = "pins"; ptp->pin_attr_group.attrs = ptp->pin_attr; - err = sysfs_create_group(&dev->kobj, &ptp->pin_attr_group); - if (err) - goto no_group; + ptp->pin_attr_groups[0] = &ptp->pin_attr_group; + return 0; -no_group: - kfree(ptp->pin_attr); no_pin_attr: kfree(ptp->pin_dev_attr); no_dev_attr: return err; } -int ptp_populate_sysfs(struct ptp_clock *ptp) +void ptp_cleanup_pin_groups(struct ptp_clock *ptp) { - struct ptp_clock_info *info = ptp->info; - int err; - - if (info->n_pins) { - err = ptp_populate_pins(ptp); - if (err) - return err; - } - return 0; + kfree(ptp->pin_attr); + kfree(ptp->pin_dev_attr); } From da97a80a657d1b1b50ef633e8ff5dbf0d417fc8d Mon Sep 17 00:00:00 2001 From: Logan Gunthorpe Date: Fri, 17 Mar 2017 12:48:08 -0600 Subject: [PATCH 039/387] chardev: add helper function to register char devs with a struct device commit 233ed09d7fdacf592ee91e6c97ce5f4364fbe7c0 upstream. Credit for this patch goes is shared with Dan Williams [1]. I've taken things one step further to make the helper function more useful and clean up calling code. There's a common pattern in the kernel whereby a struct cdev is placed in a structure along side a struct device which manages the life-cycle of both. In the naive approach, the reference counting is broken and the struct device can free everything before the chardev code is entirely released. Many developers have solved this problem by linking the internal kobjs in this fashion: cdev.kobj.parent = &parent_dev.kobj; The cdev code explicitly gets and puts a reference to it's kobj parent. So this seems like it was intended to be used this way. Dmitrty Torokhov first put this in place in 2012 with this commit: 2f0157f char_dev: pin parent kobject and the first instance of the fix was then done in the input subsystem in the following commit: 4a215aa Input: fix use-after-free introduced with dynamic minor changes Subsequently over the years, however, this issue seems to have tripped up multiple developers independently. For example, see these commits: 0d5b7da iio: Prevent race between IIO chardev opening and IIO device (by Lars-Peter Clausen in 2013) ba0ef85 tpm: Fix initialization of the cdev (by Jason Gunthorpe in 2015) 5b28dde [media] media: fix use-after-free in cdev_put() when app exits after driver unbind (by Shauh Khan in 2016) This technique is similarly done in at least 15 places within the kernel and probably should have been done so in another, at least, 5 places. The kobj line also looks very suspect in that one would not expect drivers to have to mess with kobject internals in this way. Even highly experienced kernel developers can be surprised by this code, as seen in [2]. To help alleviate this situation, and hopefully prevent future wasted effort on this problem, this patch introduces a helper function to register a char device along with its parent struct device. This creates a more regular API for tying a char device to its parent without the developer having to set members in the underlying kobject. This patch introduce cdev_device_add and cdev_device_del which replaces a common pattern including setting the kobj parent, calling cdev_add and then calling device_add. It also introduces cdev_set_parent for the few cases that set the kobject parent without using device_add. [1] https://lkml.org/lkml/2017/2/13/700 [2] https://lkml.org/lkml/2017/2/10/370 Signed-off-by: Logan Gunthorpe Signed-off-by: Dan Williams Reviewed-by: Hans Verkuil Reviewed-by: Alexandre Belloni Signed-off-by: Greg Kroah-Hartman Signed-off-by: Ben Hutchings Signed-off-by: Sasha Levin --- fs/char_dev.c | 86 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/cdev.h | 5 +++ 2 files changed, 91 insertions(+) diff --git a/fs/char_dev.c b/fs/char_dev.c index 23e0477edf7d..1bbb966c0783 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c @@ -477,6 +477,85 @@ int cdev_add(struct cdev *p, dev_t dev, unsigned count) return 0; } +/** + * cdev_set_parent() - set the parent kobject for a char device + * @p: the cdev structure + * @kobj: the kobject to take a reference to + * + * cdev_set_parent() sets a parent kobject which will be referenced + * appropriately so the parent is not freed before the cdev. This + * should be called before cdev_add. + */ +void cdev_set_parent(struct cdev *p, struct kobject *kobj) +{ + WARN_ON(!kobj->state_initialized); + p->kobj.parent = kobj; +} + +/** + * cdev_device_add() - add a char device and it's corresponding + * struct device, linkink + * @dev: the device structure + * @cdev: the cdev structure + * + * cdev_device_add() adds the char device represented by @cdev to the system, + * just as cdev_add does. It then adds @dev to the system using device_add + * The dev_t for the char device will be taken from the struct device which + * needs to be initialized first. This helper function correctly takes a + * reference to the parent device so the parent will not get released until + * all references to the cdev are released. + * + * This helper uses dev->devt for the device number. If it is not set + * it will not add the cdev and it will be equivalent to device_add. + * + * This function should be used whenever the struct cdev and the + * struct device are members of the same structure whose lifetime is + * managed by the struct device. + * + * NOTE: Callers must assume that userspace was able to open the cdev and + * can call cdev fops callbacks at any time, even if this function fails. + */ +int cdev_device_add(struct cdev *cdev, struct device *dev) +{ + int rc = 0; + + if (dev->devt) { + cdev_set_parent(cdev, &dev->kobj); + + rc = cdev_add(cdev, dev->devt, 1); + if (rc) + return rc; + } + + rc = device_add(dev); + if (rc) + cdev_del(cdev); + + return rc; +} + +/** + * cdev_device_del() - inverse of cdev_device_add + * @dev: the device structure + * @cdev: the cdev structure + * + * cdev_device_del() is a helper function to call cdev_del and device_del. + * It should be used whenever cdev_device_add is used. + * + * If dev->devt is not set it will not remove the cdev and will be equivalent + * to device_del. + * + * NOTE: This guarantees that associated sysfs callbacks are not running + * or runnable, however any cdevs already open will remain and their fops + * will still be callable even after this function returns. + */ +void cdev_device_del(struct cdev *cdev, struct device *dev) +{ + device_del(dev); + if (dev->devt) + cdev_del(cdev); +} + static void cdev_unmap(dev_t dev, unsigned count) { kobj_unmap(cdev_map, dev, count); @@ -488,6 +567,10 @@ static void cdev_unmap(dev_t dev, unsigned count) * * cdev_del() removes @p from the system, possibly freeing the structure * itself. + * + * NOTE: This guarantees that cdev device will no longer be able to be + * opened, however any cdevs already open will remain and their fops will + * still be callable even after cdev_del returns. */ void cdev_del(struct cdev *p) { @@ -576,5 +659,8 @@ EXPORT_SYMBOL(cdev_init); EXPORT_SYMBOL(cdev_alloc); EXPORT_SYMBOL(cdev_del); EXPORT_SYMBOL(cdev_add); +EXPORT_SYMBOL(cdev_set_parent); +EXPORT_SYMBOL(cdev_device_add); +EXPORT_SYMBOL(cdev_device_del); EXPORT_SYMBOL(__register_chrdev); EXPORT_SYMBOL(__unregister_chrdev); diff --git a/include/linux/cdev.h b/include/linux/cdev.h index f8763615a5f2..408bc09ce497 100644 --- a/include/linux/cdev.h +++ b/include/linux/cdev.h @@ -4,6 +4,7 @@ #include #include #include +#include struct file_operations; struct inode; @@ -26,6 +27,10 @@ void cdev_put(struct cdev *p); int cdev_add(struct cdev *, dev_t, unsigned); +void cdev_set_parent(struct cdev *p, struct kobject *kobj); +int cdev_device_add(struct cdev *cdev, struct device *dev); +void cdev_device_del(struct cdev *cdev, struct device *dev); + void cdev_del(struct cdev *); void cd_forget(struct inode *); From 9540901d5ea333fb6fcc23579d1d0d633d9107a2 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Fri, 23 Nov 2018 09:54:55 +0800 Subject: [PATCH 040/387] ptp: Fix pass zero to ERR_PTR() in ptp_clock_register commit aea0a897af9e44c258e8ab9296fad417f1bc063a upstream. Fix smatch warning: drivers/ptp/ptp_clock.c:298 ptp_clock_register() warn: passing zero to 'ERR_PTR' 'err' should be set while device_create_with_groups and pps_register_source fails Fixes: 85a66e550195 ("ptp: create "pins" together with the rest of attributes") Signed-off-by: YueHaibing Acked-by: Richard Cochran Signed-off-by: David S. Miller Signed-off-by: Ben Hutchings Signed-off-by: Sasha Levin --- drivers/ptp/ptp_clock.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index d5ac33350889..b87b7b0867a4 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c @@ -222,8 +222,10 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, ptp->dev = device_create_with_groups(ptp_class, parent, ptp->devid, ptp, ptp->pin_attr_groups, "ptp%d", ptp->index); - if (IS_ERR(ptp->dev)) + if (IS_ERR(ptp->dev)) { + err = PTR_ERR(ptp->dev); goto no_device; + } /* Register a new PPS source. */ if (info->pps) { @@ -234,6 +236,7 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, pps.owner = info->owner; ptp->pps_source = pps_register_source(&pps, PTP_PPS_DEFAULTS); if (!ptp->pps_source) { + err = -EINVAL; pr_err("failed to register pps source\n"); goto no_pps; } From 89e8fc989feaac00bf1a7f9a766289422e2f5768 Mon Sep 17 00:00:00 2001 From: Vladis Dronov Date: Fri, 27 Dec 2019 03:26:27 +0100 Subject: [PATCH 041/387] ptp: fix the race between the release of ptp_clock and cdev commit a33121e5487b424339636b25c35d3a180eaa5f5e upstream. In a case when a ptp chardev (like /dev/ptp0) is open but an underlying device is removed, closing this file leads to a race. This reproduces easily in a kvm virtual machine: ts# cat openptp0.c int main() { ... fp = fopen("/dev/ptp0", "r"); ... sleep(10); } ts# uname -r 5.5.0-rc3-46cf053e ts# cat /proc/cmdline ... slub_debug=FZP ts# modprobe ptp_kvm ts# ./openptp0 & [1] 670 opened /dev/ptp0, sleeping 10s... ts# rmmod ptp_kvm ts# ls /dev/ptp* ls: cannot access '/dev/ptp*': No such file or directory ts# ...woken up [ 48.010809] general protection fault: 0000 [#1] SMP [ 48.012502] CPU: 6 PID: 658 Comm: openptp0 Not tainted 5.5.0-rc3-46cf053e #25 [ 48.014624] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), ... [ 48.016270] RIP: 0010:module_put.part.0+0x7/0x80 [ 48.017939] RSP: 0018:ffffb3850073be00 EFLAGS: 00010202 [ 48.018339] RAX: 000000006b6b6b6b RBX: 6b6b6b6b6b6b6b6b RCX: ffff89a476c00ad0 [ 48.018936] RDX: fffff65a08d3ea08 RSI: 0000000000000247 RDI: 6b6b6b6b6b6b6b6b [ 48.019470] ... ^^^ a slub poison [ 48.023854] Call Trace: [ 48.024050] __fput+0x21f/0x240 [ 48.024288] task_work_run+0x79/0x90 [ 48.024555] do_exit+0x2af/0xab0 [ 48.024799] ? vfs_write+0x16a/0x190 [ 48.025082] do_group_exit+0x35/0x90 [ 48.025387] __x64_sys_exit_group+0xf/0x10 [ 48.025737] do_syscall_64+0x3d/0x130 [ 48.026056] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 48.026479] RIP: 0033:0x7f53b12082f6 [ 48.026792] ... [ 48.030945] Modules linked in: ptp i6300esb watchdog [last unloaded: ptp_kvm] [ 48.045001] Fixing recursive fault but reboot is needed! This happens in: static void __fput(struct file *file) { ... if (file->f_op->release) file->f_op->release(inode, file); <<< cdev is kfree'd here if (unlikely(S_ISCHR(inode->i_mode) && inode->i_cdev != NULL && !(mode & FMODE_PATH))) { cdev_put(inode->i_cdev); <<< cdev fields are accessed here Namely: __fput() posix_clock_release() kref_put(&clk->kref, delete_clock) <<< the last reference delete_clock() delete_ptp_clock() kfree(ptp) <<< cdev is embedded in ptp cdev_put module_put(p->owner) <<< *p is kfree'd, bang! Here cdev is embedded in posix_clock which is embedded in ptp_clock. The race happens because ptp_clock's lifetime is controlled by two refcounts: kref and cdev.kobj in posix_clock. This is wrong. Make ptp_clock's sysfs device a parent of cdev with cdev_device_add() created especially for such cases. This way the parent device with its ptp_clock is not released until all references to the cdev are released. This adds a requirement that an initialized but not exposed struct device should be provided to posix_clock_register() by a caller instead of a simple dev_t. This approach was adopted from the commit 72139dfa2464 ("watchdog: Fix the race between the release of watchdog_core_data and cdev"). See details of the implementation in the commit 233ed09d7fda ("chardev: add helper function to register char devs with a struct device"). Link: https://lore.kernel.org/linux-fsdevel/20191125125342.6189-1-vdronov@redhat.com/T/#u Analyzed-by: Stephen Johnston Analyzed-by: Vern Lovejoy Signed-off-by: Vladis Dronov Acked-by: Richard Cochran Signed-off-by: David S. Miller Signed-off-by: Ben Hutchings Signed-off-by: Sasha Levin --- drivers/ptp/ptp_clock.c | 31 ++++++++++++++----------------- drivers/ptp/ptp_private.h | 2 +- include/linux/posix-clock.h | 19 +++++++++++-------- kernel/time/posix-clock.c | 31 +++++++++++++------------------ 4 files changed, 39 insertions(+), 44 deletions(-) diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index b87b7b0867a4..2c1ae324da18 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c @@ -171,9 +171,9 @@ static struct posix_clock_operations ptp_clock_ops = { .read = ptp_read, }; -static void delete_ptp_clock(struct posix_clock *pc) +static void ptp_clock_release(struct device *dev) { - struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); + struct ptp_clock *ptp = container_of(dev, struct ptp_clock, dev); mutex_destroy(&ptp->tsevq_mux); mutex_destroy(&ptp->pincfg_mux); @@ -205,7 +205,6 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, } ptp->clock.ops = ptp_clock_ops; - ptp->clock.release = delete_ptp_clock; ptp->info = info; ptp->devid = MKDEV(major, index); ptp->index = index; @@ -218,15 +217,6 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, if (err) goto no_pin_groups; - /* Create a new device in our class. */ - ptp->dev = device_create_with_groups(ptp_class, parent, ptp->devid, - ptp, ptp->pin_attr_groups, - "ptp%d", ptp->index); - if (IS_ERR(ptp->dev)) { - err = PTR_ERR(ptp->dev); - goto no_device; - } - /* Register a new PPS source. */ if (info->pps) { struct pps_source_info pps; @@ -242,8 +232,18 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, } } - /* Create a posix clock. */ - err = posix_clock_register(&ptp->clock, ptp->devid); + /* Initialize a new device of our class in our clock structure. */ + device_initialize(&ptp->dev); + ptp->dev.devt = ptp->devid; + ptp->dev.class = ptp_class; + ptp->dev.parent = parent; + ptp->dev.groups = ptp->pin_attr_groups; + ptp->dev.release = ptp_clock_release; + dev_set_drvdata(&ptp->dev, ptp); + dev_set_name(&ptp->dev, "ptp%d", ptp->index); + + /* Create a posix clock and link it to the device. */ + err = posix_clock_register(&ptp->clock, &ptp->dev); if (err) { pr_err("failed to create posix clock\n"); goto no_clock; @@ -255,8 +255,6 @@ no_clock: if (ptp->pps_source) pps_unregister_source(ptp->pps_source); no_pps: - device_destroy(ptp_class, ptp->devid); -no_device: ptp_cleanup_pin_groups(ptp); no_pin_groups: mutex_destroy(&ptp->tsevq_mux); @@ -278,7 +276,6 @@ int ptp_clock_unregister(struct ptp_clock *ptp) if (ptp->pps_source) pps_unregister_source(ptp->pps_source); - device_destroy(ptp_class, ptp->devid); ptp_cleanup_pin_groups(ptp); posix_clock_unregister(&ptp->clock); diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h index d95888974d0c..15346e840caa 100644 --- a/drivers/ptp/ptp_private.h +++ b/drivers/ptp/ptp_private.h @@ -40,7 +40,7 @@ struct timestamp_event_queue { struct ptp_clock { struct posix_clock clock; - struct device *dev; + struct device dev; struct ptp_clock_info *info; dev_t devid; int index; /* index into clocks.map */ diff --git a/include/linux/posix-clock.h b/include/linux/posix-clock.h index 83b22ae9ae12..b39420a0321c 100644 --- a/include/linux/posix-clock.h +++ b/include/linux/posix-clock.h @@ -104,29 +104,32 @@ struct posix_clock_operations { * * @ops: Functional interface to the clock * @cdev: Character device instance for this clock - * @kref: Reference count. + * @dev: Pointer to the clock's device. * @rwsem: Protects the 'zombie' field from concurrent access. * @zombie: If 'zombie' is true, then the hardware has disappeared. - * @release: A function to free the structure when the reference count reaches - * zero. May be NULL if structure is statically allocated. * * Drivers should embed their struct posix_clock within a private * structure, obtaining a reference to it during callbacks using * container_of(). + * + * Drivers should supply an initialized but not exposed struct device + * to posix_clock_register(). It is used to manage lifetime of the + * driver's private structure. It's 'release' field should be set to + * a release function for this private structure. */ struct posix_clock { struct posix_clock_operations ops; struct cdev cdev; - struct kref kref; + struct device *dev; struct rw_semaphore rwsem; bool zombie; - void (*release)(struct posix_clock *clk); }; /** * posix_clock_register() - register a new clock - * @clk: Pointer to the clock. Caller must provide 'ops' and 'release' - * @devid: Allocated device id + * @clk: Pointer to the clock. Caller must provide 'ops' field + * @dev: Pointer to the initialized device. Caller must provide + * 'release' field * * A clock driver calls this function to register itself with the * clock device subsystem. If 'clk' points to dynamically allocated @@ -135,7 +138,7 @@ struct posix_clock { * * Returns zero on success, non-zero otherwise. */ -int posix_clock_register(struct posix_clock *clk, dev_t devid); +int posix_clock_register(struct posix_clock *clk, struct device *dev); /** * posix_clock_unregister() - unregister a clock diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c index e24008c098c6..45a0a26023d4 100644 --- a/kernel/time/posix-clock.c +++ b/kernel/time/posix-clock.c @@ -25,8 +25,6 @@ #include #include -static void delete_clock(struct kref *kref); - /* * Returns NULL if the posix_clock instance attached to 'fp' is old and stale. */ @@ -168,7 +166,7 @@ static int posix_clock_open(struct inode *inode, struct file *fp) err = 0; if (!err) { - kref_get(&clk->kref); + get_device(clk->dev); fp->private_data = clk; } out: @@ -184,7 +182,7 @@ static int posix_clock_release(struct inode *inode, struct file *fp) if (clk->ops.release) err = clk->ops.release(clk); - kref_put(&clk->kref, delete_clock); + put_device(clk->dev); fp->private_data = NULL; @@ -206,38 +204,35 @@ static const struct file_operations posix_clock_file_operations = { #endif }; -int posix_clock_register(struct posix_clock *clk, dev_t devid) +int posix_clock_register(struct posix_clock *clk, struct device *dev) { int err; - kref_init(&clk->kref); init_rwsem(&clk->rwsem); cdev_init(&clk->cdev, &posix_clock_file_operations); + err = cdev_device_add(&clk->cdev, dev); + if (err) { + pr_err("%s unable to add device %d:%d\n", + dev_name(dev), MAJOR(dev->devt), MINOR(dev->devt)); + return err; + } clk->cdev.owner = clk->ops.owner; - err = cdev_add(&clk->cdev, devid, 1); + clk->dev = dev; - return err; + return 0; } EXPORT_SYMBOL_GPL(posix_clock_register); -static void delete_clock(struct kref *kref) -{ - struct posix_clock *clk = container_of(kref, struct posix_clock, kref); - - if (clk->release) - clk->release(clk); -} - void posix_clock_unregister(struct posix_clock *clk) { - cdev_del(&clk->cdev); + cdev_device_del(&clk->cdev, clk->dev); down_write(&clk->rwsem); clk->zombie = true; up_write(&clk->rwsem); - kref_put(&clk->kref, delete_clock); + put_device(clk->dev); } EXPORT_SYMBOL_GPL(posix_clock_unregister); From 31db64366dea25222e8c601898bffb14af0c803f Mon Sep 17 00:00:00 2001 From: Vladis Dronov Date: Mon, 13 Jan 2020 14:00:09 +0100 Subject: [PATCH 042/387] ptp: free ptp device pin descriptors properly commit 75718584cb3c64e6269109d4d54f888ac5a5fd15 upstream. There is a bug in ptp_clock_unregister(), where ptp_cleanup_pin_groups() first frees ptp->pin_{,dev_}attr, but then posix_clock_unregister() needs them to destroy a related sysfs device. These functions can not be just swapped, as posix_clock_unregister() frees ptp which is needed in the ptp_cleanup_pin_groups(). Fix this by calling ptp_cleanup_pin_groups() in ptp_clock_release(), right before ptp is freed. This makes this patch fix an UAF bug in a patch which fixes an UAF bug. Reported-by: Antti Laakso Fixes: a33121e5487b ("ptp: fix the race between the release of ptp_clock and cdev") Link: https://lore.kernel.org/netdev/3d2bd09735dbdaf003585ca376b7c1e5b69a19bd.camel@intel.com/ Signed-off-by: Vladis Dronov Acked-by: Richard Cochran Signed-off-by: David S. Miller Signed-off-by: Ben Hutchings Signed-off-by: Sasha Levin --- drivers/ptp/ptp_clock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index 2c1ae324da18..bf1536f1c90b 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c @@ -175,6 +175,7 @@ static void ptp_clock_release(struct device *dev) { struct ptp_clock *ptp = container_of(dev, struct ptp_clock, dev); + ptp_cleanup_pin_groups(ptp); mutex_destroy(&ptp->tsevq_mux); mutex_destroy(&ptp->pincfg_mux); ida_simple_remove(&ptp_clocks_map, ptp->index); @@ -276,9 +277,8 @@ int ptp_clock_unregister(struct ptp_clock *ptp) if (ptp->pps_source) pps_unregister_source(ptp->pps_source); - ptp_cleanup_pin_groups(ptp); - posix_clock_unregister(&ptp->clock); + return 0; } EXPORT_SYMBOL(ptp_clock_unregister); From fccb7bbcc28f97a012601f6c75b99b63fc10ac7b Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Mon, 20 Apr 2020 18:14:14 -0700 Subject: [PATCH 043/387] shmem: fix possible deadlocks on shmlock_user_lock [ Upstream commit ea0dfeb4209b4eab954d6e00ed136bc6b48b380d ] Recent commit 71725ed10c40 ("mm: huge tmpfs: try to split_huge_page() when punching hole") has allowed syzkaller to probe deeper, uncovering a long-standing lockdep issue between the irq-unsafe shmlock_user_lock, the irq-safe xa_lock on mapping->i_pages, and shmem inode's info->lock which nests inside xa_lock (or tree_lock) since 4.8's shmem_uncharge(). user_shm_lock(), servicing SysV shmctl(SHM_LOCK), wants shmlock_user_lock while its caller shmem_lock() holds info->lock with interrupts disabled; but hugetlbfs_file_setup() calls user_shm_lock() with interrupts enabled, and might be interrupted by a writeback endio wanting xa_lock on i_pages. This may not risk an actual deadlock, since shmem inodes do not take part in writeback accounting, but there are several easy ways to avoid it. Requiring interrupts disabled for shmlock_user_lock would be easy, but it's a high-level global lock for which that seems inappropriate. Instead, recall that the use of info->lock to guard info->flags in shmem_lock() dates from pre-3.1 days, when races with SHMEM_PAGEIN and SHMEM_TRUNCATE could occur: nowadays it serves no purpose, the only flag added or removed is VM_LOCKED itself, and calls to shmem_lock() an inode are already serialized by the caller. Take info->lock out of the chain and the possibility of deadlock or lockdep warning goes away. Fixes: 4595ef88d136 ("shmem: make shmem_inode_info::lock irq-safe") Reported-by: syzbot+c8a8197c8852f566b9d9@syzkaller.appspotmail.com Reported-by: syzbot+40b71e145e73f78f81ad@syzkaller.appspotmail.com Signed-off-by: Hugh Dickins Signed-off-by: Andrew Morton Acked-by: Yang Shi Cc: Yang Shi Link: http://lkml.kernel.org/r/alpine.LSU.2.11.2004161707410.16322@eggly.anvils Link: https://lore.kernel.org/lkml/000000000000e5838c05a3152f53@google.com/ Link: https://lore.kernel.org/lkml/0000000000003712b305a331d3b1@google.com/ Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin --- mm/shmem.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mm/shmem.c b/mm/shmem.c index 90ccbb35458b..31b0c09fe6c6 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -2082,7 +2082,11 @@ int shmem_lock(struct file *file, int lock, struct user_struct *user) struct shmem_inode_info *info = SHMEM_I(inode); int retval = -ENOMEM; - spin_lock_irq(&info->lock); + /* + * What serializes the accesses to info->flags? + * ipc_lock_object() when called from shmctl_do_lock(), + * no serialization needed when called from shm_destroy(). + */ if (lock && !(info->flags & VM_LOCKED)) { if (!user_shm_lock(inode->i_size, user)) goto out_nomem; @@ -2097,7 +2101,6 @@ int shmem_lock(struct file *file, int lock, struct user_struct *user) retval = 0; out_nomem: - spin_unlock_irq(&info->lock); return retval; } From bf3c068c5c074ef417633c350e48109fe2578dfa Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Mon, 27 Apr 2020 08:18:03 +0200 Subject: [PATCH 044/387] net/sonic: Fix a resource leak in an error handling path in 'jazz_sonic_probe()' [ Upstream commit 10e3cc180e64385edc9890c6855acf5ed9ca1339 ] A call to 'dma_alloc_coherent()' is hidden in 'sonic_alloc_descriptors()', called from 'sonic_probe1()'. This is correctly freed in the remove function, but not in the error handling path of the probe function. Fix it and add the missing 'dma_free_coherent()' call. While at it, rename a label in order to be slightly more informative. Fixes: efcce839360f ("[PATCH] macsonic/jazzsonic network drivers update") Signed-off-by: Christophe JAILLET Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/natsemi/jazzsonic.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/natsemi/jazzsonic.c b/drivers/net/ethernet/natsemi/jazzsonic.c index acf3f11e38cc..68d2f31921ff 100644 --- a/drivers/net/ethernet/natsemi/jazzsonic.c +++ b/drivers/net/ethernet/natsemi/jazzsonic.c @@ -247,13 +247,15 @@ static int jazz_sonic_probe(struct platform_device *pdev) goto out; err = register_netdev(dev); if (err) - goto out1; + goto undo_probe1; printk("%s: MAC %pM IRQ %d\n", dev->name, dev->dev_addr, dev->irq); return 0; -out1: +undo_probe1: + dma_free_coherent(lp->device, SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), + lp->descriptors, lp->descriptors_laddr); release_mem_region(dev->base_addr, SONIC_MEM_SIZE); out: free_netdev(dev); From f0d331d1ababe75cdd3690fe1c99f6cc6aded099 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 26 Apr 2020 22:59:21 +0200 Subject: [PATCH 045/387] net: moxa: Fix a potential double 'free_irq()' [ Upstream commit ee8d2267f0e39a1bfd95532da3a6405004114b27 ] Should an irq requested with 'devm_request_irq' be released explicitly, it should be done by 'devm_free_irq()', not 'free_irq()'. Fixes: 6c821bd9edc9 ("net: Add MOXA ART SoCs ethernet driver") Signed-off-by: Christophe JAILLET Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/moxa/moxart_ether.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c index 0622fd03941b..6fe61d9343cb 100644 --- a/drivers/net/ethernet/moxa/moxart_ether.c +++ b/drivers/net/ethernet/moxa/moxart_ether.c @@ -571,7 +571,7 @@ static int moxart_remove(struct platform_device *pdev) struct net_device *ndev = platform_get_drvdata(pdev); unregister_netdev(ndev); - free_irq(ndev->irq, ndev); + devm_free_irq(&pdev->dev, ndev->irq, ndev); moxart_mac_free_memory(ndev); free_netdev(ndev); From 23d07a9b625b387eaf45d0d272a23d7b133a635b Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 30 Apr 2020 23:30:49 +0200 Subject: [PATCH 046/387] drop_monitor: work around gcc-10 stringop-overflow warning [ Upstream commit dc30b4059f6e2abf3712ab537c8718562b21c45d ] The current gcc-10 snapshot produces a false-positive warning: net/core/drop_monitor.c: In function 'trace_drop_common.constprop': cc1: error: writing 8 bytes into a region of size 0 [-Werror=stringop-overflow=] In file included from net/core/drop_monitor.c:23: include/uapi/linux/net_dropmon.h:36:8: note: at offset 0 to object 'entries' with size 4 declared here 36 | __u32 entries; | ^~~~~~~ I reported this in the gcc bugzilla, but in case it does not get fixed in the release, work around it by using a temporary variable. Fixes: 9a8afc8d3962 ("Network Drop Monitor: Adding drop monitor implementation & Netlink protocol") Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94881 Signed-off-by: Arnd Bergmann Acked-by: Neil Horman Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/core/drop_monitor.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c index ca2c9c8b9a3e..6d7ff117f379 100644 --- a/net/core/drop_monitor.c +++ b/net/core/drop_monitor.c @@ -159,6 +159,7 @@ static void sched_send_work(unsigned long _data) static void trace_drop_common(struct sk_buff *skb, void *location) { struct net_dm_alert_msg *msg; + struct net_dm_drop_point *point; struct nlmsghdr *nlh; struct nlattr *nla; int i; @@ -177,11 +178,13 @@ static void trace_drop_common(struct sk_buff *skb, void *location) nlh = (struct nlmsghdr *)dskb->data; nla = genlmsg_data(nlmsg_data(nlh)); msg = nla_data(nla); + point = msg->points; for (i = 0; i < msg->entries; i++) { - if (!memcmp(&location, msg->points[i].pc, sizeof(void *))) { - msg->points[i].count++; + if (!memcmp(&location, &point->pc, sizeof(void *))) { + point->count++; goto out; } + point++; } if (msg->entries == dm_hit_limit) goto out; @@ -190,8 +193,8 @@ static void trace_drop_common(struct sk_buff *skb, void *location) */ __nla_reserve_nohdr(dskb, sizeof(struct net_dm_drop_point)); nla->nla_len += NLA_ALIGN(sizeof(struct net_dm_drop_point)); - memcpy(msg->points[msg->entries].pc, &location, sizeof(void *)); - msg->points[msg->entries].count = 1; + memcpy(point->pc, &location, sizeof(void *)); + point->count = 1; msg->entries++; if (!timer_pending(&data->send_timer)) { From 6950c2775e02e4be51b06901306ee641e8e5b3df Mon Sep 17 00:00:00 2001 From: Wu Bo Date: Tue, 14 Apr 2020 10:13:28 +0800 Subject: [PATCH 047/387] scsi: sg: add sg_remove_request in sg_write commit 83c6f2390040f188cc25b270b4befeb5628c1aee upstream. If the __copy_from_user function failed we need to call sg_remove_request in sg_write. Link: https://lore.kernel.org/r/610618d9-e983-fd56-ed0f-639428343af7@huawei.com Acked-by: Douglas Gilbert Signed-off-by: Wu Bo Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin [groeck: Backport to v5.4.y and older kernels] Signed-off-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/sg.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index c924df5538dd..417927b279b6 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -695,8 +695,10 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) hp->flags = input_size; /* structure abuse ... */ hp->pack_id = old_hdr.pack_id; hp->usr_ptr = NULL; - if (__copy_from_user(cmnd, buf, cmd_size)) + if (__copy_from_user(cmnd, buf, cmd_size)) { + sg_remove_request(sfp, srp); return -EFAULT; + } /* * SG_DXFER_TO_FROM_DEV is functionally equivalent to SG_DXFER_FROM_DEV, * but is is possible that the app intended SG_DXFER_TO_DEV, because there From 15029156d7ac0ae4ec80f577bb25f68fe07c8af1 Mon Sep 17 00:00:00 2001 From: "wuxu.wu" Date: Wed, 1 Jan 2020 11:39:41 +0800 Subject: [PATCH 048/387] spi: spi-dw: Add lock protect dw_spi rx/tx to prevent concurrent calls commit 19b61392c5a852b4e8a0bf35aecb969983c5932d upstream. dw_spi_irq() and dw_spi_transfer_one concurrent calls. I find a panic in dw_writer(): txw = *(u8 *)(dws->tx), when dw->tx==null, dw->len==4, and dw->tx_end==1. When tpm driver's message overtime dw_spi_irq() and dw_spi_transfer_one may concurrent visit dw_spi, so I think dw_spi structure lack of protection. Otherwise dw_spi_transfer_one set dw rx/tx buffer and then open irq, store dw rx/tx instructions and other cores handle irq load dw rx/tx instructions may out of order. [ 1025.321302] Call trace: ... [ 1025.321319] __crash_kexec+0x98/0x148 [ 1025.321323] panic+0x17c/0x314 [ 1025.321329] die+0x29c/0x2e8 [ 1025.321334] die_kernel_fault+0x68/0x78 [ 1025.321337] __do_kernel_fault+0x90/0xb0 [ 1025.321346] do_page_fault+0x88/0x500 [ 1025.321347] do_translation_fault+0xa8/0xb8 [ 1025.321349] do_mem_abort+0x68/0x118 [ 1025.321351] el1_da+0x20/0x8c [ 1025.321362] dw_writer+0xc8/0xd0 [ 1025.321364] interrupt_transfer+0x60/0x110 [ 1025.321365] dw_spi_irq+0x48/0x70 ... Signed-off-by: wuxu.wu Link: https://lore.kernel.org/r/1577849981-31489-1-git-send-email-wuxu.wu@huawei.com Signed-off-by: Mark Brown Signed-off-by: Nobuhiro Iwamatsu (CIP) Signed-off-by: Greg Kroah-Hartman --- drivers/spi/spi-dw.c | 15 ++++++++++++--- drivers/spi/spi-dw.h | 1 + 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index c4226c07e091..16f0def9df82 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -180,9 +180,11 @@ static inline u32 rx_max(struct dw_spi *dws) static void dw_writer(struct dw_spi *dws) { - u32 max = tx_max(dws); + u32 max; u16 txw = 0; + spin_lock(&dws->buf_lock); + max = tx_max(dws); while (max--) { /* Set the tx word if the transfer's original "tx" is not null */ if (dws->tx_end - dws->len) { @@ -194,13 +196,16 @@ static void dw_writer(struct dw_spi *dws) dw_write_io_reg(dws, DW_SPI_DR, txw); dws->tx += dws->n_bytes; } + spin_unlock(&dws->buf_lock); } static void dw_reader(struct dw_spi *dws) { - u32 max = rx_max(dws); + u32 max; u16 rxw; + spin_lock(&dws->buf_lock); + max = rx_max(dws); while (max--) { rxw = dw_read_io_reg(dws, DW_SPI_DR); /* Care rx only if the transfer's original "rx" is not null */ @@ -212,6 +217,7 @@ static void dw_reader(struct dw_spi *dws) } dws->rx += dws->n_bytes; } + spin_unlock(&dws->buf_lock); } static void int_error_stop(struct dw_spi *dws, const char *msg) @@ -284,18 +290,20 @@ static int dw_spi_transfer_one(struct spi_master *master, { struct dw_spi *dws = spi_master_get_devdata(master); struct chip_data *chip = spi_get_ctldata(spi); + unsigned long flags; u8 imask = 0; u16 txlevel = 0; u32 cr0; int ret; dws->dma_mapped = 0; - + spin_lock_irqsave(&dws->buf_lock, flags); dws->tx = (void *)transfer->tx_buf; dws->tx_end = dws->tx + transfer->len; dws->rx = transfer->rx_buf; dws->rx_end = dws->rx + transfer->len; dws->len = transfer->len; + spin_unlock_irqrestore(&dws->buf_lock, flags); spi_enable_chip(dws, 0); @@ -487,6 +495,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) dws->dma_inited = 0; dws->dma_addr = (dma_addr_t)(dws->paddr + DW_SPI_DR); snprintf(dws->name, sizeof(dws->name), "dw_spi%d", dws->bus_num); + spin_lock_init(&dws->buf_lock); ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, dws->name, master); if (ret < 0) { diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index c21ca02f8ec5..e80338e6ffa2 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -117,6 +117,7 @@ struct dw_spi { size_t len; void *tx; void *tx_end; + spinlock_t buf_lock; void *rx; void *rx_end; int dma_mapped; From 79d25ee27b5dafa06bd967f10217da178e220a9e Mon Sep 17 00:00:00 2001 From: Samuel Cabrero Date: Tue, 11 Jul 2017 12:44:39 +0200 Subject: [PATCH 049/387] cifs: Check for timeout on Negotiate stage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 76e752701a8af4404bbd9c45723f7cbd6e4a251e ] Some servers seem to accept connections while booting but never send the SMBNegotiate response neither close the connection, causing all processes accessing the share hang on uninterruptible sleep state. This happens when the cifs_demultiplex_thread detects the server is unresponsive so releases the socket and start trying to reconnect. At some point, the faulty server will accept the socket and the TCP status will be set to NeedNegotiate. The first issued command accessing the share will start the negotiation (pid 5828 below), but the response will never arrive so other commands will be blocked waiting on the mutex (pid 55352). This patch checks for unresponsive servers also on the negotiate stage releasing the socket and reconnecting if the response is not received and checking again the tcp state when the mutex is acquired. PID: 55352 TASK: ffff880fd6cc02c0 CPU: 0 COMMAND: "ls" #0 [ffff880fd9add9f0] schedule at ffffffff81467eb9 #1 [ffff880fd9addb38] __mutex_lock_slowpath at ffffffff81468fe0 #2 [ffff880fd9addba8] mutex_lock at ffffffff81468b1a #3 [ffff880fd9addbc0] cifs_reconnect_tcon at ffffffffa042f905 [cifs] #4 [ffff880fd9addc60] smb_init at ffffffffa042faeb [cifs] #5 [ffff880fd9addca0] CIFSSMBQPathInfo at ffffffffa04360b5 [cifs] .... Which is waiting a mutex owned by: PID: 5828 TASK: ffff880fcc55e400 CPU: 0 COMMAND: "xxxx" #0 [ffff880fbfdc19b8] schedule at ffffffff81467eb9 #1 [ffff880fbfdc1b00] wait_for_response at ffffffffa044f96d [cifs] #2 [ffff880fbfdc1b60] SendReceive at ffffffffa04505ce [cifs] #3 [ffff880fbfdc1bb0] CIFSSMBNegotiate at ffffffffa0438d79 [cifs] #4 [ffff880fbfdc1c50] cifs_negotiate_protocol at ffffffffa043b383 [cifs] #5 [ffff880fbfdc1c80] cifs_reconnect_tcon at ffffffffa042f911 [cifs] #6 [ffff880fbfdc1d20] smb_init at ffffffffa042faeb [cifs] #7 [ffff880fbfdc1d60] CIFSSMBQFSInfo at ffffffffa0434eb0 [cifs] .... Signed-off-by: Samuel Cabrero Reviewed-by: Aurélien Aptel Reviewed-by: Ronnie Sahlberg Signed-off-by: Steve French Signed-off-by: Sasha Levin --- fs/cifs/cifssmb.c | 12 ++++++++++++ fs/cifs/connect.c | 3 ++- fs/cifs/smb2pdu.c | 12 ++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 741b83c59a30..568abcd6d0dd 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -184,6 +184,18 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command) * reconnect the same SMB session */ mutex_lock(&ses->session_mutex); + + /* + * Recheck after acquire mutex. If another thread is negotiating + * and the server never sends an answer the socket will be closed + * and tcpStatus set to reconnect. + */ + if (server->tcpStatus == CifsNeedReconnect) { + rc = -EHOSTDOWN; + mutex_unlock(&ses->session_mutex); + goto out; + } + rc = cifs_negotiate_protocol(0, ses); if (rc == 0 && ses->need_reconnect) rc = cifs_setup_session(0, ses, nls_codepage); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index c018d161735c..37c8cac86431 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -561,7 +561,8 @@ server_unresponsive(struct TCP_Server_Info *server) * 65s kernel_recvmsg times out, and we see that we haven't gotten * a response in >60s. */ - if (server->tcpStatus == CifsGood && + if ((server->tcpStatus == CifsGood || + server->tcpStatus == CifsNeedNegotiate) && time_after(jiffies, server->lstrp + 2 * server->echo_interval)) { cifs_dbg(VFS, "Server %s has not responded in %lu seconds. Reconnecting...\n", server->hostname, (2 * server->echo_interval) / HZ); diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index e8dc28dbe563..0a23b6002ff1 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -246,6 +246,18 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon) * the same SMB session */ mutex_lock(&tcon->ses->session_mutex); + + /* + * Recheck after acquire mutex. If another thread is negotiating + * and the server never sends an answer the socket will be closed + * and tcpStatus set to reconnect. + */ + if (server->tcpStatus == CifsNeedReconnect) { + rc = -EHOSTDOWN; + mutex_unlock(&tcon->ses->session_mutex); + goto out; + } + rc = cifs_negotiate_protocol(0, tcon->ses); if (!rc && tcon->ses->need_reconnect) { rc = cifs_setup_session(0, tcon->ses, nls_codepage); From f0fff9a77e8aa241f9ad7270e6bf8f1502dd3a19 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Sat, 6 Jul 2019 06:52:46 +1000 Subject: [PATCH 050/387] cifs: Fix a race condition with cifs_echo_request [ Upstream commit f2caf901c1b7ce65f9e6aef4217e3241039db768 ] There is a race condition with how we send (or supress and don't send) smb echos that will cause the client to incorrectly think the server is unresponsive and thus needs to be reconnected. Summary of the race condition: 1) Daisy chaining scheduling creates a gap. 2) If traffic comes unfortunate shortly after the last echo, the planned echo is suppressed. 3) Due to the gap, the next echo transmission is delayed until after the timeout, which is set hard to twice the echo interval. This is fixed by changing the timeouts from 2 to three times the echo interval. Detailed description of the bug: https://lutz.donnerhacke.de/eng/Blog/Groundhog-Day-with-SMB-remount Signed-off-by: Ronnie Sahlberg Reviewed-by: Pavel Shilovsky Signed-off-by: Steve French Signed-off-by: Sasha Levin --- fs/cifs/connect.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 37c8cac86431..3545b237187a 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -551,10 +551,10 @@ static bool server_unresponsive(struct TCP_Server_Info *server) { /* - * We need to wait 2 echo intervals to make sure we handle such + * We need to wait 3 echo intervals to make sure we handle such * situations right: * 1s client sends a normal SMB request - * 2s client gets a response + * 3s client gets a response * 30s echo workqueue job pops, and decides we got a response recently * and don't need to send another * ... @@ -563,9 +563,9 @@ server_unresponsive(struct TCP_Server_Info *server) */ if ((server->tcpStatus == CifsGood || server->tcpStatus == CifsNeedNegotiate) && - time_after(jiffies, server->lstrp + 2 * server->echo_interval)) { + time_after(jiffies, server->lstrp + 3 * server->echo_interval)) { cifs_dbg(VFS, "Server %s has not responded in %lu seconds. Reconnecting...\n", - server->hostname, (2 * server->echo_interval) / HZ); + server->hostname, (3 * server->echo_interval) / HZ); cifs_reconnect(server); wake_up(&server->response_q); return true; From 87b49639e11c13dac42d3a2fdd85fc0a0d35143c Mon Sep 17 00:00:00 2001 From: Madhuparna Bhowmik Date: Thu, 16 Apr 2020 11:53:35 +0530 Subject: [PATCH 051/387] dmaengine: pch_dma.c: Avoid data race between probe and irq handler [ Upstream commit 2e45676a4d33af47259fa186ea039122ce263ba9 ] pd->dma.dev is read in irq handler pd_irq(). However, it is set to pdev->dev after request_irq(). Therefore, set pd->dma.dev to pdev->dev before request_irq() to avoid data race between pch_dma_probe() and pd_irq(). Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Madhuparna Bhowmik Link: https://lore.kernel.org/r/20200416062335.29223-1-madhuparnabhowmik10@gmail.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/dma/pch_dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c index df95727dc2fb..8a0c70e4f727 100644 --- a/drivers/dma/pch_dma.c +++ b/drivers/dma/pch_dma.c @@ -876,6 +876,7 @@ static int pch_dma_probe(struct pci_dev *pdev, } pci_set_master(pdev); + pd->dma.dev = &pdev->dev; err = request_irq(pdev->irq, pd_irq, IRQF_SHARED, DRV_NAME, pd); if (err) { @@ -891,7 +892,6 @@ static int pch_dma_probe(struct pci_dev *pdev, goto err_free_irq; } - pd->dma.dev = &pdev->dev; INIT_LIST_HEAD(&pd->dma.channels); From 6f53659a06780eec15454798ed20571f0ec23fe0 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Sun, 19 Apr 2020 18:49:09 +0200 Subject: [PATCH 052/387] dmaengine: mmp_tdma: Reset channel error on release [ Upstream commit 0c89446379218698189a47871336cb30286a7197 ] When a channel configuration fails, the status of the channel is set to DEV_ERROR so that an attempt to submit it fails. However, this status sticks until the heat end of the universe, making it impossible to recover from the error. Let's reset it when the channel is released so that further use of the channel with correct configuration is not impacted. Signed-off-by: Lubomir Rintel Link: https://lore.kernel.org/r/20200419164912.670973-5-lkundrak@v3.sk Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/dma/mmp_tdma.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/dma/mmp_tdma.c b/drivers/dma/mmp_tdma.c index 13c68b6434ce..15b4a44e6006 100644 --- a/drivers/dma/mmp_tdma.c +++ b/drivers/dma/mmp_tdma.c @@ -362,6 +362,8 @@ static void mmp_tdma_free_descriptor(struct mmp_tdma_chan *tdmac) gen_pool_free(gpool, (unsigned long)tdmac->desc_arr, size); tdmac->desc_arr = NULL; + if (tdmac->status == DMA_ERROR) + tdmac->status = DMA_COMPLETE; return; } From bb577c20b991c2c16c6172d82f0e12d2e4658eef Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Tue, 28 Apr 2020 15:38:36 +0300 Subject: [PATCH 053/387] ALSA: hda/hdmi: fix race in monitor detection during probe [ Upstream commit ca76282b6faffc83601c25bd2a95f635c03503ef ] A race exists between build_pcms() and build_controls() phases of codec setup. Build_pcms() sets up notifier for jack events. If a monitor event is received before build_controls() is run, the initial jack state is lost and never reported via mixer controls. The problem can be hit at least with SOF as the controller driver. SOF calls snd_hda_codec_build_controls() in its workqueue-based probe and this can be delayed enough to hit the race condition. Fix the issue by invalidating the per-pin ELD information when build_controls() is called. The existing call to hdmi_present_sense() will update the ELD contents. This ensures initial monitor state is correctly reflected via mixer controls. BugLink: https://github.com/thesofproject/linux/issues/1687 Signed-off-by: Kai Vehmanen Link: https://lore.kernel.org/r/20200428123836.24512-1-kai.vehmanen@linux.intel.com Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/pci/hda/patch_hdmi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index e19f447e27ae..a866a20349c3 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -2044,7 +2044,9 @@ static int generic_hdmi_build_controls(struct hda_codec *codec) for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); + struct hdmi_eld *pin_eld = &per_pin->sink_eld; + pin_eld->eld_valid = false; hdmi_present_sense(per_pin, 0); } From f5c0c5434e8b2e305e41080b8bd261547d71a700 Mon Sep 17 00:00:00 2001 From: Vasily Averin Date: Wed, 29 Apr 2020 12:34:36 +0300 Subject: [PATCH 054/387] drm/qxl: lost qxl_bo_kunmap_atomic_page in qxl_image_init_helper() [ Upstream commit 5b5703dbafae74adfbe298a56a81694172caf5e6 ] v2: removed TODO reminder Signed-off-by: Vasily Averin Link: http://patchwork.freedesktop.org/patch/msgid/a4e0ae09-a73c-1c62-04ef-3f990d41bea9@virtuozzo.com Signed-off-by: Gerd Hoffmann Signed-off-by: Sasha Levin --- drivers/gpu/drm/qxl/qxl_image.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/qxl/qxl_image.c b/drivers/gpu/drm/qxl/qxl_image.c index 7fbcc35e8ad3..c89c10055641 100644 --- a/drivers/gpu/drm/qxl/qxl_image.c +++ b/drivers/gpu/drm/qxl/qxl_image.c @@ -210,7 +210,8 @@ qxl_image_init_helper(struct qxl_device *qdev, break; default: DRM_ERROR("unsupported image bit depth\n"); - return -EINVAL; /* TODO: cleanup */ + qxl_bo_kunmap_atomic_page(qdev, image_bo, ptr); + return -EINVAL; } image->u.bitmap.flags = QXL_BITMAP_TOP_DOWN; image->u.bitmap.x = width; From 27634d8333a74aaf904a89575eac05503dbaf497 Mon Sep 17 00:00:00 2001 From: Vasily Averin Date: Wed, 13 May 2020 17:50:48 -0700 Subject: [PATCH 055/387] ipc/util.c: sysvipc_find_ipc() incorrectly updates position index [ Upstream commit 5e698222c70257d13ae0816720dde57c56f81e15 ] Commit 89163f93c6f9 ("ipc/util.c: sysvipc_find_ipc() should increase position index") is causing this bug (seen on 5.6.8): # ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages # ipcmk -Q Message queue id: 0 # ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages 0x82db8127 0 root 644 0 0 # ipcmk -Q Message queue id: 1 # ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages 0x82db8127 0 root 644 0 0 0x76d1fb2a 1 root 644 0 0 # ipcrm -q 0 # ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages 0x76d1fb2a 1 root 644 0 0 0x76d1fb2a 1 root 644 0 0 # ipcmk -Q Message queue id: 2 # ipcrm -q 2 # ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages 0x76d1fb2a 1 root 644 0 0 0x76d1fb2a 1 root 644 0 0 # ipcmk -Q Message queue id: 3 # ipcrm -q 1 # ipcs -q ------ Message Queues -------- key msqid owner perms used-bytes messages 0x7c982867 3 root 644 0 0 0x7c982867 3 root 644 0 0 0x7c982867 3 root 644 0 0 0x7c982867 3 root 644 0 0 Whenever an IPC item with a low id is deleted, the items with higher ids are duplicated, as if filling a hole. new_pos should jump through hole of unused ids, pos can be updated inside "for" cycle. Fixes: 89163f93c6f9 ("ipc/util.c: sysvipc_find_ipc() should increase position index") Reported-by: Andreas Schwab Reported-by: Randy Dunlap Signed-off-by: Vasily Averin Signed-off-by: Andrew Morton Acked-by: Waiman Long Cc: NeilBrown Cc: Steven Rostedt Cc: Ingo Molnar Cc: Peter Oberparleiter Cc: Davidlohr Bueso Cc: Manfred Spraul Cc: Link: http://lkml.kernel.org/r/4921fe9b-9385-a2b4-1dc4-1099be6d2e39@virtuozzo.com Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin --- ipc/util.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ipc/util.c b/ipc/util.c index e65ecf3ccbda..76d4afcde7bb 100644 --- a/ipc/util.c +++ b/ipc/util.c @@ -751,21 +751,21 @@ static struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t pos, total++; } - *new_pos = pos + 1; + ipc = NULL; if (total >= ids->in_use) - return NULL; + goto out; for (; pos < IPCMNI; pos++) { ipc = idr_find(&ids->ipcs_idr, pos); if (ipc != NULL) { rcu_read_lock(); ipc_lock_object(ipc); - return ipc; + break; } } - - /* Out of range - return NULL to terminate iteration */ - return NULL; +out: + *new_pos = pos + 1; + return ipc; } static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos) From e965c55d4ef594ff2426d204fbd58da0285be8db Mon Sep 17 00:00:00 2001 From: Grace Kao Date: Fri, 17 Apr 2020 12:11:54 +0800 Subject: [PATCH 056/387] pinctrl: cherryview: Add missing spinlock usage in chv_gpio_irq_handler [ Upstream commit 69388e15f5078c961b9e5319e22baea4c57deff1 ] According to Braswell NDA Specification Update (#557593), concurrent read accesses may result in returning 0xffffffff and write instructions may be dropped. We have an established format for the commit references, i.e. cdca06e4e859 ("pinctrl: baytrail: Add missing spinlock usage in byt_gpio_irq_handler") Fixes: 0bd50d719b00 ("pinctrl: cherryview: prevent concurrent access to GPIO controllers") Signed-off-by: Grace Kao Reported-by: Brian Norris Reviewed-by: Brian Norris Acked-by: Mika Westerberg Signed-off-by: Andy Shevchenko Signed-off-by: Sasha Levin --- drivers/pinctrl/intel/pinctrl-cherryview.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index e8c08eb97530..d1a99b2e2d4c 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -1509,11 +1509,15 @@ static void chv_gpio_irq_handler(struct irq_desc *desc) struct chv_pinctrl *pctrl = gpiochip_get_data(gc); struct irq_chip *chip = irq_desc_get_chip(desc); unsigned long pending; + unsigned long flags; u32 intr_line; chained_irq_enter(chip, desc); + raw_spin_lock_irqsave(&chv_lock, flags); pending = readl(pctrl->regs + CHV_INTSTAT); + raw_spin_unlock_irqrestore(&chv_lock, flags); + for_each_set_bit(intr_line, &pending, pctrl->community->nirqs) { unsigned irq, offset; From c449481dc9eb52f5aa338246b6204ed1d03a0c7e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 22 Apr 2020 12:22:11 +0300 Subject: [PATCH 057/387] i40iw: Fix error handling in i40iw_manage_arp_cache() [ Upstream commit 37e31d2d26a4124506c24e95434e9baf3405a23a ] The i40iw_arp_table() function can return -EOVERFLOW if i40iw_alloc_resource() fails so we can't just test for "== -1". Fixes: 4e9042e647ff ("i40iw: add hw and utils files") Link: https://lore.kernel.org/r/20200422092211.GA195357@mwanda Signed-off-by: Dan Carpenter Acked-by: Shiraz Saleem Signed-off-by: Jason Gunthorpe Signed-off-by: Sasha Levin --- drivers/infiniband/hw/i40iw/i40iw_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/i40iw/i40iw_hw.c b/drivers/infiniband/hw/i40iw/i40iw_hw.c index 0c92a40b3e86..e4867d6de789 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_hw.c +++ b/drivers/infiniband/hw/i40iw/i40iw_hw.c @@ -479,7 +479,7 @@ void i40iw_manage_arp_cache(struct i40iw_device *iwdev, int arp_index; arp_index = i40iw_arp_table(iwdev, ip_addr, ipv4, mac_addr, action); - if (arp_index == -1) + if (arp_index < 0) return; cqp_request = i40iw_get_cqp_request(&iwdev->cqp, false); if (!cqp_request) From 4bdea735b1b10b312a280d797f3290c9f8f247af Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 30 Apr 2020 23:30:48 +0200 Subject: [PATCH 058/387] netfilter: conntrack: avoid gcc-10 zero-length-bounds warning [ Upstream commit 2c407aca64977ede9b9f35158e919773cae2082f ] gcc-10 warns around a suspicious access to an empty struct member: net/netfilter/nf_conntrack_core.c: In function '__nf_conntrack_alloc': net/netfilter/nf_conntrack_core.c:1522:9: warning: array subscript 0 is outside the bounds of an interior zero-length array 'u8[0]' {aka 'unsigned char[0]'} [-Wzero-length-bounds] 1522 | memset(&ct->__nfct_init_offset[0], 0, | ^~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from net/netfilter/nf_conntrack_core.c:37: include/net/netfilter/nf_conntrack.h:90:5: note: while referencing '__nfct_init_offset' 90 | u8 __nfct_init_offset[0]; | ^~~~~~~~~~~~~~~~~~ The code is correct but a bit unusual. Rework it slightly in a way that does not trigger the warning, using an empty struct instead of an empty array. There are probably more elegant ways to do this, but this is the smallest change. Fixes: c41884ce0562 ("netfilter: conntrack: avoid zeroing timer") Signed-off-by: Arnd Bergmann Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin --- include/net/netfilter/nf_conntrack.h | 2 +- net/netfilter/nf_conntrack_core.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h index b57a9f37c297..7befec513295 100644 --- a/include/net/netfilter/nf_conntrack.h +++ b/include/net/netfilter/nf_conntrack.h @@ -103,7 +103,7 @@ struct nf_conn { struct hlist_node nat_bysource; #endif /* all members below initialized via memset */ - u8 __nfct_init_offset[0]; + struct { } __nfct_init_offset; /* If we were expected by an expectation, this will be it */ struct nf_conn *master; diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 1bdae8f188e1..d507d0fc7858 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -1124,9 +1124,9 @@ __nf_conntrack_alloc(struct net *net, *(unsigned long *)(&ct->tuplehash[IP_CT_DIR_REPLY].hnnode.pprev) = hash; ct->status = 0; write_pnet(&ct->ct_net, net); - memset(&ct->__nfct_init_offset[0], 0, + memset(&ct->__nfct_init_offset, 0, offsetof(struct nf_conn, proto) - - offsetof(struct nf_conn, __nfct_init_offset[0])); + offsetof(struct nf_conn, __nfct_init_offset)); nf_ct_zone_add(ct, zone); From f1273b63716574e8b60ed51931c905542bebf813 Mon Sep 17 00:00:00 2001 From: Jack Morgenstein Date: Sun, 26 Apr 2020 10:59:21 +0300 Subject: [PATCH 059/387] IB/mlx4: Test return value of calls to ib_get_cached_pkey [ Upstream commit 6693ca95bd4330a0ad7326967e1f9bcedd6b0800 ] In the mlx4_ib_post_send() flow, some functions call ib_get_cached_pkey() without checking its return value. If ib_get_cached_pkey() returns an error code, these functions should return failure. Fixes: 1ffeb2eb8be9 ("IB/mlx4: SR-IOV IB context objects and proxy/tunnel SQP support") Fixes: 225c7b1feef1 ("IB/mlx4: Add a driver Mellanox ConnectX InfiniBand adapters") Fixes: e622f2f4ad21 ("IB: split struct ib_send_wr") Link: https://lore.kernel.org/r/20200426075921.130074-1-leon@kernel.org Signed-off-by: Jack Morgenstein Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe Signed-off-by: Sasha Levin --- drivers/infiniband/hw/mlx4/qp.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 709d6491d243..7284a9176844 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -2307,6 +2307,7 @@ static int build_sriov_qp0_header(struct mlx4_ib_sqp *sqp, int send_size; int header_size; int spc; + int err; int i; if (wr->wr.opcode != IB_WR_SEND) @@ -2341,7 +2342,9 @@ static int build_sriov_qp0_header(struct mlx4_ib_sqp *sqp, sqp->ud_header.lrh.virtual_lane = 0; sqp->ud_header.bth.solicited_event = !!(wr->wr.send_flags & IB_SEND_SOLICITED); - ib_get_cached_pkey(ib_dev, sqp->qp.port, 0, &pkey); + err = ib_get_cached_pkey(ib_dev, sqp->qp.port, 0, &pkey); + if (err) + return err; sqp->ud_header.bth.pkey = cpu_to_be16(pkey); if (sqp->qp.mlx4_ib_qp_type == MLX4_IB_QPT_TUN_SMI_OWNER) sqp->ud_header.bth.destination_qpn = cpu_to_be32(wr->remote_qpn); @@ -2618,9 +2621,14 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_ud_wr *wr, } sqp->ud_header.bth.solicited_event = !!(wr->wr.send_flags & IB_SEND_SOLICITED); if (!sqp->qp.ibqp.qp_num) - ib_get_cached_pkey(ib_dev, sqp->qp.port, sqp->pkey_index, &pkey); + err = ib_get_cached_pkey(ib_dev, sqp->qp.port, sqp->pkey_index, + &pkey); else - ib_get_cached_pkey(ib_dev, sqp->qp.port, wr->pkey_index, &pkey); + err = ib_get_cached_pkey(ib_dev, sqp->qp.port, wr->pkey_index, + &pkey); + if (err) + return err; + sqp->ud_header.bth.pkey = cpu_to_be16(pkey); sqp->ud_header.bth.destination_qpn = cpu_to_be32(wr->remote_qpn); sqp->ud_header.bth.psn = cpu_to_be32((sqp->send_psn++) & ((1 << 24) - 1)); From 19427360c49376620da3d9147ea5daff444c32a8 Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Tue, 14 Apr 2020 12:10:50 -0300 Subject: [PATCH 060/387] pnp: Use list_for_each_entry() instead of open coding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 01b2bafe57b19d9119413f138765ef57990921ce upstream. Aside from good practice, this avoids a warning from gcc 10: ./include/linux/kernel.h:997:3: warning: array subscript -31 is outside array bounds of ‘struct list_head[1]’ [-Warray-bounds] 997 | ((type *)(__mptr - offsetof(type, member))); }) | ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ./include/linux/list.h:493:2: note: in expansion of macro ‘container_of’ 493 | container_of(ptr, type, member) | ^~~~~~~~~~~~ ./include/linux/pnp.h:275:30: note: in expansion of macro ‘list_entry’ 275 | #define global_to_pnp_dev(n) list_entry(n, struct pnp_dev, global_list) | ^~~~~~~~~~ ./include/linux/pnp.h:281:11: note: in expansion of macro ‘global_to_pnp_dev’ 281 | (dev) != global_to_pnp_dev(&pnp_global); \ | ^~~~~~~~~~~~~~~~~ arch/x86/kernel/rtc.c:189:2: note: in expansion of macro ‘pnp_for_each_dev’ 189 | pnp_for_each_dev(dev) { Because the common code doesn't cast the starting list_head to the containing struct. Signed-off-by: Jason Gunthorpe [ rjw: Whitespace adjustments ] Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- include/linux/pnp.h | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/include/linux/pnp.h b/include/linux/pnp.h index 2588ca6a9028..acbfe53eb948 100644 --- a/include/linux/pnp.h +++ b/include/linux/pnp.h @@ -219,10 +219,8 @@ struct pnp_card { #define global_to_pnp_card(n) list_entry(n, struct pnp_card, global_list) #define protocol_to_pnp_card(n) list_entry(n, struct pnp_card, protocol_list) #define to_pnp_card(n) container_of(n, struct pnp_card, dev) -#define pnp_for_each_card(card) \ - for((card) = global_to_pnp_card(pnp_cards.next); \ - (card) != global_to_pnp_card(&pnp_cards); \ - (card) = global_to_pnp_card((card)->global_list.next)) +#define pnp_for_each_card(card) \ + list_for_each_entry(card, &pnp_cards, global_list) struct pnp_card_link { struct pnp_card *card; @@ -275,14 +273,9 @@ struct pnp_dev { #define card_to_pnp_dev(n) list_entry(n, struct pnp_dev, card_list) #define protocol_to_pnp_dev(n) list_entry(n, struct pnp_dev, protocol_list) #define to_pnp_dev(n) container_of(n, struct pnp_dev, dev) -#define pnp_for_each_dev(dev) \ - for((dev) = global_to_pnp_dev(pnp_global.next); \ - (dev) != global_to_pnp_dev(&pnp_global); \ - (dev) = global_to_pnp_dev((dev)->global_list.next)) -#define card_for_each_dev(card,dev) \ - for((dev) = card_to_pnp_dev((card)->devices.next); \ - (dev) != card_to_pnp_dev(&(card)->devices); \ - (dev) = card_to_pnp_dev((dev)->card_list.next)) +#define pnp_for_each_dev(dev) list_for_each_entry(dev, &pnp_global, global_list) +#define card_for_each_dev(card, dev) \ + list_for_each_entry(dev, &(card)->devices, card_list) #define pnp_dev_name(dev) (dev)->name static inline void *pnp_get_drvdata(struct pnp_dev *pdev) @@ -436,14 +429,10 @@ struct pnp_protocol { }; #define to_pnp_protocol(n) list_entry(n, struct pnp_protocol, protocol_list) -#define protocol_for_each_card(protocol,card) \ - for((card) = protocol_to_pnp_card((protocol)->cards.next); \ - (card) != protocol_to_pnp_card(&(protocol)->cards); \ - (card) = protocol_to_pnp_card((card)->protocol_list.next)) -#define protocol_for_each_dev(protocol,dev) \ - for((dev) = protocol_to_pnp_dev((protocol)->devices.next); \ - (dev) != protocol_to_pnp_dev(&(protocol)->devices); \ - (dev) = protocol_to_pnp_dev((dev)->protocol_list.next)) +#define protocol_for_each_card(protocol, card) \ + list_for_each_entry(card, &(protocol)->cards, protocol_list) +#define protocol_for_each_dev(protocol, dev) \ + list_for_each_entry(dev, &(protocol)->devices, protocol_list) extern struct bus_type pnp_bus_type; From 5ba9126d709e5e7921413b7177ce3ecc98185670 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 4 May 2020 09:16:37 -0700 Subject: [PATCH 061/387] gcc-10 warnings: fix low-hanging fruit commit 9d82973e032e246ff5663c9805fbb5407ae932e3 upstream. Due to a bug-report that was compiler-dependent, I updated one of my machines to gcc-10. That shows a lot of new warnings. Happily they seem to be mostly the valid kind, but it's going to cause a round of churn for getting rid of them.. This is the really low-hanging fruit of removing a couple of zero-sized arrays in some core code. We have had a round of these patches before, and we'll have many more coming, and there is nothing special about these except that they were particularly trivial, and triggered more warnings than most. Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- include/linux/fs.h | 2 +- include/linux/tty.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/fs.h b/include/linux/fs.h index c2c04f891785..2d569738eb32 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -931,7 +931,7 @@ struct file_handle { __u32 handle_bytes; int handle_type; /* file identifier */ - unsigned char f_handle[0]; + unsigned char f_handle[]; }; static inline struct file *get_file(struct file *f) diff --git a/include/linux/tty.h b/include/linux/tty.h index fe483976b119..15cf871046b3 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -64,7 +64,7 @@ struct tty_buffer { int read; int flags; /* Data points here */ - unsigned long data[0]; + unsigned long data[]; }; /* Values for .flags field of tty_buffer */ From c0138cf0fda7cb2a7bd4285e51749423ff06edd0 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 21 Feb 2019 13:13:38 +0900 Subject: [PATCH 062/387] kbuild: compute false-positive -Wmaybe-uninitialized cases in Kconfig commit b303c6df80c9f8f13785aa83a0471fca7e38b24d upstream. Since -Wmaybe-uninitialized was introduced by GCC 4.7, we have patched various false positives: - commit e74fc973b6e5 ("Turn off -Wmaybe-uninitialized when building with -Os") turned off this option for -Os. - commit 815eb71e7149 ("Kbuild: disable 'maybe-uninitialized' warning for CONFIG_PROFILE_ALL_BRANCHES") turned off this option for CONFIG_PROFILE_ALL_BRANCHES - commit a76bcf557ef4 ("Kbuild: enable -Wmaybe-uninitialized warning for "make W=1"") turned off this option for GCC < 4.9 Arnd provided more explanation in https://lkml.org/lkml/2017/3/14/903 I think this looks better by shifting the logic from Makefile to Kconfig. Link: https://github.com/ClangBuiltLinux/linux/issues/350 Signed-off-by: Masahiro Yamada Reviewed-by: Nathan Chancellor Tested-by: Nick Desaulniers Signed-off-by: Greg Kroah-Hartman --- Makefile | 11 ++++------- init/Kconfig | 17 +++++++++++++++++ kernel/trace/Kconfig | 1 + 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 2a923301987e..36b03a49ccc0 100644 --- a/Makefile +++ b/Makefile @@ -658,17 +658,14 @@ KBUILD_CFLAGS += $(call cc-option,-fdata-sections,) endif ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE -KBUILD_CFLAGS += -Os $(call cc-disable-warning,maybe-uninitialized,) -else -ifdef CONFIG_PROFILE_ALL_BRANCHES -KBUILD_CFLAGS += -O2 $(call cc-disable-warning,maybe-uninitialized,) +KBUILD_CFLAGS += -Os else KBUILD_CFLAGS += -O2 endif -endif -KBUILD_CFLAGS += $(call cc-ifversion, -lt, 0409, \ - $(call cc-disable-warning,maybe-uninitialized,)) +ifdef CONFIG_CC_DISABLE_WARN_MAYBE_UNINITIALIZED +KBUILD_CFLAGS += -Wno-maybe-uninitialized +endif # Tell gcc to never replace conditional load with a non-conditional one KBUILD_CFLAGS += $(call cc-option,--param=allow-store-data-races=0) diff --git a/init/Kconfig b/init/Kconfig index b331feeabda4..63fb2da49163 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -16,6 +16,22 @@ config DEFCONFIG_LIST default "$ARCH_DEFCONFIG" default "arch/$ARCH/defconfig" +config CC_HAS_WARN_MAYBE_UNINITIALIZED + def_bool $(cc-option,-Wmaybe-uninitialized) + help + GCC >= 4.7 supports this option. + +config CC_DISABLE_WARN_MAYBE_UNINITIALIZED + bool + depends on CC_HAS_WARN_MAYBE_UNINITIALIZED + default CC_IS_GCC && GCC_VERSION < 40900 # unreliable for GCC < 4.9 + help + GCC's -Wmaybe-uninitialized is not reliable by definition. + Lots of false positive warnings are produced in some cases. + + If this option is enabled, -Wno-maybe-uninitialzed is passed + to the compiler to suppress maybe-uninitialized warnings. + config CONSTRUCTORS bool depends on !UML @@ -1333,6 +1349,7 @@ config CC_OPTIMIZE_FOR_PERFORMANCE config CC_OPTIMIZE_FOR_SIZE bool "Optimize for size" + imply CC_DISABLE_WARN_MAYBE_UNINITIALIZED # avoid false positives help Enabling this option will pass "-Os" instead of "-O2" to your compiler resulting in a smaller kernel. diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 2a96b063d659..6254fa608cab 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -342,6 +342,7 @@ config PROFILE_ANNOTATED_BRANCHES config PROFILE_ALL_BRANCHES bool "Profile all if conditionals" select TRACE_BRANCH_PROFILING + imply CC_DISABLE_WARN_MAYBE_UNINITIALIZED # avoid false positives help This tracer profiles all branch conditions. Every if () taken in the kernel is recorded whether it hit or miss. From ce9f411be7f9639fb109528c3e661a0a4a867090 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 9 May 2020 13:57:10 -0700 Subject: [PATCH 063/387] Stop the ad-hoc games with -Wno-maybe-initialized commit 78a5255ffb6a1af189a83e493d916ba1c54d8c75 upstream. We have some rather random rules about when we accept the "maybe-initialized" warnings, and when we don't. For example, we consider it unreliable for gcc versions < 4.9, but also if -O3 is enabled, or if optimizing for size. And then various kernel config options disabled it, because they know that they trigger that warning by confusing gcc sufficiently (ie PROFILE_ALL_BRANCHES). And now gcc-10 seems to be introducing a lot of those warnings too, so it falls under the same heading as 4.9 did. At the same time, we have a very straightforward way to _enable_ that warning when wanted: use "W=2" to enable more warnings. So stop playing these ad-hoc games, and just disable that warning by default, with the known and straight-forward "if you want to work on the extra compiler warnings, use W=123". Would it be great to have code that is always so obvious that it never confuses the compiler whether a variable is used initialized or not? Yes, it would. In a perfect world, the compilers would be smarter, and our source code would be simpler. That's currently not the world we live in, though. Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- Makefile | 7 +++---- init/Kconfig | 17 ----------------- kernel/trace/Kconfig | 1 - 3 files changed, 3 insertions(+), 22 deletions(-) diff --git a/Makefile b/Makefile index 36b03a49ccc0..9fc96b0b0b70 100644 --- a/Makefile +++ b/Makefile @@ -663,10 +663,6 @@ else KBUILD_CFLAGS += -O2 endif -ifdef CONFIG_CC_DISABLE_WARN_MAYBE_UNINITIALIZED -KBUILD_CFLAGS += -Wno-maybe-uninitialized -endif - # Tell gcc to never replace conditional load with a non-conditional one KBUILD_CFLAGS += $(call cc-option,--param=allow-store-data-races=0) @@ -801,6 +797,9 @@ KBUILD_CFLAGS += $(call cc-disable-warning, pointer-sign) # disable stringop warnings in gcc 8+ KBUILD_CFLAGS += $(call cc-disable-warning, stringop-truncation) +# Enabled with W=2, disabled by default as noisy +KBUILD_CFLAGS += $(call cc-disable-warning, maybe-uninitialized) + # disable invalid "can't wrap" optimizations for signed / pointers KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow) diff --git a/init/Kconfig b/init/Kconfig index 63fb2da49163..b331feeabda4 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -16,22 +16,6 @@ config DEFCONFIG_LIST default "$ARCH_DEFCONFIG" default "arch/$ARCH/defconfig" -config CC_HAS_WARN_MAYBE_UNINITIALIZED - def_bool $(cc-option,-Wmaybe-uninitialized) - help - GCC >= 4.7 supports this option. - -config CC_DISABLE_WARN_MAYBE_UNINITIALIZED - bool - depends on CC_HAS_WARN_MAYBE_UNINITIALIZED - default CC_IS_GCC && GCC_VERSION < 40900 # unreliable for GCC < 4.9 - help - GCC's -Wmaybe-uninitialized is not reliable by definition. - Lots of false positive warnings are produced in some cases. - - If this option is enabled, -Wno-maybe-uninitialzed is passed - to the compiler to suppress maybe-uninitialized warnings. - config CONSTRUCTORS bool depends on !UML @@ -1349,7 +1333,6 @@ config CC_OPTIMIZE_FOR_PERFORMANCE config CC_OPTIMIZE_FOR_SIZE bool "Optimize for size" - imply CC_DISABLE_WARN_MAYBE_UNINITIALIZED # avoid false positives help Enabling this option will pass "-Os" instead of "-O2" to your compiler resulting in a smaller kernel. diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 6254fa608cab..2a96b063d659 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -342,7 +342,6 @@ config PROFILE_ANNOTATED_BRANCHES config PROFILE_ALL_BRANCHES bool "Profile all if conditionals" select TRACE_BRANCH_PROFILING - imply CC_DISABLE_WARN_MAYBE_UNINITIALIZED # avoid false positives help This tracer profiles all branch conditions. Every if () taken in the kernel is recorded whether it hit or miss. From 0101213f67193e4bebf92336d3f149bee0dc7fa7 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 2 Mar 2018 15:08:38 -0800 Subject: [PATCH 064/387] net: phy: micrel: Use strlcpy() for ethtool::get_strings commit 55f53567afe5f0cd2fd9e006b174c08c31c466f8 upstream. Our statistics strings are allocated at initialization without being bound to a specific size, yet, we would copy ETH_GSTRING_LEN bytes using memcpy() which would create out of bounds accesses, this was flagged by KASAN. Replace this with strlcpy() to make sure we are bound the source buffer size and we also always NUL-terminate strings. Fixes: 2b2427d06426 ("phy: micrel: Add ethtool statistics counters") Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/phy/micrel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index adb38a4ec9ac..1704d9e2ca8d 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -677,8 +677,8 @@ static void kszphy_get_strings(struct phy_device *phydev, u8 *data) int i; for (i = 0; i < ARRAY_SIZE(kszphy_hw_stats); i++) { - memcpy(data + i * ETH_GSTRING_LEN, - kszphy_hw_stats[i].string, ETH_GSTRING_LEN); + strlcpy(data + i * ETH_GSTRING_LEN, + kszphy_hw_stats[i].string, ETH_GSTRING_LEN); } } From 414eae103d3ed66e18d929d4fac4dd3ddda4c2bd Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 9 May 2020 15:58:04 -0700 Subject: [PATCH 065/387] gcc-10: avoid shadowing standard library 'free()' in crypto MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 1a263ae60b04de959d9ce9caea4889385eefcc7b upstream. gcc-10 has started warning about conflicting types for a few new built-in functions, particularly 'free()'. This results in warnings like: crypto/xts.c:325:13: warning: conflicting types for built-in function ‘free’; expected ‘void(void *)’ [-Wbuiltin-declaration-mismatch] because the crypto layer had its local freeing functions called 'free()'. Gcc-10 is in the wrong here, since that function is marked 'static', and thus there is no chance of confusion with any standard library function namespace. But the simplest thing to do is to just use a different name here, and avoid this gcc mis-feature. [ Side note: gcc knowing about 'free()' is in itself not the mis-feature: the semantics of 'free()' are special enough that a compiler can validly do special things when seeing it. So the mis-feature here is that gcc thinks that 'free()' is some restricted name, and you can't shadow it as a local static function. Making the special 'free()' semantics be a function attribute rather than tied to the name would be the much better model ] Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- crypto/lrw.c | 4 ++-- crypto/xts.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crypto/lrw.c b/crypto/lrw.c index d38a382b09eb..fc3d4fec8ddd 100644 --- a/crypto/lrw.c +++ b/crypto/lrw.c @@ -377,7 +377,7 @@ out_put_alg: return inst; } -static void free(struct crypto_instance *inst) +static void free_inst(struct crypto_instance *inst) { crypto_drop_spawn(crypto_instance_ctx(inst)); kfree(inst); @@ -386,7 +386,7 @@ static void free(struct crypto_instance *inst) static struct crypto_template crypto_tmpl = { .name = "lrw", .alloc = alloc, - .free = free, + .free = free_inst, .module = THIS_MODULE, }; diff --git a/crypto/xts.c b/crypto/xts.c index 305343f22a02..e41ed483e8a5 100644 --- a/crypto/xts.c +++ b/crypto/xts.c @@ -329,7 +329,7 @@ out_put_alg: return inst; } -static void free(struct crypto_instance *inst) +static void free_inst(struct crypto_instance *inst) { crypto_drop_spawn(crypto_instance_ctx(inst)); kfree(inst); @@ -338,7 +338,7 @@ static void free(struct crypto_instance *inst) static struct crypto_template crypto_tmpl = { .name = "xts", .alloc = alloc, - .free = free, + .free = free_inst, .module = THIS_MODULE, }; From 207ad349e2321c5317a07e96492e0867737e160e Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 9 May 2020 14:30:29 -0700 Subject: [PATCH 066/387] gcc-10: disable 'zero-length-bounds' warning for now commit 5c45de21a2223fe46cf9488c99a7fbcf01527670 upstream. This is a fine warning, but we still have a number of zero-length arrays in the kernel that come from the traditional gcc extension. Yes, they are getting converted to flexible arrays, but in the meantime the gcc-10 warning about zero-length bounds is very verbose, and is hiding other issues. I missed one actual build failure because it was hidden among hundreds of lines of warning. Thankfully I caught it on the second go before pushing things out, but it convinced me that I really need to disable the new warnings for now. We'll hopefully be all done with our conversion to flexible arrays in the not too distant future, and we can then re-enable this warning. Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 9fc96b0b0b70..1dfded1a980e 100644 --- a/Makefile +++ b/Makefile @@ -797,6 +797,9 @@ KBUILD_CFLAGS += $(call cc-disable-warning, pointer-sign) # disable stringop warnings in gcc 8+ KBUILD_CFLAGS += $(call cc-disable-warning, stringop-truncation) +# We'll want to enable this eventually, but it's not going away for 5.7 at least +KBUILD_CFLAGS += $(call cc-disable-warning, zero-length-bounds) + # Enabled with W=2, disabled by default as noisy KBUILD_CFLAGS += $(call cc-disable-warning, maybe-uninitialized) From 55e8e4b87b7ba5d52586128048d3b625319a5b41 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 9 May 2020 14:52:44 -0700 Subject: [PATCH 067/387] gcc-10: disable 'array-bounds' warning for now commit 44720996e2d79e47d508b0abe99b931a726a3197 upstream. This is another fine warning, related to the 'zero-length-bounds' one, but hitting the same historical code in the kernel. Because C didn't historically support flexible array members, we have code that instead uses a one-sized array, the same way we have cases of zero-sized arrays. The one-sized arrays come from either not wanting to use the gcc zero-sized array extension, or from a slight convenience-feature, where particularly for strings, the size of the structure now includes the allocation for the final NUL character. So with a "char name[1];" at the end of a structure, you can do things like v = my_malloc(sizeof(struct vendor) + strlen(name)); and avoid the "+1" for the terminator. Yes, the modern way to do that is with a flexible array, and using 'offsetof()' instead of 'sizeof()', and adding the "+1" by hand. That also technically gets the size "more correct" in that it avoids any alignment (and thus padding) issues, but this is another long-term cleanup thing that will not happen for 5.7. So disable the warning for now, even though it's potentially quite useful. Having a slew of warnings that then hide more urgent new issues is not an improvement. Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 1dfded1a980e..a1c08c9c5326 100644 --- a/Makefile +++ b/Makefile @@ -799,6 +799,7 @@ KBUILD_CFLAGS += $(call cc-disable-warning, stringop-truncation) # We'll want to enable this eventually, but it's not going away for 5.7 at least KBUILD_CFLAGS += $(call cc-disable-warning, zero-length-bounds) +KBUILD_CFLAGS += $(call cc-disable-warning, array-bounds) # Enabled with W=2, disabled by default as noisy KBUILD_CFLAGS += $(call cc-disable-warning, maybe-uninitialized) From 01d51bb3125103be4d0991d3a7e3f7feb36bf3c2 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 9 May 2020 15:40:52 -0700 Subject: [PATCH 068/387] gcc-10: disable 'stringop-overflow' warning for now commit 5a76021c2eff7fcf2f0918a08fd8a37ce7922921 upstream. This is the final array bounds warning removal for gcc-10 for now. Again, the warning is good, and we should re-enable all these warnings when we have converted all the legacy array declaration cases to flexible arrays. But in the meantime, it's just noise. Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index a1c08c9c5326..be47f0ec8235 100644 --- a/Makefile +++ b/Makefile @@ -800,6 +800,7 @@ KBUILD_CFLAGS += $(call cc-disable-warning, stringop-truncation) # We'll want to enable this eventually, but it's not going away for 5.7 at least KBUILD_CFLAGS += $(call cc-disable-warning, zero-length-bounds) KBUILD_CFLAGS += $(call cc-disable-warning, array-bounds) +KBUILD_CFLAGS += $(call cc-disable-warning, stringop-overflow) # Enabled with W=2, disabled by default as noisy KBUILD_CFLAGS += $(call cc-disable-warning, maybe-uninitialized) From 9799d957182c8681943a3734a66e123f62a3a2f8 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 9 May 2020 15:45:21 -0700 Subject: [PATCH 069/387] gcc-10: disable 'restrict' warning for now commit adc71920969870dfa54e8f40dac8616284832d02 upstream. gcc-10 now warns about passing aliasing pointers to functions that take restricted pointers. That's actually a great warning, and if we ever start using 'restrict' in the kernel, it might be quite useful. But right now we don't, and it turns out that the only thing this warns about is an idiom where we have declared a few functions to be "printf-like" (which seems to make gcc pick up the restricted pointer thing), and then we print to the same buffer that we also use as an input. And people do that as an odd concatenation pattern, with code like this: #define sysfs_show_gen_prop(buffer, fmt, ...) \ snprintf(buffer, PAGE_SIZE, "%s"fmt, buffer, __VA_ARGS__) where we have 'buffer' as both the destination of the final result, and as the initial argument. Yes, it's a bit questionable. And outside of the kernel, people do have standard declarations like int snprintf( char *restrict buffer, size_t bufsz, const char *restrict format, ... ); where that output buffer is marked as a restrict pointer that cannot alias with any other arguments. But in the context of the kernel, that 'use snprintf() to concatenate to the end result' does work, and the pattern shows up in multiple places. And we have not marked our own version of snprintf() as taking restrict pointers, so the warning is incorrect for now, and gcc picks it up on its own. If we do start using 'restrict' in the kernel (and it might be a good idea if people find places where it matters), we'll need to figure out how to avoid this issue for snprintf and friends. But in the meantime, this warning is not useful. Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index be47f0ec8235..4901317d22a0 100644 --- a/Makefile +++ b/Makefile @@ -802,6 +802,9 @@ KBUILD_CFLAGS += $(call cc-disable-warning, zero-length-bounds) KBUILD_CFLAGS += $(call cc-disable-warning, array-bounds) KBUILD_CFLAGS += $(call cc-disable-warning, stringop-overflow) +# Another good warning that we'll want to enable eventually +KBUILD_CFLAGS += $(call cc-disable-warning, restrict) + # Enabled with W=2, disabled by default as noisy KBUILD_CFLAGS += $(call cc-disable-warning, maybe-uninitialized) From 74af5e3ecf14b11c822870d9235d51d383401f9e Mon Sep 17 00:00:00 2001 From: Cong Wang Date: Thu, 7 May 2020 12:19:03 -0700 Subject: [PATCH 070/387] net: fix a potential recursive NETDEV_FEAT_CHANGE [ Upstream commit dd912306ff008891c82cd9f63e8181e47a9cb2fb ] syzbot managed to trigger a recursive NETDEV_FEAT_CHANGE event between bonding master and slave. I managed to find a reproducer for this: ip li set bond0 up ifenslave bond0 eth0 brctl addbr br0 ethtool -K eth0 lro off brctl addif br0 bond0 ip li set br0 up When a NETDEV_FEAT_CHANGE event is triggered on a bonding slave, it captures this and calls bond_compute_features() to fixup its master's and other slaves' features. However, when syncing with its lower devices by netdev_sync_lower_features() this event is triggered again on slaves when the LRO feature fails to change, so it goes back and forth recursively until the kernel stack is exhausted. Commit 17b85d29e82c intentionally lets __netdev_update_features() return -1 for such a failure case, so we have to just rely on the existing check inside netdev_sync_lower_features() and skip NETDEV_FEAT_CHANGE event only for this specific failure case. Fixes: fd867d51f889 ("net/core: generic support for disabling netdev features down stack") Reported-by: syzbot+e73ceacfd8560cc8a3ca@syzkaller.appspotmail.com Reported-by: syzbot+c2fb6f9ddcea95ba49b5@syzkaller.appspotmail.com Cc: Jarod Wilson Cc: Nikolay Aleksandrov Cc: Josh Poimboeuf Cc: Jann Horn Reviewed-by: Jay Vosburgh Signed-off-by: Cong Wang Acked-by: Nikolay Aleksandrov Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/core/dev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/core/dev.c b/net/core/dev.c index 842654302110..1041523aaa76 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -6939,11 +6939,13 @@ static void netdev_sync_lower_features(struct net_device *upper, netdev_dbg(upper, "Disabling feature %pNF on lower dev %s.\n", &feature, lower->name); lower->wanted_features &= ~feature; - netdev_update_features(lower); + __netdev_update_features(lower); if (unlikely(lower->features & feature)) netdev_WARN(upper, "failed to disable %pNF on %s!\n", &feature, lower->name); + else + netdev_features_change(lower); } } } From 9232577ef3e10775eefe7f2689cbf851c8b13d80 Mon Sep 17 00:00:00 2001 From: Paolo Abeni Date: Tue, 12 May 2020 14:43:14 +0200 Subject: [PATCH 071/387] netlabel: cope with NULL catmap [ Upstream commit eead1c2ea2509fd754c6da893a94f0e69e83ebe4 ] The cipso and calipso code can set the MLS_CAT attribute on successful parsing, even if the corresponding catmap has not been allocated, as per current configuration and external input. Later, selinux code tries to access the catmap if the MLS_CAT flag is present via netlbl_catmap_getlong(). That may cause null ptr dereference while processing incoming network traffic. Address the issue setting the MLS_CAT flag only if the catmap is really allocated. Additionally let netlbl_catmap_getlong() cope with NULL catmap. Reported-by: Matthew Sheets Fixes: 4b8feff251da ("netlabel: fix the horribly broken catmap functions") Fixes: ceba1832b1b2 ("calipso: Set the calipso socket label to match the secattr.") Signed-off-by: Paolo Abeni Acked-by: Paul Moore Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/ipv4/cipso_ipv4.c | 6 ++++-- net/ipv6/calipso.c | 3 ++- net/netlabel/netlabel_kapi.c | 6 ++++++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index 0a6f72763beb..71409928763b 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c @@ -1272,7 +1272,8 @@ static int cipso_v4_parsetag_rbm(const struct cipso_v4_doi *doi_def, return ret_val; } - secattr->flags |= NETLBL_SECATTR_MLS_CAT; + if (secattr->attr.mls.cat) + secattr->flags |= NETLBL_SECATTR_MLS_CAT; } return 0; @@ -1453,7 +1454,8 @@ static int cipso_v4_parsetag_rng(const struct cipso_v4_doi *doi_def, return ret_val; } - secattr->flags |= NETLBL_SECATTR_MLS_CAT; + if (secattr->attr.mls.cat) + secattr->flags |= NETLBL_SECATTR_MLS_CAT; } return 0; diff --git a/net/ipv6/calipso.c b/net/ipv6/calipso.c index 9742abf5ac26..b206415bbde7 100644 --- a/net/ipv6/calipso.c +++ b/net/ipv6/calipso.c @@ -1061,7 +1061,8 @@ static int calipso_opt_getattr(const unsigned char *calipso, goto getattr_return; } - secattr->flags |= NETLBL_SECATTR_MLS_CAT; + if (secattr->attr.mls.cat) + secattr->flags |= NETLBL_SECATTR_MLS_CAT; } secattr->type = NETLBL_NLTYPE_CALIPSO; diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c index cb9d1d1210cb..d0cfdff04993 100644 --- a/net/netlabel/netlabel_kapi.c +++ b/net/netlabel/netlabel_kapi.c @@ -748,6 +748,12 @@ int netlbl_catmap_getlong(struct netlbl_lsm_catmap *catmap, if ((off & (BITS_PER_LONG - 1)) != 0) return -EINVAL; + /* a null catmap is equivalent to an empty one */ + if (!catmap) { + *offset = (u32)-1; + return 0; + } + if (off < catmap->startbit) { off = catmap->startbit; *offset = off; From bac931d9325b2b224a533e671676784301988198 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= Date: Tue, 5 May 2020 11:57:23 -0700 Subject: [PATCH 072/387] Revert "ipv6: add mtu lock check in __ip6_rt_update_pmtu" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 09454fd0a4ce23cb3d8af65066c91a1bf27120dd ] This reverts commit 19bda36c4299ce3d7e5bce10bebe01764a655a6d: | ipv6: add mtu lock check in __ip6_rt_update_pmtu | | Prior to this patch, ipv6 didn't do mtu lock check in ip6_update_pmtu. | It leaded to that mtu lock doesn't really work when receiving the pkt | of ICMPV6_PKT_TOOBIG. | | This patch is to add mtu lock check in __ip6_rt_update_pmtu just as ipv4 | did in __ip_rt_update_pmtu. The above reasoning is incorrect. IPv6 *requires* icmp based pmtu to work. There's already a comment to this effect elsewhere in the kernel: $ git grep -p -B1 -A3 'RTAX_MTU lock' net/ipv6/route.c=4813= static int rt6_mtu_change_route(struct fib6_info *f6i, void *p_arg) ... /* In IPv6 pmtu discovery is not optional, so that RTAX_MTU lock cannot disable it. We still use this lock to block changes caused by addrconf/ndisc. */ This reverts to the pre-4.9 behaviour. Cc: Eric Dumazet Cc: Willem de Bruijn Cc: Xin Long Cc: Hannes Frederic Sowa Signed-off-by: Maciej Żenczykowski Fixes: 19bda36c4299 ("ipv6: add mtu lock check in __ip6_rt_update_pmtu") Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/ipv6/route.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 2c4743f2d50e..03d1a61b4729 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1373,8 +1373,10 @@ static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk, { struct rt6_info *rt6 = (struct rt6_info *)dst; - if (dst_metric_locked(dst, RTAX_MTU)) - return; + /* Note: do *NOT* check dst_metric_locked(dst, RTAX_MTU) + * IPv6 pmtu discovery isn't optional, so 'mtu lock' cannot disable it. + * [see also comment in rt6_mtu_change_route()] + */ dst_confirm(dst); mtu = max_t(u32, mtu, IPV6_MIN_MTU); From be38a13c9e4666cde185718cd32a6e9e83323112 Mon Sep 17 00:00:00 2001 From: Paolo Abeni Date: Fri, 8 May 2020 19:28:34 +0200 Subject: [PATCH 073/387] net: ipv4: really enforce backoff for redirects [ Upstream commit 57644431a6c2faac5d754ebd35780cf43a531b1a ] In commit b406472b5ad7 ("net: ipv4: avoid mixed n_redirects and rate_tokens usage") I missed the fact that a 0 'rate_tokens' will bypass the backoff algorithm. Since rate_tokens is cleared after a redirect silence, and never incremented on redirects, if the host keeps receiving packets requiring redirect it will reply ignoring the backoff. Additionally, the 'rate_last' field will be updated with the cadence of the ingress packet requiring redirect. If that rate is high enough, that will prevent the host from generating any other kind of ICMP messages The check for a zero 'rate_tokens' value was likely a shortcut to avoid the more complex backoff algorithm after a redirect silence period. Address the issue checking for 'n_redirects' instead, which is incremented on successful redirect, and does not interfere with other ICMP replies. Fixes: b406472b5ad7 ("net: ipv4: avoid mixed n_redirects and rate_tokens usage") Reported-and-tested-by: Colin Walters Signed-off-by: Paolo Abeni Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/ipv4/route.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index b4f24eabfa54..81efd2d3998d 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -898,7 +898,7 @@ void ip_rt_send_redirect(struct sk_buff *skb) /* Check for load limit; set rate_last to the latest sent * redirect. */ - if (peer->rate_tokens == 0 || + if (peer->n_redirects == 0 || time_after(jiffies, (peer->rate_last + (ip_rt_redirect_load << peer->n_redirects)))) { From d1d65ba019d21cdbf3e2b83a0a7e0e8512a4b526 Mon Sep 17 00:00:00 2001 From: Zefan Li Date: Sat, 9 May 2020 11:32:10 +0800 Subject: [PATCH 074/387] netprio_cgroup: Fix unlimited memory leak of v2 cgroups [ Upstream commit 090e28b229af92dc5b40786ca673999d59e73056 ] If systemd is configured to use hybrid mode which enables the use of both cgroup v1 and v2, systemd will create new cgroup on both the default root (v2) and netprio_cgroup hierarchy (v1) for a new session and attach task to the two cgroups. If the task does some network thing then the v2 cgroup can never be freed after the session exited. One of our machines ran into OOM due to this memory leak. In the scenario described above when sk_alloc() is called cgroup_sk_alloc() thought it's in v2 mode, so it stores the cgroup pointer in sk->sk_cgrp_data and increments the cgroup refcnt, but then sock_update_netprioidx() thought it's in v1 mode, so it stores netprioidx value in sk->sk_cgrp_data, so the cgroup refcnt will never be freed. Currently we do the mode switch when someone writes to the ifpriomap cgroup control file. The easiest fix is to also do the switch when a task is attached to a new cgroup. Fixes: bd1060a1d671 ("sock, cgroup: add sock->sk_cgroup") Reported-by: Yang Yingliang Tested-by: Yang Yingliang Signed-off-by: Zefan Li Acked-by: Tejun Heo Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/core/netprio_cgroup.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c index 2ec86fc552df..22506194bd76 100644 --- a/net/core/netprio_cgroup.c +++ b/net/core/netprio_cgroup.c @@ -237,6 +237,8 @@ static void net_prio_attach(struct cgroup_taskset *tset) struct task_struct *p; struct cgroup_subsys_state *css; + cgroup_sk_alloc_disable(); + cgroup_taskset_for_each(p, css, tset) { void *v = (void *)(unsigned long)css->cgroup->id; From 9568ef017c0b88c705f7d585b7f30d56f3f0ed87 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 14 May 2020 18:05:33 +0200 Subject: [PATCH 075/387] ALSA: hda/realtek - Limit int mic boost for Thinkpad T530 commit b590b38ca305d6d7902ec7c4f7e273e0069f3bcc upstream. Lenovo Thinkpad T530 seems to have a sensitive internal mic capture that needs to limit the mic boost like a few other Thinkpad models. Although we may change the quirk for ALC269_FIXUP_LENOVO_DOCK, this hits way too many other laptop models, so let's add a new fixup model that limits the internal mic boost on top of the existing quirk and apply to only T530. BugLink: https://bugzilla.suse.com/show_bug.cgi?id=1171293 Cc: Link: https://lore.kernel.org/r/20200514160533.10337-1-tiwai@suse.de Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/pci/hda/patch_realtek.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 000b59d474ab..412f52aaf454 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4890,6 +4890,7 @@ enum { ALC269_FIXUP_HP_LINE1_MIC1_LED, ALC269_FIXUP_INV_DMIC, ALC269_FIXUP_LENOVO_DOCK, + ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST, ALC269_FIXUP_NO_SHUTUP, ALC286_FIXUP_SONY_MIC_NO_PRESENCE, ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT, @@ -5157,6 +5158,12 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT }, + [ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc269_fixup_limit_int_mic_boost, + .chained = true, + .chain_id = ALC269_FIXUP_LENOVO_DOCK, + }, [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = { .type = HDA_FIXUP_FUNC, .v.func = alc269_fixup_pincfg_no_hp_to_lineout, @@ -5820,7 +5827,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), - SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK), + SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST), SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK), SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK), SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK), @@ -5945,6 +5952,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = { {.id = ALC269_FIXUP_HEADSET_MODE, .name = "headset-mode"}, {.id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, .name = "headset-mode-no-hp-mic"}, {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"}, + {.id = ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST, .name = "lenovo-dock-limit-boost"}, {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"}, {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic1-led"}, {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, From 135c2b1c05d027ea20d9ecf359f8d7534569ffc1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 3 Sep 2018 15:16:43 +0200 Subject: [PATCH 076/387] ALSA: rawmidi: Initialize allocated buffers commit 5a7b44a8df822e0667fc76ed7130252523993bda upstream. syzbot reported the uninitialized value exposure in certain situations using virmidi loop. It's likely a very small race at writing and reading, and the influence is almost negligible. But it's safer to paper over this just by replacing the existing kvmalloc() with kvzalloc(). Reported-by: syzbot+194dffdb8b22fc5d207a@syzkaller.appspotmail.com Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/core/rawmidi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index c8b2309352d7..358b6efbd6aa 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -125,7 +125,7 @@ static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream) runtime->avail = 0; else runtime->avail = runtime->buffer_size; - if ((runtime->buffer = kmalloc(runtime->buffer_size, GFP_KERNEL)) == NULL) { + if ((runtime->buffer = kzalloc(runtime->buffer_size, GFP_KERNEL)) == NULL) { kfree(runtime); return -ENOMEM; } @@ -650,7 +650,7 @@ int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream, return -EINVAL; } if (params->buffer_size != runtime->buffer_size) { - newbuf = kmalloc(params->buffer_size, GFP_KERNEL); + newbuf = kzalloc(params->buffer_size, GFP_KERNEL); if (!newbuf) return -ENOMEM; spin_lock_irq(&runtime->lock); From c13f1463d84b86bedb664e509838bef37e6ea317 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 7 May 2020 13:44:56 +0200 Subject: [PATCH 077/387] ALSA: rawmidi: Fix racy buffer resize under concurrent accesses commit c1f6e3c818dd734c30f6a7eeebf232ba2cf3181d upstream. The rawmidi core allows user to resize the runtime buffer via ioctl, and this may lead to UAF when performed during concurrent reads or writes: the read/write functions unlock the runtime lock temporarily during copying form/to user-space, and that's the race window. This patch fixes the hole by introducing a reference counter for the runtime buffer read/write access and returns -EBUSY error when the resize is performed concurrently against read/write. Note that the ref count field is a simple integer instead of refcount_t here, since the all contexts accessing the buffer is basically protected with a spinlock, hence we need no expensive atomic ops. Also, note that this busy check is needed only against read / write functions, and not in receive/transmit callbacks; the race can happen only at the spinlock hole mentioned in the above, while the whole function is protected for receive / transmit callbacks. Reported-by: butt3rflyh4ck Cc: Link: https://lore.kernel.org/r/CAFcO6XMWpUVK_yzzCpp8_XP7+=oUpQvuBeCbMffEDkpe8jWrfg@mail.gmail.com Link: https://lore.kernel.org/r/s5heerw3r5z.wl-tiwai@suse.de Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- include/sound/rawmidi.h | 1 + sound/core/rawmidi.c | 31 +++++++++++++++++++++++++++---- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/include/sound/rawmidi.h b/include/sound/rawmidi.h index 5432111c8761..2a87128b3075 100644 --- a/include/sound/rawmidi.h +++ b/include/sound/rawmidi.h @@ -76,6 +76,7 @@ struct snd_rawmidi_runtime { size_t avail_min; /* min avail for wakeup */ size_t avail; /* max used buffer for wakeup */ size_t xruns; /* over/underruns counter */ + int buffer_ref; /* buffer reference count */ /* misc */ spinlock_t lock; wait_queue_head_t sleep; diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index 358b6efbd6aa..481c1ad1db57 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -108,6 +108,17 @@ static void snd_rawmidi_input_event_work(struct work_struct *work) runtime->event(runtime->substream); } +/* buffer refcount management: call with runtime->lock held */ +static inline void snd_rawmidi_buffer_ref(struct snd_rawmidi_runtime *runtime) +{ + runtime->buffer_ref++; +} + +static inline void snd_rawmidi_buffer_unref(struct snd_rawmidi_runtime *runtime) +{ + runtime->buffer_ref--; +} + static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream) { struct snd_rawmidi_runtime *runtime; @@ -654,6 +665,11 @@ int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream, if (!newbuf) return -ENOMEM; spin_lock_irq(&runtime->lock); + if (runtime->buffer_ref) { + spin_unlock_irq(&runtime->lock); + kfree(newbuf); + return -EBUSY; + } oldbuf = runtime->buffer; runtime->buffer = newbuf; runtime->buffer_size = params->buffer_size; @@ -962,8 +978,10 @@ static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream, long result = 0, count1; struct snd_rawmidi_runtime *runtime = substream->runtime; unsigned long appl_ptr; + int err = 0; spin_lock_irqsave(&runtime->lock, flags); + snd_rawmidi_buffer_ref(runtime); while (count > 0 && runtime->avail) { count1 = runtime->buffer_size - runtime->appl_ptr; if (count1 > count) @@ -982,16 +1000,19 @@ static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream, if (userbuf) { spin_unlock_irqrestore(&runtime->lock, flags); if (copy_to_user(userbuf + result, - runtime->buffer + appl_ptr, count1)) { - return result > 0 ? result : -EFAULT; - } + runtime->buffer + appl_ptr, count1)) + err = -EFAULT; spin_lock_irqsave(&runtime->lock, flags); + if (err) + goto out; } result += count1; count -= count1; } + out: + snd_rawmidi_buffer_unref(runtime); spin_unlock_irqrestore(&runtime->lock, flags); - return result; + return result > 0 ? result : err; } long snd_rawmidi_kernel_read(struct snd_rawmidi_substream *substream, @@ -1262,6 +1283,7 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, return -EAGAIN; } } + snd_rawmidi_buffer_ref(runtime); while (count > 0 && runtime->avail > 0) { count1 = runtime->buffer_size - runtime->appl_ptr; if (count1 > count) @@ -1293,6 +1315,7 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, } __end: count1 = runtime->avail < runtime->buffer_size; + snd_rawmidi_buffer_unref(runtime); spin_unlock_irqrestore(&runtime->lock, flags); if (count1) snd_rawmidi_output_trigger(substream, 1); From 482a6f13fe708a2beed6e35a6ba1b45c62ddbd8f Mon Sep 17 00:00:00 2001 From: Jesus Ramos Date: Mon, 27 Apr 2020 06:21:39 -0700 Subject: [PATCH 078/387] ALSA: usb-audio: Add control message quirk delay for Kingston HyperX headset commit 073919e09ca445d4486968e3f851372ff44cf2b5 upstream. Kingston HyperX headset with 0951:16ad also needs the same quirk for delaying the frequency controls. Signed-off-by: Jesus Ramos Cc: Link: https://lore.kernel.org/r/BY5PR19MB3634BA68C7CCA23D8DF428E796AF0@BY5PR19MB3634.namprd19.prod.outlook.com Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/usb/quirks.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 064f3485a977..0484a8d8a5bb 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1316,13 +1316,14 @@ void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe, && (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) mdelay(20); - /* Zoom R16/24, Logitech H650e, Jabra 550a needs a tiny delay here, - * otherwise requests like get/set frequency return as failed despite - * actually succeeding. + /* Zoom R16/24, Logitech H650e, Jabra 550a, Kingston HyperX needs a tiny + * delay here, otherwise requests like get/set frequency return as + * failed despite actually succeeding. */ if ((chip->usb_id == USB_ID(0x1686, 0x00dd) || chip->usb_id == USB_ID(0x046d, 0x0a46) || - chip->usb_id == USB_ID(0x0b0e, 0x0349)) && + chip->usb_id == USB_ID(0x0b0e, 0x0349) || + chip->usb_id == USB_ID(0x0951, 0x16ad)) && (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) mdelay(1); } From 2056c78ee8abacaf71c89c999483183203e8441d Mon Sep 17 00:00:00 2001 From: Kyungtae Kim Date: Sun, 10 May 2020 05:43:34 +0000 Subject: [PATCH 079/387] USB: gadget: fix illegal array access in binding with UDC commit 15753588bcd4bbffae1cca33c8ced5722477fe1f upstream. FuzzUSB (a variant of syzkaller) found an illegal array access using an incorrect index while binding a gadget with UDC. Reference: https://www.spinics.net/lists/linux-usb/msg194331.html This bug occurs when a size variable used for a buffer is misused to access its strcpy-ed buffer. Given a buffer along with its size variable (taken from user input), from which, a new buffer is created using kstrdup(). Due to the original buffer containing 0 value in the middle, the size of the kstrdup-ed buffer becomes smaller than that of the original. So accessing the kstrdup-ed buffer with the same size variable triggers memory access violation. The fix makes sure no zero value in the buffer, by comparing the strlen() of the orignal buffer with the size variable, so that the access to the kstrdup-ed buffer is safe. BUG: KASAN: slab-out-of-bounds in gadget_dev_desc_UDC_store+0x1ba/0x200 drivers/usb/gadget/configfs.c:266 Read of size 1 at addr ffff88806a55dd7e by task syz-executor.0/17208 CPU: 2 PID: 17208 Comm: syz-executor.0 Not tainted 5.6.8 #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0xce/0x128 lib/dump_stack.c:118 print_address_description.constprop.4+0x21/0x3c0 mm/kasan/report.c:374 __kasan_report+0x131/0x1b0 mm/kasan/report.c:506 kasan_report+0x12/0x20 mm/kasan/common.c:641 __asan_report_load1_noabort+0x14/0x20 mm/kasan/generic_report.c:132 gadget_dev_desc_UDC_store+0x1ba/0x200 drivers/usb/gadget/configfs.c:266 flush_write_buffer fs/configfs/file.c:251 [inline] configfs_write_file+0x2f1/0x4c0 fs/configfs/file.c:283 __vfs_write+0x85/0x110 fs/read_write.c:494 vfs_write+0x1cd/0x510 fs/read_write.c:558 ksys_write+0x18a/0x220 fs/read_write.c:611 __do_sys_write fs/read_write.c:623 [inline] __se_sys_write fs/read_write.c:620 [inline] __x64_sys_write+0x73/0xb0 fs/read_write.c:620 do_syscall_64+0x9e/0x510 arch/x86/entry/common.c:294 entry_SYSCALL_64_after_hwframe+0x49/0xbe Signed-off-by: Kyungtae Kim Reported-and-tested-by: Kyungtae Kim Cc: Felipe Balbi Cc: stable Link: https://lore.kernel.org/r/20200510054326.GA19198@pizza01 Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/configfs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 3f1662b64bab..6420cae820bc 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -259,6 +259,9 @@ static ssize_t gadget_dev_desc_UDC_store(struct config_item *item, char *name; int ret; + if (strlen(page) < len) + return -EOVERFLOW; + name = kstrdup(page, GFP_KERNEL); if (!name) return -ENOMEM; From 5b92711aec195b0ca6f35170ee5d15a38c4d1e92 Mon Sep 17 00:00:00 2001 From: Sriharsha Allenki Date: Thu, 14 May 2020 14:04:31 +0300 Subject: [PATCH 080/387] usb: xhci: Fix NULL pointer dereference when enqueuing trbs from urb sg list commit 3c6f8cb92c9178fc0c66b580ea3df1fa3ac1155a upstream. On platforms with IOMMU enabled, multiple SGs can be coalesced into one by the IOMMU driver. In that case the SG list processing as part of the completion of a urb on a bulk endpoint can result into a NULL pointer dereference with the below stack dump. <6> Unable to handle kernel NULL pointer dereference at virtual address 0000000c <6> pgd = c0004000 <6> [0000000c] *pgd=00000000 <6> Internal error: Oops: 5 [#1] PREEMPT SMP ARM <2> PC is at xhci_queue_bulk_tx+0x454/0x80c <2> LR is at xhci_queue_bulk_tx+0x44c/0x80c <2> pc : [] lr : [] psr: 000000d3 <2> sp : ca337c80 ip : 00000000 fp : ffffffff <2> r10: 00000000 r9 : 50037000 r8 : 00004000 <2> r7 : 00000000 r6 : 00004000 r5 : 00000000 r4 : 00000000 <2> r3 : 00000000 r2 : 00000082 r1 : c2c1a200 r0 : 00000000 <2> Flags: nzcv IRQs off FIQs off Mode SVC_32 ISA ARM Segment none <2> Control: 10c0383d Table: b412c06a DAC: 00000051 <6> Process usb-storage (pid: 5961, stack limit = 0xca336210) <2> [] (xhci_queue_bulk_tx) <2> [] (xhci_urb_enqueue) <2> [] (usb_hcd_submit_urb) <2> [] (usb_sg_wait) <2> [] (usb_stor_bulk_transfer_sglist) <2> [] (usb_stor_bulk_srb) <2> [] (usb_stor_Bulk_transport) <2> [] (usb_stor_invoke_transport) <2> [] (usb_stor_control_thread) <2> [] (kthread) The above NULL pointer dereference is the result of block_len and the sent_len set to zero after the first SG of the list when IOMMU driver is enabled. Because of this the loop of processing the SGs has run more than num_sgs which resulted in a sg_next on the last SG of the list which has SG_END set. Fix this by check for the sg before any attributes of the sg are accessed. [modified reason for null pointer dereference in commit message subject -Mathias] Fixes: f9c589e142d04 ("xhci: TD-fragment, align the unsplittable case with a bounce buffer") Cc: stable@vger.kernel.org Signed-off-by: Sriharsha Allenki Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20200514110432.25564-2-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index b426c83ecb9b..1468dca77fac 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -3347,8 +3347,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, /* New sg entry */ --num_sgs; sent_len -= block_len; - if (num_sgs != 0) { - sg = sg_next(sg); + sg = sg_next(sg); + if (num_sgs != 0 && sg) { block_len = sg_dma_len(sg); addr = (u64) sg_dma_address(sg); addr += sent_len; From 115719aca84fd8f2bc51015cd994073615875f0d Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 27 Mar 2020 10:36:24 -0300 Subject: [PATCH 081/387] ARM: dts: imx27-phytec-phycard-s-rdk: Fix the I2C1 pinctrl entries commit 0caf34350a25907515d929a9c77b9b206aac6d1e upstream. The I2C2 pins are already used and the following errors are seen: imx27-pinctrl 10015000.iomuxc: pin MX27_PAD_I2C2_SDA already requested by 10012000.i2c; cannot claim for 1001d000.i2c imx27-pinctrl 10015000.iomuxc: pin-69 (1001d000.i2c) status -22 imx27-pinctrl 10015000.iomuxc: could not request pin 69 (MX27_PAD_I2C2_SDA) from group i2c2grp on device 10015000.iomuxc imx-i2c 1001d000.i2c: Error applying setting, reverse things back imx-i2c: probe of 1001d000.i2c failed with error -22 Fix it by adding the correct I2C1 IOMUX entries for the pinctrl_i2c1 group. Cc: Fixes: 61664d0b432a ("ARM: dts: imx27 phyCARD-S pinctrl") Signed-off-by: Fabio Estevam Reviewed-by: Stefan Riedmueller Signed-off-by: Shawn Guo Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts b/arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts index bfd4946cf9fe..8b63b6593d3a 100644 --- a/arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts +++ b/arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts @@ -81,8 +81,8 @@ imx27-phycard-s-rdk { pinctrl_i2c1: i2c1grp { fsl,pins = < - MX27_PAD_I2C2_SDA__I2C2_SDA 0x0 - MX27_PAD_I2C2_SCL__I2C2_SCL 0x0 + MX27_PAD_I2C_DATA__I2C_DATA 0x0 + MX27_PAD_I2C_CLK__I2C_CLK 0x0 >; }; From b263060dba4096b74bf5dbf796c535aa85fb73c6 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 22 Apr 2020 18:11:30 +0200 Subject: [PATCH 082/387] x86: Fix early boot crash on gcc-10, third try MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit a9a3ed1eff3601b63aea4fb462d8b3b92c7c1e7e upstream. ... or the odyssey of trying to disable the stack protector for the function which generates the stack canary value. The whole story started with Sergei reporting a boot crash with a kernel built with gcc-10: Kernel panic — not syncing: stack-protector: Kernel stack is corrupted in: start_secondary CPU: 1 PID: 0 Comm: swapper/1 Not tainted 5.6.0-rc5—00235—gfffb08b37df9 #139 Hardware name: Gigabyte Technology Co., Ltd. To be filled by O.E.M./H77M—D3H, BIOS F12 11/14/2013 Call Trace: dump_stack panic ? start_secondary __stack_chk_fail start_secondary secondary_startup_64 -—-[ end Kernel panic — not syncing: stack—protector: Kernel stack is corrupted in: start_secondary This happens because gcc-10 tail-call optimizes the last function call in start_secondary() - cpu_startup_entry() - and thus emits a stack canary check which fails because the canary value changes after the boot_init_stack_canary() call. To fix that, the initial attempt was to mark the one function which generates the stack canary with: __attribute__((optimize("-fno-stack-protector"))) ... start_secondary(void *unused) however, using the optimize attribute doesn't work cumulatively as the attribute does not add to but rather replaces previously supplied optimization options - roughly all -fxxx options. The key one among them being -fno-omit-frame-pointer and thus leading to not present frame pointer - frame pointer which the kernel needs. The next attempt to prevent compilers from tail-call optimizing the last function call cpu_startup_entry(), shy of carving out start_secondary() into a separate compilation unit and building it with -fno-stack-protector, was to add an empty asm(""). This current solution was short and sweet, and reportedly, is supported by both compilers but we didn't get very far this time: future (LTO?) optimization passes could potentially eliminate this, which leads us to the third attempt: having an actual memory barrier there which the compiler cannot ignore or move around etc. That should hold for a long time, but hey we said that about the other two solutions too so... Reported-by: Sergei Trofimovich Signed-off-by: Borislav Petkov Tested-by: Kalle Valo Cc: Link: https://lkml.kernel.org/r/20200314164451.346497-1-slyfox@gentoo.org Signed-off-by: Greg Kroah-Hartman --- arch/x86/include/asm/stackprotector.h | 7 ++++++- arch/x86/kernel/smpboot.c | 8 ++++++++ arch/x86/xen/smp.c | 1 + include/linux/compiler.h | 7 +++++++ init/main.c | 2 ++ 5 files changed, 24 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h index 58505f01962f..743bd2d77e51 100644 --- a/arch/x86/include/asm/stackprotector.h +++ b/arch/x86/include/asm/stackprotector.h @@ -54,8 +54,13 @@ /* * Initialize the stackprotector canary value. * - * NOTE: this must only be called from functions that never return, + * NOTE: this must only be called from functions that never return * and it must always be inlined. + * + * In addition, it should be called from a compilation unit for which + * stack protector is disabled. Alternatively, the caller should not end + * with a function call which gets tail-call optimized as that would + * lead to checking a modified canary value. */ static __always_inline void boot_init_stack_canary(void) { diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index ef38bc1d1c00..fe5896259c0f 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -249,6 +249,14 @@ static void notrace start_secondary(void *unused) wmb(); cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); + + /* + * Prevent tail call to cpu_startup_entry() because the stack protector + * guard has been changed a couple of function calls up, in + * boot_init_stack_canary() and must not be checked before tail calling + * another function. + */ + prevent_tail_call_optimization(); } /** diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 8eca26ef6471..15a90ab3b373 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -116,6 +116,7 @@ asmlinkage __visible void cpu_bringup_and_idle(int cpu) #endif cpu_bringup(); cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); + prevent_tail_call_optimization(); } void xen_smp_intr_free(unsigned int cpu) diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 7837afabbd78..824b1b97f989 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -605,4 +605,11 @@ unsigned long read_word_at_a_time(const void *addr) # define __kprobes # define nokprobe_inline inline #endif + +/* + * This is needed in functions which generate the stack canary, see + * arch/x86/kernel/smpboot.c::start_secondary() for an example. + */ +#define prevent_tail_call_optimization() mb() + #endif /* __LINUX_COMPILER_H */ diff --git a/init/main.c b/init/main.c index 148843e627a0..d47860dbe896 100644 --- a/init/main.c +++ b/init/main.c @@ -662,6 +662,8 @@ asmlinkage __visible void __init start_kernel(void) /* Do the rest non-__init'ed, we're now alive */ rest_init(); + + prevent_tail_call_optimization(); } /* Call all constructor functions linked into the kernel. */ From 72d5fb7f67de5d8a2e5f12a98e66b10209aa4a65 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sat, 16 May 2020 16:29:20 -0500 Subject: [PATCH 083/387] exec: Move would_dump into flush_old_exec commit f87d1c9559164294040e58f5e3b74a162bf7c6e8 upstream. I goofed when I added mm->user_ns support to would_dump. I missed the fact that in the case of binfmt_loader, binfmt_em86, binfmt_misc, and binfmt_script bprm->file is reassigned. Which made the move of would_dump from setup_new_exec to __do_execve_file before exec_binprm incorrect as it can result in would_dump running on the script instead of the interpreter of the script. The net result is that the code stopped making unreadable interpreters undumpable. Which allows them to be ptraced and written to disk without special permissions. Oops. The move was necessary because the call in set_new_exec was after bprm->mm was no longer valid. To correct this mistake move the misplaced would_dump from __do_execve_file into flos_old_exec, before exec_mmap is called. I tested and confirmed that without this fix I can attach with gdb to a script with an unreadable interpreter, and with this fix I can not. Cc: stable@vger.kernel.org Fixes: f84df2a6f268 ("exec: Ensure mm->user_ns contains the execed files") Signed-off-by: "Eric W. Biederman" Signed-off-by: Greg Kroah-Hartman --- fs/exec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/exec.c b/fs/exec.c index bb03b98fd03b..cd5da140f94c 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1270,6 +1270,8 @@ int flush_old_exec(struct linux_binprm * bprm) */ set_mm_exe_file(bprm->mm, bprm->file); + would_dump(bprm, bprm->file); + /* * Release all of the old mmap stuff */ @@ -1780,8 +1782,6 @@ static int do_execveat_common(int fd, struct filename *filename, if (retval < 0) goto out; - would_dump(bprm, bprm->file); - retval = exec_binprm(bprm); if (retval < 0) goto out; From a1e63dd3d6ba30fadcb51169593da6566c9e8bfd Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Mon, 27 Apr 2020 20:04:23 +0200 Subject: [PATCH 084/387] usb: gadget: net2272: Fix a memory leak in an error handling path in 'net2272_plat_probe()' commit ccaef7e6e354fb65758eaddd3eae8065a8b3e295 upstream. 'dev' is allocated in 'net2272_probe_init()'. It must be freed in the error handling path, as already done in the remove function (i.e. 'net2272_plat_remove()') Fixes: 90fccb529d24 ("usb: gadget: Gadget directory cleanup - group UDC drivers") Signed-off-by: Christophe JAILLET Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/udc/net2272.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/gadget/udc/net2272.c b/drivers/usb/gadget/udc/net2272.c index f57d293a1791..4b6797797141 100644 --- a/drivers/usb/gadget/udc/net2272.c +++ b/drivers/usb/gadget/udc/net2272.c @@ -2666,6 +2666,8 @@ net2272_plat_probe(struct platform_device *pdev) err_req: release_mem_region(base, len); err: + kfree(dev); + return ret; } From 3fa699ebae128e7ac68e3202cb3195017ee8fc7c Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 3 May 2020 12:47:07 +0200 Subject: [PATCH 085/387] usb: gadget: audio: Fix a missing error return value in audio_bind() commit 19b94c1f9c9a16d41a8de3ccbdb8536cf1aecdbf upstream. If 'usb_otg_descriptor_alloc()' fails, we must return an error code, not 0. Fixes: 56023ce0fd70 ("usb: gadget: audio: allocate and init otg descriptor by otg capabilities") Reviewed-by: Peter Chen Signed-off-by: Christophe JAILLET Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/legacy/audio.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/legacy/audio.c b/drivers/usb/gadget/legacy/audio.c index 5d7b3c6a422b..f61936b8baaf 100644 --- a/drivers/usb/gadget/legacy/audio.c +++ b/drivers/usb/gadget/legacy/audio.c @@ -249,8 +249,10 @@ static int audio_bind(struct usb_composite_dev *cdev) struct usb_descriptor_header *usb_desc; usb_desc = usb_otg_descriptor_alloc(cdev->gadget); - if (!usb_desc) + if (!usb_desc) { + status = -ENOMEM; goto fail; + } usb_otg_descriptor_init(cdev->gadget, usb_desc); otg_desc[0] = usb_desc; otg_desc[1] = NULL; From 170cbe87348e0104f89eb0b26be9d3fe131bb0ef Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 7 May 2020 05:13:23 +0000 Subject: [PATCH 086/387] usb: gadget: legacy: fix error return code in gncm_bind() commit e27d4b30b71c66986196d8a1eb93cba9f602904a upstream. If 'usb_otg_descriptor_alloc()' fails, we must return a negative error code -ENOMEM, not 0. Fixes: 1156e91dd7cc ("usb: gadget: ncm: allocate and init otg descriptor by otg capabilities") Reported-by: Hulk Robot Signed-off-by: Wei Yongjun Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/legacy/ncm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/legacy/ncm.c b/drivers/usb/gadget/legacy/ncm.c index 2fb4a847dd52..5448cf4ff588 100644 --- a/drivers/usb/gadget/legacy/ncm.c +++ b/drivers/usb/gadget/legacy/ncm.c @@ -162,8 +162,10 @@ static int gncm_bind(struct usb_composite_dev *cdev) struct usb_descriptor_header *usb_desc; usb_desc = usb_otg_descriptor_alloc(gadget); - if (!usb_desc) + if (!usb_desc) { + status = -ENOMEM; goto fail; + } usb_otg_descriptor_init(gadget, usb_desc); otg_desc[0] = usb_desc; otg_desc[1] = NULL; From 25ac42422d887d0d937a6881325a53c63e989322 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 7 May 2020 05:13:32 +0000 Subject: [PATCH 087/387] usb: gadget: legacy: fix error return code in cdc_bind() commit e8f7f9e3499a6d96f7f63a4818dc7d0f45a7783b upstream. If 'usb_otg_descriptor_alloc()' fails, we must return a negative error code -ENOMEM, not 0. Fixes: ab6796ae9833 ("usb: gadget: cdc2: allocate and init otg descriptor by otg capabilities") Reported-by: Hulk Robot Signed-off-by: Wei Yongjun Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/legacy/cdc2.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/legacy/cdc2.c b/drivers/usb/gadget/legacy/cdc2.c index 5ee25beb52f0..dc83e07bb242 100644 --- a/drivers/usb/gadget/legacy/cdc2.c +++ b/drivers/usb/gadget/legacy/cdc2.c @@ -183,8 +183,10 @@ static int cdc_bind(struct usb_composite_dev *cdev) struct usb_descriptor_header *usb_desc; usb_desc = usb_otg_descriptor_alloc(gadget); - if (!usb_desc) + if (!usb_desc) { + status = -ENOMEM; goto fail1; + } usb_otg_descriptor_init(gadget, usb_desc); otg_desc[0] = usb_desc; otg_desc[1] = NULL; From 1c4be4e03f4ca119b1c7a14e622e462abea4c144 Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Sun, 3 May 2020 23:24:46 +0800 Subject: [PATCH 088/387] Revert "ALSA: hda/realtek: Fix pop noise on ALC225" commit f41224efcf8aafe80ea47ac870c5e32f3209ffc8 upstream. This reverts commit 3b36b13d5e69d6f51ff1c55d1b404a74646c9757. Enable power save node breaks some systems with ACL225. Revert the patch and use a platform specific quirk for the original issue isntead. Fixes: 3b36b13d5e69 ("ALSA: hda/realtek: Fix pop noise on ALC225") BugLink: https://bugs.launchpad.net/bugs/1875916 Signed-off-by: Kai-Heng Feng Link: https://lore.kernel.org/r/20200503152449.22761-1-kai.heng.feng@canonical.com Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/pci/hda/patch_realtek.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 412f52aaf454..df6d0211df51 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4212,8 +4212,6 @@ static void alc_determine_headset_type(struct hda_codec *codec) is_ctia = (val & 0x1c02) == 0x1c02; break; case 0x10ec0225: - codec->power_save_node = 1; - /* fall through */ case 0x10ec0295: case 0x10ec0299: alc_process_coef_fw(codec, coef0225); From 6e4d34ed1ab9f71367921ba8bb28904b4c17553f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 8 Apr 2020 11:09:26 +0200 Subject: [PATCH 089/387] ARM: dts: r8a73a4: Add missing CMT1 interrupts commit 0f739fdfe9e5ce668bd6d3210f310df282321837 upstream. The R-Mobile APE6 Compare Match Timer 1 generates 8 interrupts, one for each channel, but currently only 1 is described. Fix this by adding the missing interrupts. Fixes: f7b65230019b9dac ("ARM: shmobile: r8a73a4: Add CMT1 node") Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20200408090926.25201-1-geert+renesas@glider.be Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/dts/r8a73a4.dtsi | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/r8a73a4.dtsi b/arch/arm/boot/dts/r8a73a4.dtsi index ca8672778fe0..547032eebd67 100644 --- a/arch/arm/boot/dts/r8a73a4.dtsi +++ b/arch/arm/boot/dts/r8a73a4.dtsi @@ -135,7 +135,14 @@ cmt1: timer@e6130000 { compatible = "renesas,cmt-48-r8a73a4", "renesas,cmt-48-gen2"; reg = <0 0xe6130000 0 0x1004>; - interrupts = ; + interrupts = , + , + , + , + , + , + , + ; clocks = <&mstp3_clks R8A73A4_CLK_CMT1>; clock-names = "fck"; power-domains = <&pd_c5>; From 03ec8f87b0798493f5be8cf20faf6af1e69114e8 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 8 May 2020 11:59:18 +0200 Subject: [PATCH 090/387] ARM: dts: r8a7740: Add missing extal2 to CPG node commit e47cb97f153193d4b41ca8d48127da14513d54c7 upstream. The Clock Pulse Generator (CPG) device node lacks the extal2 clock. This may lead to a failure registering the "r" clock, or to a wrong parent for the "usb24s" clock, depending on MD_CK2 pin configuration and boot loader CPG_USBCKCR register configuration. This went unnoticed, as this does not affect the single upstream board configuration, which relies on the first clock input only. Fixes: d9ffd583bf345e2e ("ARM: shmobile: r8a7740: add SoC clocks to DTS") Signed-off-by: Geert Uytterhoeven Reviewed-by: Ulrich Hecht Link: https://lore.kernel.org/r/20200508095918.6061-1-geert+renesas@glider.be Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/dts/r8a7740.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi index 159e04eb1b9e..41244942f085 100644 --- a/arch/arm/boot/dts/r8a7740.dtsi +++ b/arch/arm/boot/dts/r8a7740.dtsi @@ -467,7 +467,7 @@ cpg_clocks: cpg_clocks@e6150000 { compatible = "renesas,r8a7740-cpg-clocks"; reg = <0xe6150000 0x10000>; - clocks = <&extal1_clk>, <&extalr_clk>; + clocks = <&extal1_clk>, <&extal2_clk>, <&extalr_clk>; #clock-cells = <1>; clock-output-names = "system", "pllc0", "pllc1", "pllc2", "r", From 238b045a01313649a7b9b81dc097bd5b1ac531b2 Mon Sep 17 00:00:00 2001 From: Jim Mattson Date: Mon, 11 May 2020 15:56:16 -0700 Subject: [PATCH 091/387] KVM: x86: Fix off-by-one error in kvm_vcpu_ioctl_x86_setup_mce commit c4e0e4ab4cf3ec2b3f0b628ead108d677644ebd9 upstream. Bank_num is a one-based count of banks, not a zero-based index. It overflows the allocated space only when strictly greater than KVM_MAX_MCE_BANKS. Fixes: a9e38c3e01ad ("KVM: x86: Catch potential overrun in MCE setup") Signed-off-by: Jue Wang Signed-off-by: Jim Mattson Reviewed-by: Peter Shier Message-Id: <20200511225616.19557-1-jmattson@google.com> Reviewed-by: Vitaly Kuznetsov Signed-off-by: Paolo Bonzini Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/x86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 314eb954bdee..0f66f7dd8938 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3128,7 +3128,7 @@ static int kvm_vcpu_ioctl_x86_setup_mce(struct kvm_vcpu *vcpu, unsigned bank_num = mcg_cap & 0xff, bank; r = -EINVAL; - if (!bank_num || bank_num >= KVM_MAX_MCE_BANKS) + if (!bank_num || bank_num > KVM_MAX_MCE_BANKS) goto out; if (mcg_cap & ~(kvm_mce_cap_supported | 0xff | 0xff0000)) goto out; From 3bead443ef3d8fd53c8e40c6888671da225494d9 Mon Sep 17 00:00:00 2001 From: Sergei Trofimovich Date: Tue, 17 Mar 2020 00:07:18 +0000 Subject: [PATCH 092/387] Makefile: disallow data races on gcc-10 as well commit b1112139a103b4b1101d0d2d72931f2d33d8c978 upstream. gcc-10 will rename --param=allow-store-data-races=0 to -fno-allow-store-data-races. The flag change happened at https://gcc.gnu.org/PR92046. Signed-off-by: Sergei Trofimovich Acked-by: Jiri Kosina Signed-off-by: Masahiro Yamada Cc: Thomas Backlund Signed-off-by: Greg Kroah-Hartman --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 4901317d22a0..8d48cf916f5c 100644 --- a/Makefile +++ b/Makefile @@ -665,6 +665,7 @@ endif # Tell gcc to never replace conditional load with a non-conditional one KBUILD_CFLAGS += $(call cc-option,--param=allow-store-data-races=0) +KBUILD_CFLAGS += $(call cc-option,-fno-allow-store-data-races) # check for 'asm goto' ifeq ($(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-goto.sh $(CC) $(KBUILD_CFLAGS)), y) From e4ebe4fae299b559e683eb31a2dc950507842bf7 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 20 May 2020 08:15:44 +0200 Subject: [PATCH 093/387] Linux 4.9.224 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8d48cf916f5c..3e58c142f92f 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 4 PATCHLEVEL = 9 -SUBLEVEL = 223 +SUBLEVEL = 224 EXTRAVERSION = NAME = Roaring Lionus From 0b3bc1fbff6f92674ed6e4007710fbd8eb58e182 Mon Sep 17 00:00:00 2001 From: Cao jin Date: Tue, 8 Nov 2016 15:06:20 +0800 Subject: [PATCH 094/387] igb: use igb_adapter->io_addr instead of e1000_hw->hw_addr commit 629823b872402451b42462414da08dddd0e2c93d upstream. When running as guest, under certain condition, it will oops as following. writel() in igb_configure_tx_ring() results in oops, because hw->hw_addr is NULL. While other register access won't oops kernel because they use wr32/rd32 which have a defense against NULL pointer. [ 141.225449] pcieport 0000:00:1c.0: AER: Multiple Uncorrected (Fatal) error received: id=0101 [ 141.225523] igb 0000:01:00.1: PCIe Bus Error: severity=Uncorrected (Fatal), type=Unaccessible, id=0101(Unregistered Agent ID) [ 141.299442] igb 0000:01:00.1: broadcast error_detected message [ 141.300539] igb 0000:01:00.0 enp1s0f0: PCIe link lost, device now detached [ 141.351019] igb 0000:01:00.1 enp1s0f1: PCIe link lost, device now detached [ 143.465904] pcieport 0000:00:1c.0: Root Port link has been reset [ 143.465994] igb 0000:01:00.1: broadcast slot_reset message [ 143.466039] igb 0000:01:00.0: enabling device (0000 -> 0002) [ 144.389078] igb 0000:01:00.1: enabling device (0000 -> 0002) [ 145.312078] igb 0000:01:00.1: broadcast resume message [ 145.322211] BUG: unable to handle kernel paging request at 0000000000003818 [ 145.361275] IP: [] igb_configure_tx_ring+0x14d/0x280 [igb] [ 145.400048] PGD 0 [ 145.438007] Oops: 0002 [#1] SMP A similar issue & solution could be found at: http://patchwork.ozlabs.org/patch/689592/ Signed-off-by: Cao jin Acked-by: Alexander Duyck Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher Cc: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/intel/igb/igb_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 7e35bd665630..90eab0521be1 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -3395,7 +3395,7 @@ void igb_configure_tx_ring(struct igb_adapter *adapter, tdba & 0x00000000ffffffffULL); wr32(E1000_TDBAH(reg_idx), tdba >> 32); - ring->tail = hw->hw_addr + E1000_TDT(reg_idx); + ring->tail = adapter->io_addr + E1000_TDT(reg_idx); wr32(E1000_TDH(reg_idx), 0); writel(0, ring->tail); @@ -3734,7 +3734,7 @@ void igb_configure_rx_ring(struct igb_adapter *adapter, ring->count * sizeof(union e1000_adv_rx_desc)); /* initialize head and tail */ - ring->tail = hw->hw_addr + E1000_RDT(reg_idx); + ring->tail = adapter->io_addr + E1000_RDT(reg_idx); wr32(E1000_RDH(reg_idx), 0); writel(0, ring->tail); From c4c5322aa67da57585f68fc2c04f8b6484914947 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Mon, 17 Oct 2016 12:16:08 +0200 Subject: [PATCH 095/387] padata: Remove unused but set variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 119a0798dc42ed4c4f96d39b8b676efcea73aec6 upstream. Remove the unused but set variable pinst in padata_parallel_worker to fix the following warning when building with 'W=1': kernel/padata.c: In function ‘padata_parallel_worker’: kernel/padata.c:68:26: warning: variable ‘pinst’ set but not used [-Wunused-but-set-variable] Also remove the now unused variable pd which is only used to set pinst. Signed-off-by: Tobias Klauser Acked-by: Steffen Klassert Signed-off-by: Herbert Xu Cc: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- kernel/padata.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/kernel/padata.c b/kernel/padata.c index 6939111b3cbe..408f58c4565a 100644 --- a/kernel/padata.c +++ b/kernel/padata.c @@ -66,15 +66,11 @@ static int padata_cpu_hash(struct parallel_data *pd) static void padata_parallel_worker(struct work_struct *parallel_work) { struct padata_parallel_queue *pqueue; - struct parallel_data *pd; - struct padata_instance *pinst; LIST_HEAD(local_list); local_bh_disable(); pqueue = container_of(parallel_work, struct padata_parallel_queue, work); - pd = pqueue->pd; - pinst = pd->pinst; spin_lock(&pqueue->parallel.lock); list_replace_init(&pqueue->parallel.list, &local_list); From 7174609f3a75b96c1ea8a99588218daded337a2d Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Wed, 12 Apr 2017 10:40:19 +0200 Subject: [PATCH 096/387] padata: get_next is never NULL commit 69b348449bda0f9588737539cfe135774c9939a7 upstream. Per Dan's static checker warning, the code that returns NULL was removed in 2010, so this patch updates the comments and fixes the code assumptions. Signed-off-by: Jason A. Donenfeld Reported-by: Dan Carpenter Acked-by: Steffen Klassert Signed-off-by: Herbert Xu Cc: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- kernel/padata.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/kernel/padata.c b/kernel/padata.c index 408f58c4565a..d36c6becc22f 100644 --- a/kernel/padata.c +++ b/kernel/padata.c @@ -156,8 +156,6 @@ EXPORT_SYMBOL(padata_do_parallel); * A pointer to the control struct of the next object that needs * serialization, if present in one of the percpu reorder queues. * - * NULL, if all percpu reorder queues are empty. - * * -EINPROGRESS, if the next object that needs serialization will * be parallel processed by another cpu and is not yet present in * the cpu's reorder queue. @@ -184,8 +182,6 @@ static struct padata_priv *padata_get_next(struct parallel_data *pd) cpu = padata_index_to_cpu(pd, next_index); next_queue = per_cpu_ptr(pd->pqueue, cpu); - padata = NULL; - reorder = &next_queue->reorder; spin_lock(&reorder->lock); @@ -237,12 +233,11 @@ static void padata_reorder(struct parallel_data *pd) padata = padata_get_next(pd); /* - * All reorder queues are empty, or the next object that needs - * serialization is parallel processed by another cpu and is - * still on it's way to the cpu's reorder queue, nothing to - * do for now. + * If the next object that needs serialization is parallel + * processed by another cpu and is still on it's way to the + * cpu's reorder queue, nothing to do for now. */ - if (!padata || PTR_ERR(padata) == -EINPROGRESS) + if (PTR_ERR(padata) == -EINPROGRESS) break; /* From 08257da7e755584852c972d35f3d3ac32b297685 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Fri, 8 Sep 2017 20:57:10 +0200 Subject: [PATCH 097/387] padata: ensure the reorder timer callback runs on the correct CPU commit cf5868c8a22dc2854b96e9569064bb92365549ca upstream. The reorder timer function runs on the CPU where the timer interrupt was handled which is not necessarily one of the CPUs of the 'pcpu' CPU mask set. Ensure the padata_reorder() callback runs on the correct CPU, which is one in the 'pcpu' CPU mask set and, preferrably, the next expected one. Do so by comparing the current CPU with the expected target CPU. If they match, call padata_reorder() right away. If they differ, schedule a work item on the target CPU that does the padata_reorder() call for us. Signed-off-by: Mathias Krause Signed-off-by: Herbert Xu Cc: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- include/linux/padata.h | 2 ++ kernel/padata.c | 43 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/include/linux/padata.h b/include/linux/padata.h index 0f9e567d5e15..50704b51230a 100644 --- a/include/linux/padata.h +++ b/include/linux/padata.h @@ -85,6 +85,7 @@ struct padata_serial_queue { * @swork: work struct for serialization. * @pd: Backpointer to the internal control structure. * @work: work struct for parallelization. + * @reorder_work: work struct for reordering. * @num_obj: Number of objects that are processed by this cpu. * @cpu_index: Index of the cpu. */ @@ -93,6 +94,7 @@ struct padata_parallel_queue { struct padata_list reorder; struct parallel_data *pd; struct work_struct work; + struct work_struct reorder_work; atomic_t num_obj; int cpu_index; }; diff --git a/kernel/padata.c b/kernel/padata.c index d36c6becc22f..666f984e1201 100644 --- a/kernel/padata.c +++ b/kernel/padata.c @@ -282,11 +282,51 @@ static void padata_reorder(struct parallel_data *pd) return; } +static void invoke_padata_reorder(struct work_struct *work) +{ + struct padata_parallel_queue *pqueue; + struct parallel_data *pd; + + local_bh_disable(); + pqueue = container_of(work, struct padata_parallel_queue, reorder_work); + pd = pqueue->pd; + padata_reorder(pd); + local_bh_enable(); +} + static void padata_reorder_timer(unsigned long arg) { struct parallel_data *pd = (struct parallel_data *)arg; + unsigned int weight; + int target_cpu, cpu; - padata_reorder(pd); + cpu = get_cpu(); + + /* We don't lock pd here to not interfere with parallel processing + * padata_reorder() calls on other CPUs. We just need any CPU out of + * the cpumask.pcpu set. It would be nice if it's the right one but + * it doesn't matter if we're off to the next one by using an outdated + * pd->processed value. + */ + weight = cpumask_weight(pd->cpumask.pcpu); + target_cpu = padata_index_to_cpu(pd, pd->processed % weight); + + /* ensure to call the reorder callback on the correct CPU */ + if (cpu != target_cpu) { + struct padata_parallel_queue *pqueue; + struct padata_instance *pinst; + + /* The timer function is serialized wrt itself -- no locking + * needed. + */ + pinst = pd->pinst; + pqueue = per_cpu_ptr(pd->pqueue, target_cpu); + queue_work_on(target_cpu, pinst->wq, &pqueue->reorder_work); + } else { + padata_reorder(pd); + } + + put_cpu(); } static void padata_serial_worker(struct work_struct *serial_work) @@ -413,6 +453,7 @@ static void padata_init_pqueues(struct parallel_data *pd) __padata_list_init(&pqueue->reorder); __padata_list_init(&pqueue->parallel); INIT_WORK(&pqueue->work, padata_parallel_worker); + INIT_WORK(&pqueue->reorder_work, invoke_padata_reorder); atomic_set(&pqueue->num_obj, 0); } } From 6953f88cd3e7ba0be11863604215a7e68d8e203d Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Fri, 8 Sep 2017 20:57:11 +0200 Subject: [PATCH 098/387] padata: ensure padata_do_serial() runs on the correct CPU commit 350ef88e7e922354f82a931897ad4a4ce6c686ff upstream. If the algorithm we're parallelizing is asynchronous we might change CPUs between padata_do_parallel() and padata_do_serial(). However, we don't expect this to happen as we need to enqueue the padata object into the per-cpu reorder queue we took it from, i.e. the same-cpu's parallel queue. Ensure we're not switching CPUs for a given padata object by tracking the CPU within the padata object. If the serial callback gets called on the wrong CPU, defer invoking padata_reorder() via a kernel worker on the CPU we're expected to run on. Signed-off-by: Mathias Krause Signed-off-by: Herbert Xu Cc: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- include/linux/padata.h | 2 ++ kernel/padata.c | 20 +++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/include/linux/padata.h b/include/linux/padata.h index 50704b51230a..86c885f90878 100644 --- a/include/linux/padata.h +++ b/include/linux/padata.h @@ -37,6 +37,7 @@ * @list: List entry, to attach to the padata lists. * @pd: Pointer to the internal control structure. * @cb_cpu: Callback cpu for serializatioon. + * @cpu: Cpu for parallelization. * @seq_nr: Sequence number of the parallelized data object. * @info: Used to pass information from the parallel to the serial function. * @parallel: Parallel execution function. @@ -46,6 +47,7 @@ struct padata_priv { struct list_head list; struct parallel_data *pd; int cb_cpu; + int cpu; int info; void (*parallel)(struct padata_priv *padata); void (*serial)(struct padata_priv *padata); diff --git a/kernel/padata.c b/kernel/padata.c index 666f984e1201..693536efccf9 100644 --- a/kernel/padata.c +++ b/kernel/padata.c @@ -133,6 +133,7 @@ int padata_do_parallel(struct padata_instance *pinst, padata->cb_cpu = cb_cpu; target_cpu = padata_cpu_hash(pd); + padata->cpu = target_cpu; queue = per_cpu_ptr(pd->pqueue, target_cpu); spin_lock(&queue->parallel.lock); @@ -376,10 +377,21 @@ void padata_do_serial(struct padata_priv *padata) int cpu; struct padata_parallel_queue *pqueue; struct parallel_data *pd; + int reorder_via_wq = 0; pd = padata->pd; cpu = get_cpu(); + + /* We need to run on the same CPU padata_do_parallel(.., padata, ..) + * was called on -- or, at least, enqueue the padata object into the + * correct per-cpu queue. + */ + if (cpu != padata->cpu) { + reorder_via_wq = 1; + cpu = padata->cpu; + } + pqueue = per_cpu_ptr(pd->pqueue, cpu); spin_lock(&pqueue->reorder.lock); @@ -396,7 +408,13 @@ void padata_do_serial(struct padata_priv *padata) put_cpu(); - padata_reorder(pd); + /* If we're running on the wrong CPU, call padata_reorder() via a + * kernel worker. + */ + if (reorder_via_wq) + queue_work_on(cpu, pd->pinst->wq, &pqueue->reorder_work); + else + padata_reorder(pd); } EXPORT_SYMBOL(padata_do_serial); From ab97e5a9fdda460e4ef43cae75139193a46b12eb Mon Sep 17 00:00:00 2001 From: Roberto Sassu Date: Mon, 27 Apr 2020 12:28:56 +0200 Subject: [PATCH 099/387] evm: Check also if *tfm is an error pointer in init_desc() [ Upstream commit 53de3b080d5eae31d0de219617155dcc34e7d698 ] This patch avoids a kernel panic due to accessing an error pointer set by crypto_alloc_shash(). It occurs especially when there are many files that require an unsupported algorithm, as it would increase the likelihood of the following race condition: Task A: *tfm = crypto_alloc_shash() <= error pointer Task B: if (*tfm == NULL) <= *tfm is not NULL, use it Task B: rc = crypto_shash_init(desc) <= panic Task A: *tfm = NULL This patch uses the IS_ERR_OR_NULL macro to determine whether or not a new crypto context must be created. Cc: stable@vger.kernel.org Fixes: d46eb3699502b ("evm: crypto hash replaced by shash") Co-developed-by: Krzysztof Struczynski Signed-off-by: Krzysztof Struczynski Signed-off-by: Roberto Sassu Signed-off-by: Mimi Zohar Signed-off-by: Sasha Levin --- security/integrity/evm/evm_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c index c783fefa558a..e034dc21421e 100644 --- a/security/integrity/evm/evm_crypto.c +++ b/security/integrity/evm/evm_crypto.c @@ -90,7 +90,7 @@ static struct shash_desc *init_desc(char type) algo = evm_hash; } - if (*tfm == NULL) { + if (IS_ERR_OR_NULL(*tfm)) { mutex_lock(&mutex); if (*tfm) goto out; From d8d4da8a96b0763eca94656940c0ccdff1a1f39f Mon Sep 17 00:00:00 2001 From: Roberto Sassu Date: Mon, 27 Apr 2020 12:31:28 +0200 Subject: [PATCH 100/387] ima: Fix return value of ima_write_policy() [ Upstream commit 2e3a34e9f409ebe83d1af7cd2f49fca7af97dfac ] This patch fixes the return value of ima_write_policy() when a new policy is directly passed to IMA and the current policy requires appraisal of the file containing the policy. Currently, if appraisal is not in ENFORCE mode, ima_write_policy() returns 0 and leads user space applications to an endless loop. Fix this issue by denying the operation regardless of the appraisal mode. Cc: stable@vger.kernel.org # 4.10.x Fixes: 19f8a84713edc ("ima: measure and appraise the IMA policy itself") Signed-off-by: Roberto Sassu Reviewed-by: Krzysztof Struczynski Signed-off-by: Mimi Zohar Signed-off-by: Sasha Levin --- security/integrity/ima/ima_fs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c index 44b44d7e0dbc..853a7d2333b3 100644 --- a/security/integrity/ima/ima_fs.c +++ b/security/integrity/ima/ima_fs.c @@ -331,8 +331,7 @@ static ssize_t ima_write_policy(struct file *file, const char __user *buf, integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL, "policy_update", "signed policy required", 1, 0); - if (ima_appraise & IMA_APPRAISE_ENFORCE) - result = -EACCES; + result = -EACCES; } else { result = ima_parse_add_rule(data); } From 26204c47c87966ec458258a74555bc11ce6fca68 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 19 May 2020 17:48:52 -0400 Subject: [PATCH 101/387] fix multiplication overflow in copy_fdtable() [ Upstream commit 4e89b7210403fa4a8acafe7c602b6212b7af6c3b ] cpy and set really should be size_t; we won't get an overflow on that, since sysctl_nr_open can't be set above ~(size_t)0 / sizeof(void *), so nr that would've managed to overflow size_t on that multiplication won't get anywhere near copy_fdtable() - we'll fail with EMFILE before that. Cc: stable@kernel.org # v2.6.25+ Fixes: 9cfe015aa424 (get rid of NR_OPEN and introduce a sysctl_nr_open) Reported-by: Thiago Macieira Signed-off-by: Al Viro Signed-off-by: Sasha Levin --- fs/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/file.c b/fs/file.c index 09aac4d4729b..82d3f925bab3 100644 --- a/fs/file.c +++ b/fs/file.c @@ -89,7 +89,7 @@ static void copy_fd_bitmaps(struct fdtable *nfdt, struct fdtable *ofdt, */ static void copy_fdtable(struct fdtable *nfdt, struct fdtable *ofdt) { - unsigned int cpy, set; + size_t cpy, set; BUG_ON(nfdt->max_fds < ofdt->max_fds); From 57dd229d420af7b7397ab13ae9af736c04874469 Mon Sep 17 00:00:00 2001 From: Alexander Monakov Date: Mon, 11 May 2020 10:23:52 +0000 Subject: [PATCH 102/387] iommu/amd: Fix over-read of ACPI UID from IVRS table [ Upstream commit e461b8c991b9202b007ea2059d953e264240b0c9 ] IVRS parsing code always tries to read 255 bytes from memory when retrieving ACPI device path, and makes an assumption that firmware provides a zero-terminated string. Both of those are bugs: the entry is likely to be shorter than 255 bytes, and zero-termination is not guaranteed. With Acer SF314-42 firmware these issues manifest visibly in dmesg: AMD-Vi: ivrs, add hid:AMDI0020, uid:\_SB.FUR0\xf0\xa5, rdevid:160 AMD-Vi: ivrs, add hid:AMDI0020, uid:\_SB.FUR1\xf0\xa5, rdevid:160 AMD-Vi: ivrs, add hid:AMDI0020, uid:\_SB.FUR2\xf0\xa5, rdevid:160 AMD-Vi: ivrs, add hid:AMDI0020, uid:\_SB.FUR3>\x83e\x8d\x9a\xd1... The first three lines show how the code over-reads adjacent table entries into the UID, and in the last line it even reads garbage data beyond the end of the IVRS table itself. Since each entry has the length of the UID (uidl member of ivhd_entry struct), use that for memcpy, and manually add a zero terminator. Avoid zero-filling hid and uid arrays up front, and instead ensure the uid array is always zero-terminated. No change needed for the hid array, as it was already properly zero-terminated. Fixes: 2a0cb4e2d423c ("iommu/amd: Add new map for storing IVHD dev entry type HID") Signed-off-by: Alexander Monakov Cc: Joerg Roedel Cc: iommu@lists.linux-foundation.org Link: https://lore.kernel.org/r/20200511102352.1831-1-amonakov@ispras.ru Signed-off-by: Joerg Roedel Signed-off-by: Sasha Levin --- drivers/iommu/amd_iommu_init.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index e6ae8d123984..a3279f303b49 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -1171,8 +1171,8 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, } case IVHD_DEV_ACPI_HID: { u16 devid; - u8 hid[ACPIHID_HID_LEN] = {0}; - u8 uid[ACPIHID_UID_LEN] = {0}; + u8 hid[ACPIHID_HID_LEN]; + u8 uid[ACPIHID_UID_LEN]; int ret; if (h->type != 0x40) { @@ -1189,6 +1189,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, break; } + uid[0] = '\0'; switch (e->uidf) { case UID_NOT_PRESENT: @@ -1203,8 +1204,8 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, break; case UID_IS_CHARACTER: - memcpy(uid, (u8 *)(&e->uid), ACPIHID_UID_LEN - 1); - uid[ACPIHID_UID_LEN - 1] = '\0'; + memcpy(uid, &e->uid, e->uidl); + uid[e->uidl] = '\0'; break; default: From 350d523b27eac2d19890fa06b90242e40b70416e Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Wed, 6 May 2020 21:21:00 +0200 Subject: [PATCH 103/387] i2c: mux: demux-pinctrl: Fix an error handling path in 'i2c_demux_pinctrl_probe()' [ Upstream commit e9d1a0a41d4486955e96552293c1fcf1fce61602 ] A call to 'i2c_demux_deactivate_master()' is missing in the error handling path, as already done in the remove function. Fixes: 50a5ba876908 ("i2c: mux: demux-pinctrl: add driver") Signed-off-by: Christophe JAILLET Signed-off-by: Wolfram Sang Signed-off-by: Sasha Levin --- drivers/i2c/muxes/i2c-demux-pinctrl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/i2c/muxes/i2c-demux-pinctrl.c b/drivers/i2c/muxes/i2c-demux-pinctrl.c index 3e6fe1760d82..a86c511c29e0 100644 --- a/drivers/i2c/muxes/i2c-demux-pinctrl.c +++ b/drivers/i2c/muxes/i2c-demux-pinctrl.c @@ -270,6 +270,7 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev) err_rollback_available: device_remove_file(&pdev->dev, &dev_attr_available_masters); err_rollback: + i2c_demux_deactivate_master(priv); for (j = 0; j < i; j++) { of_node_put(priv->chan[j].parent_np); of_changeset_destroy(&priv->chan[j].chgset); From ebf9988ee7aae149595a23b52624282d03169d70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Pierret=20=28fepitre=29?= Date: Tue, 7 Apr 2020 13:32:59 +0200 Subject: [PATCH 104/387] gcc-common.h: Update for GCC 10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit c7527373fe28f97d8a196ab562db5589be0d34b9 ] Remove "params.h" include, which has been dropped in GCC 10. Remove is_a_helper() macro, which is now defined in gimple.h, as seen when running './scripts/gcc-plugin.sh g++ g++ gcc': In file included from :1: ./gcc-plugins/gcc-common.h:852:13: error: redefinition of ‘static bool is_a_helper::test(U*) [with U = const gimple; T = const ggoto*]’ 852 | inline bool is_a_helper::test(const_gimple gs) | ^~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from ./gcc-plugins/gcc-common.h:125, from :1: /usr/lib/gcc/x86_64-redhat-linux/10/plugin/include/gimple.h:1037:1: note: ‘static bool is_a_helper::test(U*) [with U = const gimple; T = const ggoto*]’ previously declared here 1037 | is_a_helper ::test (const gimple *gs) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ Add -Wno-format-diag to scripts/gcc-plugins/Makefile to avoid meaningless warnings from error() formats used by plugins: scripts/gcc-plugins/structleak_plugin.c: In function ‘int plugin_init(plugin_name_args*, plugin_gcc_version*)’: scripts/gcc-plugins/structleak_plugin.c:253:12: warning: unquoted sequence of 2 consecutive punctuation characters ‘'-’ in format [-Wformat-diag] 253 | error(G_("unknown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Signed-off-by: Frédéric Pierret (fepitre) Link: https://lore.kernel.org/r/20200407113259.270172-1-frederic.pierret@qubes-os.org [kees: include -Wno-format-diag for plugin builds] Signed-off-by: Kees Cook Signed-off-by: Sasha Levin --- scripts/gcc-plugins/Makefile | 1 + scripts/gcc-plugins/gcc-common.h | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile index 8b29dc17c73c..2cad963c4fb7 100644 --- a/scripts/gcc-plugins/Makefile +++ b/scripts/gcc-plugins/Makefile @@ -9,6 +9,7 @@ else HOST_EXTRACXXFLAGS += -I$(GCC_PLUGINS_DIR)/include -I$(src) -std=gnu++98 -fno-rtti HOST_EXTRACXXFLAGS += -fno-exceptions -fasynchronous-unwind-tables -ggdb HOST_EXTRACXXFLAGS += -Wno-narrowing -Wno-unused-variable + HOST_EXTRACXXFLAGS += -Wno-format-diag export HOST_EXTRACXXFLAGS endif diff --git a/scripts/gcc-plugins/gcc-common.h b/scripts/gcc-plugins/gcc-common.h index 08fe09c28bd2..6792915f5174 100644 --- a/scripts/gcc-plugins/gcc-common.h +++ b/scripts/gcc-plugins/gcc-common.h @@ -31,7 +31,9 @@ #include "ggc.h" #include "timevar.h" +#if BUILDING_GCC_VERSION < 10000 #include "params.h" +#endif #if BUILDING_GCC_VERSION <= 4009 #include "pointer-set.h" @@ -796,6 +798,7 @@ static inline gimple gimple_build_assign_with_ops(enum tree_code subcode, tree l return gimple_build_assign(lhs, subcode, op1, op2 PASS_MEM_STAT); } +#if BUILDING_GCC_VERSION < 10000 template <> template <> inline bool is_a_helper::test(const_gimple gs) @@ -809,6 +812,7 @@ inline bool is_a_helper::test(const_gimple gs) { return gs->code == GIMPLE_RETURN; } +#endif static inline gasm *as_a_gasm(gimple stmt) { From f477b49c2c103c40b7930104215b8f2e47c28566 Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Mon, 13 Apr 2020 18:02:37 +0200 Subject: [PATCH 105/387] HID: multitouch: add eGalaxTouch P80H84 support [ Upstream commit f9e82295eec141a0569649d400d249333d74aa91 ] Add support for P80H84 touchscreen from eGalaxy: idVendor 0x0eef D-WAV Scientific Co., Ltd idProduct 0xc002 iManufacturer 1 eGalax Inc. iProduct 2 eGalaxTouch P80H84 2019 vDIVA_1204_T01 k4.02.146 Signed-off-by: Sebastian Reichel Signed-off-by: Jiri Kosina Signed-off-by: Sasha Levin --- drivers/hid/hid-ids.h | 1 + drivers/hid/hid-multitouch.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 25c006338100..4630b58634d8 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -353,6 +353,7 @@ #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7349 0x7349 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_73F7 0x73f7 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001 0xa001 +#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_C002 0xc002 #define USB_VENDOR_ID_ELAN 0x04f3 diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index fba655d639af..1207102823de 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -1332,6 +1332,9 @@ static const struct hid_device_id mt_devices[] = { { .driver_data = MT_CLS_EGALAX_SERIAL, MT_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) }, + { .driver_data = MT_CLS_EGALAX, + MT_USB_DEVICE(USB_VENDOR_ID_DWAV, + USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_C002) }, /* Elitegroup panel */ { .driver_data = MT_CLS_SERIAL, From 1957df4975448f4b1169f8f3a83f273ccb41f5e3 Mon Sep 17 00:00:00 2001 From: Xiyu Yang Date: Sat, 25 Apr 2020 20:52:26 +0800 Subject: [PATCH 106/387] configfs: fix config_item refcnt leak in configfs_rmdir() [ Upstream commit 8aebfffacfa379ba400da573a5bf9e49634e38cb ] configfs_rmdir() invokes configfs_get_config_item(), which returns a reference of the specified config_item object to "parent_item" with increased refcnt. When configfs_rmdir() returns, local variable "parent_item" becomes invalid, so the refcount should be decreased to keep refcount balanced. The reference counting issue happens in one exception handling path of configfs_rmdir(). When down_write_killable() fails, the function forgets to decrease the refcnt increased by configfs_get_config_item(), causing a refcnt leak. Fix this issue by calling config_item_put() when down_write_killable() fails. Signed-off-by: Xiyu Yang Signed-off-by: Xin Tan Signed-off-by: Christoph Hellwig Signed-off-by: Sasha Levin --- fs/configfs/dir.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index c2ef617d2f97..c875f246cb0e 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -1537,6 +1537,7 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry) spin_lock(&configfs_dirent_lock); configfs_detach_rollback(dentry); spin_unlock(&configfs_dirent_lock); + config_item_put(parent_item); return -EINTR; } frag->frag_dead = true; From 2700d2c22e5429020145e83673b29c2697692ef4 Mon Sep 17 00:00:00 2001 From: James Hilliard Date: Sat, 11 Apr 2020 13:02:41 -0600 Subject: [PATCH 107/387] component: Silence bind error on -EPROBE_DEFER [ Upstream commit 7706b0a76a9697021e2bf395f3f065c18f51043d ] If a component fails to bind due to -EPROBE_DEFER we should not log an error as this is not a real failure. Fixes messages like: vc4-drm soc:gpu: failed to bind 3f902000.hdmi (ops vc4_hdmi_ops): -517 vc4-drm soc:gpu: master bind failed: -517 Signed-off-by: James Hilliard Link: https://lore.kernel.org/r/20200411190241.89404-1-james.hilliard1@gmail.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/base/component.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/base/component.c b/drivers/base/component.c index 08da6160e94d..55f0856bd9b5 100644 --- a/drivers/base/component.c +++ b/drivers/base/component.c @@ -162,7 +162,8 @@ static int try_to_bring_up_master(struct master *master, ret = master->ops->bind(master->dev); if (ret < 0) { devres_release_group(master->dev, NULL); - dev_info(master->dev, "master bind failed: %d\n", ret); + if (ret != -EPROBE_DEFER) + dev_info(master->dev, "master bind failed: %d\n", ret); return ret; } @@ -431,8 +432,9 @@ static int component_bind(struct component *component, struct master *master, devres_release_group(component->dev, NULL); devres_release_group(master->dev, NULL); - dev_err(master->dev, "failed to bind %s (ops %ps): %d\n", - dev_name(component->dev), component->ops, ret); + if (ret != -EPROBE_DEFER) + dev_err(master->dev, "failed to bind %s (ops %ps): %d\n", + dev_name(component->dev), component->ops, ret); } return ret; From 2e7f7b28c449de743d365a5a3d063b9cdda64c0b Mon Sep 17 00:00:00 2001 From: Yoshiyuki Kurauchi Date: Thu, 30 Apr 2020 14:01:36 +0900 Subject: [PATCH 108/387] gtp: set NLM_F_MULTI flag in gtp_genl_dump_pdp() [ Upstream commit 846c68f7f1ac82c797a2f1db3344a2966c0fe2e1 ] In drivers/net/gtp.c, gtp_genl_dump_pdp() should set NLM_F_MULTI flag since it returns multipart message. This patch adds a new arg "flags" in gtp_genl_fill_info() so that flags can be set by the callers. Signed-off-by: Yoshiyuki Kurauchi Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/gtp.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c index a9e8a7356c41..fe844888e0ed 100644 --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -1108,11 +1108,11 @@ static struct genl_family gtp_genl_family = { }; static int gtp_genl_fill_info(struct sk_buff *skb, u32 snd_portid, u32 snd_seq, - u32 type, struct pdp_ctx *pctx) + int flags, u32 type, struct pdp_ctx *pctx) { void *genlh; - genlh = genlmsg_put(skb, snd_portid, snd_seq, >p_genl_family, 0, + genlh = genlmsg_put(skb, snd_portid, snd_seq, >p_genl_family, flags, type); if (genlh == NULL) goto nlmsg_failure; @@ -1208,8 +1208,8 @@ static int gtp_genl_get_pdp(struct sk_buff *skb, struct genl_info *info) goto err_unlock; } - err = gtp_genl_fill_info(skb2, NETLINK_CB(skb).portid, - info->snd_seq, info->nlhdr->nlmsg_type, pctx); + err = gtp_genl_fill_info(skb2, NETLINK_CB(skb).portid, info->snd_seq, + 0, info->nlhdr->nlmsg_type, pctx); if (err < 0) goto err_unlock_free; @@ -1252,6 +1252,7 @@ static int gtp_genl_dump_pdp(struct sk_buff *skb, gtp_genl_fill_info(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, + NLM_F_MULTI, cb->nlh->nlmsg_type, pctx)) { cb->args[0] = i; cb->args[1] = j; From 1de356b13c9960cfe5dc180cf9774af92b6a9b91 Mon Sep 17 00:00:00 2001 From: Wu Bo Date: Thu, 30 Apr 2020 14:12:49 +0800 Subject: [PATCH 109/387] ceph: fix double unlock in handle_cap_export() [ Upstream commit 4d8e28ff3106b093d98bfd2eceb9b430c70a8758 ] If the ceph_mdsc_open_export_target_session() return fails, it will do a "goto retry", but the session mutex has already been unlocked. Re-lock the mutex in that case to ensure that we don't unlock it twice. Signed-off-by: Wu Bo Reviewed-by: "Yan, Zheng" Signed-off-by: Ilya Dryomov Signed-off-by: Sasha Levin --- fs/ceph/caps.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 617e9ae67f50..e11aacb35d6b 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -3394,6 +3394,7 @@ retry: WARN_ON(1); tsession = NULL; target = -1; + mutex_lock(&session->s_mutex); } goto retry; From 21851aa8868ad79788fccb6c0f781abb790c2600 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 1 May 2020 16:07:28 -0400 Subject: [PATCH 110/387] USB: core: Fix misleading driver bug report [ Upstream commit ac854131d9844f79e2fdcef67a7707227538d78a ] The syzbot fuzzer found a race between URB submission to endpoint 0 and device reset. Namely, during the reset we call usb_ep0_reinit() because the characteristics of ep0 may have changed (if the reset follows a firmware update, for example). While usb_ep0_reinit() is running there is a brief period during which the pointers stored in udev->ep_in[0] and udev->ep_out[0] are set to NULL, and if an URB is submitted to ep0 during that period, usb_urb_ep_type_check() will report it as a driver bug. In the absence of those pointers, the routine thinks that the endpoint doesn't exist. The log message looks like this: ------------[ cut here ]------------ usb 2-1: BOGUS urb xfer, pipe 2 != type 2 WARNING: CPU: 0 PID: 9241 at drivers/usb/core/urb.c:478 usb_submit_urb+0x1188/0x1460 drivers/usb/core/urb.c:478 Now, although submitting an URB while the device is being reset is a questionable thing to do, it shouldn't count as a driver bug as severe as submitting an URB for an endpoint that doesn't exist. Indeed, endpoint 0 always exists, even while the device is in its unconfigured state. To prevent these misleading driver bug reports, this patch updates usb_disable_endpoint() to avoid clearing the ep_in[] and ep_out[] pointers when the endpoint being disabled is ep0. There's no danger of leaving a stale pointer in place, because the usb_host_endpoint structure being pointed to is stored permanently in udev->ep0; it doesn't get deallocated until the entire usb_device structure does. Reported-and-tested-by: syzbot+db339689b2101f6f6071@syzkaller.appspotmail.com Signed-off-by: Alan Stern Link: https://lore.kernel.org/r/Pine.LNX.4.44L0.2005011558590.903-100000@netrider.rowland.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/core/message.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 2e541a029657..e33d23c2f6ea 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1081,11 +1081,11 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr, if (usb_endpoint_out(epaddr)) { ep = dev->ep_out[epnum]; - if (reset_hardware) + if (reset_hardware && epnum != 0) dev->ep_out[epnum] = NULL; } else { ep = dev->ep_in[epnum]; - if (reset_hardware) + if (reset_hardware && epnum != 0) dev->ep_in[epnum] = NULL; } if (ep) { From e09cb4c341d7cbdfd80f63cf0daa2fb9eb41943e Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 23 Apr 2020 00:05:59 +0200 Subject: [PATCH 111/387] platform/x86: asus-nb-wmi: Do not load on Asus T100TA and T200TA [ Upstream commit 3bd12da7f50b8bc191fcb3bab1f55c582234df59 ] asus-nb-wmi does not add any extra functionality on these Asus Transformer books. They have detachable keyboards, so the hotkeys are send through a HID device (and handled by the hid-asus driver) and also the rfkill functionality is not used on these devices. Besides not adding any extra functionality, initializing the WMI interface on these devices actually has a negative side-effect. For some reason the \_SB.ATKD.INIT() function which asus_wmi_platform_init() calls drives GPO2 (INT33FC:02) pin 8, which is connected to the front facing webcam LED, high and there is no (WMI or other) interface to drive this low again causing the LED to be permanently on, even during suspend. This commit adds a blacklist of DMI system_ids on which not to load the asus-nb-wmi and adds these Transformer books to this list. This fixes the webcam LED being permanently on under Linux. Signed-off-by: Hans de Goede Signed-off-by: Andy Shevchenko Signed-off-by: Sasha Levin --- drivers/platform/x86/asus-nb-wmi.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c index 0fd7e40b86a0..8137aa343706 100644 --- a/drivers/platform/x86/asus-nb-wmi.c +++ b/drivers/platform/x86/asus-nb-wmi.c @@ -561,9 +561,33 @@ static struct asus_wmi_driver asus_nb_wmi_driver = { .detect_quirks = asus_nb_wmi_quirks, }; +static const struct dmi_system_id asus_nb_wmi_blacklist[] __initconst = { + { + /* + * asus-nb-wm adds no functionality. The T100TA has a detachable + * USB kbd, so no hotkeys and it has no WMI rfkill; and loading + * asus-nb-wm causes the camera LED to turn and _stay_ on. + */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"), + }, + }, + { + /* The Asus T200TA has the same issue as the T100TA */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T200TA"), + }, + }, + {} /* Terminating entry */ +}; static int __init asus_nb_wmi_init(void) { + if (dmi_check_system(asus_nb_wmi_blacklist)) + return -ENODEV; + return asus_wmi_register_driver(&asus_nb_wmi_driver); } From 7a5c2b73e522db3200a69f4772beeb72f786a0b9 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 14 Apr 2020 11:07:22 +0200 Subject: [PATCH 112/387] ARM: futex: Address build warning [ Upstream commit 8101b5a1531f3390b3a69fa7934c70a8fd6566ad ] Stephen reported the following build warning on a ARM multi_v7_defconfig build with GCC 9.2.1: kernel/futex.c: In function 'do_futex': kernel/futex.c:1676:17: warning: 'oldval' may be used uninitialized in this function [-Wmaybe-uninitialized] 1676 | return oldval == cmparg; | ~~~~~~~^~~~~~~~~ kernel/futex.c:1652:6: note: 'oldval' was declared here 1652 | int oldval, ret; | ^~~~~~ introduced by commit a08971e9488d ("futex: arch_futex_atomic_op_inuser() calling conventions change"). While that change should not make any difference it confuses GCC which fails to work out that oldval is not referenced when the return value is not zero. GCC fails to properly analyze arch_futex_atomic_op_inuser(). It's not the early return, the issue is with the assembly macros. GCC fails to detect that those either set 'ret' to 0 and set oldval or set 'ret' to -EFAULT which makes oldval uninteresting. The store to the callsite supplied oldval pointer is conditional on ret == 0. The straight forward way to solve this is to make the store unconditional. Aside of addressing the build warning this makes sense anyway because it removes the conditional from the fastpath. In the error case the stored value is uninteresting and the extra store does not matter at all. Reported-by: Stephen Rothwell Signed-off-by: Thomas Gleixner Link: https://lkml.kernel.org/r/87pncao2ph.fsf@nanos.tec.linutronix.de Signed-off-by: Sasha Levin --- arch/arm/include/asm/futex.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/arm/include/asm/futex.h b/arch/arm/include/asm/futex.h index cc414382dab4..561b2ba6bc28 100644 --- a/arch/arm/include/asm/futex.h +++ b/arch/arm/include/asm/futex.h @@ -162,8 +162,13 @@ arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) preempt_enable(); #endif - if (!ret) - *oval = oldval; + /* + * Store unconditionally. If ret != 0 the extra store is the least + * of the worries but GCC cannot figure out that __futex_atomic_op() + * is either setting ret to -EFAULT or storing the old value in + * oldval which results in a uninitialized warning at the call site. + */ + *oval = oldval; return ret; } From c0d34399045609eda76882fa6d01fdfaf5b20d38 Mon Sep 17 00:00:00 2001 From: Kevin Hao Date: Fri, 11 Oct 2019 23:00:14 +0800 Subject: [PATCH 113/387] i2c: dev: Fix the race between the release of i2c_dev and cdev [ Upstream commit 1413ef638abae4ab5621901cf4d8ef08a4a48ba6 ] The struct cdev is embedded in the struct i2c_dev. In the current code, we would free the i2c_dev struct directly in put_i2c_dev(), but the cdev is manged by a kobject, and the release of it is not predictable. So it is very possible that the i2c_dev is freed before the cdev is entirely released. We can easily get the following call trace with CONFIG_DEBUG_KOBJECT_RELEASE and CONFIG_DEBUG_OBJECTS_TIMERS enabled. ODEBUG: free active (active state 0) object type: timer_list hint: delayed_work_timer_fn+0x0/0x38 WARNING: CPU: 19 PID: 1 at lib/debugobjects.c:325 debug_print_object+0xb0/0xf0 Modules linked in: CPU: 19 PID: 1 Comm: swapper/0 Tainted: G W 5.2.20-yocto-standard+ #120 Hardware name: Marvell OcteonTX CN96XX board (DT) pstate: 80c00089 (Nzcv daIf +PAN +UAO) pc : debug_print_object+0xb0/0xf0 lr : debug_print_object+0xb0/0xf0 sp : ffff00001292f7d0 x29: ffff00001292f7d0 x28: ffff800b82151788 x27: 0000000000000001 x26: ffff800b892c0000 x25: ffff0000124a2558 x24: 0000000000000000 x23: ffff00001107a1d8 x22: ffff0000116b5088 x21: ffff800bdc6afca8 x20: ffff000012471ae8 x19: ffff00001168f2c8 x18: 0000000000000010 x17: 00000000fd6f304b x16: 00000000ee79de43 x15: ffff800bc0e80568 x14: 79616c6564203a74 x13: 6e6968207473696c x12: 5f72656d6974203a x11: ffff0000113f0018 x10: 0000000000000000 x9 : 000000000000001f x8 : 0000000000000000 x7 : ffff0000101294cc x6 : 0000000000000000 x5 : 0000000000000000 x4 : 0000000000000001 x3 : 00000000ffffffff x2 : 0000000000000000 x1 : 387fc15c8ec0f200 x0 : 0000000000000000 Call trace: debug_print_object+0xb0/0xf0 __debug_check_no_obj_freed+0x19c/0x228 debug_check_no_obj_freed+0x1c/0x28 kfree+0x250/0x440 put_i2c_dev+0x68/0x78 i2cdev_detach_adapter+0x60/0xc8 i2cdev_notifier_call+0x3c/0x70 notifier_call_chain+0x8c/0xe8 blocking_notifier_call_chain+0x64/0x88 device_del+0x74/0x380 device_unregister+0x54/0x78 i2c_del_adapter+0x278/0x2d0 unittest_i2c_bus_remove+0x3c/0x80 platform_drv_remove+0x30/0x50 device_release_driver_internal+0xf4/0x1c0 driver_detach+0x58/0xa0 bus_remove_driver+0x84/0xd8 driver_unregister+0x34/0x60 platform_driver_unregister+0x20/0x30 of_unittest_overlay+0x8d4/0xbe0 of_unittest+0xae8/0xb3c do_one_initcall+0xac/0x450 do_initcall_level+0x208/0x224 kernel_init_freeable+0x2d8/0x36c kernel_init+0x18/0x108 ret_from_fork+0x10/0x1c irq event stamp: 3934661 hardirqs last enabled at (3934661): [] debug_exception_exit+0x4c/0x58 hardirqs last disabled at (3934660): [] debug_exception_enter+0xa4/0xe0 softirqs last enabled at (3934654): [] __do_softirq+0x46c/0x628 softirqs last disabled at (3934649): [] irq_exit+0x104/0x118 This is a common issue when using cdev embedded in a struct. Fortunately, we already have a mechanism to solve this kind of issue. Please see commit 233ed09d7fda ("chardev: add helper function to register char devs with a struct device") for more detail. In this patch, we choose to embed the struct device into the i2c_dev, and use the API provided by the commit 233ed09d7fda to make sure that the release of i2c_dev and cdev are in sequence. Signed-off-by: Kevin Hao Signed-off-by: Wolfram Sang Signed-off-by: Sasha Levin --- drivers/i2c/i2c-dev.c | 46 +++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index eaa312bc3a3c..c4066276eb7b 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -47,7 +47,7 @@ struct i2c_dev { struct list_head list; struct i2c_adapter *adap; - struct device *dev; + struct device dev; struct cdev cdev; }; @@ -91,12 +91,14 @@ static struct i2c_dev *get_free_i2c_dev(struct i2c_adapter *adap) return i2c_dev; } -static void put_i2c_dev(struct i2c_dev *i2c_dev) +static void put_i2c_dev(struct i2c_dev *i2c_dev, bool del_cdev) { spin_lock(&i2c_dev_list_lock); list_del(&i2c_dev->list); spin_unlock(&i2c_dev_list_lock); - kfree(i2c_dev); + if (del_cdev) + cdev_device_del(&i2c_dev->cdev, &i2c_dev->dev); + put_device(&i2c_dev->dev); } static ssize_t name_show(struct device *dev, @@ -542,6 +544,14 @@ static const struct file_operations i2cdev_fops = { static struct class *i2c_dev_class; +static void i2cdev_dev_release(struct device *dev) +{ + struct i2c_dev *i2c_dev; + + i2c_dev = container_of(dev, struct i2c_dev, dev); + kfree(i2c_dev); +} + static int i2cdev_attach_adapter(struct device *dev, void *dummy) { struct i2c_adapter *adap; @@ -558,27 +568,23 @@ static int i2cdev_attach_adapter(struct device *dev, void *dummy) cdev_init(&i2c_dev->cdev, &i2cdev_fops); i2c_dev->cdev.owner = THIS_MODULE; - res = cdev_add(&i2c_dev->cdev, MKDEV(I2C_MAJOR, adap->nr), 1); - if (res) - goto error_cdev; - /* register this i2c device with the driver core */ - i2c_dev->dev = device_create(i2c_dev_class, &adap->dev, - MKDEV(I2C_MAJOR, adap->nr), NULL, - "i2c-%d", adap->nr); - if (IS_ERR(i2c_dev->dev)) { - res = PTR_ERR(i2c_dev->dev); - goto error; + device_initialize(&i2c_dev->dev); + i2c_dev->dev.devt = MKDEV(I2C_MAJOR, adap->nr); + i2c_dev->dev.class = i2c_dev_class; + i2c_dev->dev.parent = &adap->dev; + i2c_dev->dev.release = i2cdev_dev_release; + dev_set_name(&i2c_dev->dev, "i2c-%d", adap->nr); + + res = cdev_device_add(&i2c_dev->cdev, &i2c_dev->dev); + if (res) { + put_i2c_dev(i2c_dev, false); + return res; } pr_debug("i2c-dev: adapter [%s] registered as minor %d\n", adap->name, adap->nr); return 0; -error: - cdev_del(&i2c_dev->cdev); -error_cdev: - put_i2c_dev(i2c_dev); - return res; } static int i2cdev_detach_adapter(struct device *dev, void *dummy) @@ -594,9 +600,7 @@ static int i2cdev_detach_adapter(struct device *dev, void *dummy) if (!i2c_dev) /* attach_adapter must have failed */ return 0; - cdev_del(&i2c_dev->cdev); - put_i2c_dev(i2c_dev); - device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr)); + put_i2c_dev(i2c_dev, true); pr_debug("i2c-dev: adapter [%s] unregistered\n", adap->name); return 0; From 251716d96a1dd6cfb2bef917eccae63372aa37f2 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 21 May 2020 16:48:44 -0400 Subject: [PATCH 114/387] padata: set cpu_index of unused CPUs to -1 [ Upstream commit 1bd845bcb41d5b7f83745e0cb99273eb376f2ec5 ] The parallel queue per-cpu data structure gets initialized only for CPUs in the 'pcpu' CPU mask set. This is not sufficient as the reorder timer may run on a different CPU and might wrongly decide it's the target CPU for the next reorder item as per-cpu memory gets memset(0) and we might be waiting for the first CPU in cpumask.pcpu, i.e. cpu_index 0. Make the '__this_cpu_read(pd->pqueue->cpu_index) == next_queue->cpu_index' compare in padata_get_next() fail in this case by initializing the cpu_index member of all per-cpu parallel queues. Use -1 for unused ones. Signed-off-by: Mathias Krause Signed-off-by: Herbert Xu Signed-off-by: Daniel Jordan Signed-off-by: Sasha Levin --- kernel/padata.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/kernel/padata.c b/kernel/padata.c index 693536efccf9..52a1d3fd13b5 100644 --- a/kernel/padata.c +++ b/kernel/padata.c @@ -462,8 +462,14 @@ static void padata_init_pqueues(struct parallel_data *pd) struct padata_parallel_queue *pqueue; cpu_index = 0; - for_each_cpu(cpu, pd->cpumask.pcpu) { + for_each_possible_cpu(cpu) { pqueue = per_cpu_ptr(pd->pqueue, cpu); + + if (!cpumask_test_cpu(cpu, pd->cpumask.pcpu)) { + pqueue->cpu_index = -1; + continue; + } + pqueue->pd = pd; pqueue->cpu_index = cpu_index; cpu_index++; From f501513bd2dda34c73bf12785163bfe713af0d99 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 21 May 2020 16:48:45 -0400 Subject: [PATCH 115/387] padata: Replace delayed timer with immediate workqueue in padata_reorder [ Upstream commit 6fc4dbcf0276279d488c5fbbfabe94734134f4fa ] The function padata_reorder will use a timer when it cannot progress while completed jobs are outstanding (pd->reorder_objects > 0). This is suboptimal as if we do end up using the timer then it would have introduced a gratuitous delay of one second. In fact we can easily distinguish between whether completed jobs are outstanding and whether we can make progress. All we have to do is look at the next pqueue list. This patch does that by replacing pd->processed with pd->cpu so that the next pqueue is more accessible. A work queue is used instead of the original try_again to avoid hogging the CPU. Note that we don't bother removing the work queue in padata_flush_queues because the whole premise is broken. You cannot flush async crypto requests so it makes no sense to even try. A subsequent patch will fix it by replacing it with a ref counting scheme. Signed-off-by: Herbert Xu [dj: - adjust context - corrected setup_timer -> timer_setup to delete hunk - skip padata_flush_queues() hunk, function already removed in 4.9] Signed-off-by: Daniel Jordan Signed-off-by: Sasha Levin --- include/linux/padata.h | 13 ++---- kernel/padata.c | 95 ++++++++---------------------------------- 2 files changed, 22 insertions(+), 86 deletions(-) diff --git a/include/linux/padata.h b/include/linux/padata.h index 86c885f90878..3afa17ed59da 100644 --- a/include/linux/padata.h +++ b/include/linux/padata.h @@ -24,7 +24,6 @@ #include #include #include -#include #include #include @@ -85,18 +84,14 @@ struct padata_serial_queue { * @serial: List to wait for serialization after reordering. * @pwork: work struct for parallelization. * @swork: work struct for serialization. - * @pd: Backpointer to the internal control structure. * @work: work struct for parallelization. - * @reorder_work: work struct for reordering. * @num_obj: Number of objects that are processed by this cpu. * @cpu_index: Index of the cpu. */ struct padata_parallel_queue { struct padata_list parallel; struct padata_list reorder; - struct parallel_data *pd; struct work_struct work; - struct work_struct reorder_work; atomic_t num_obj; int cpu_index; }; @@ -122,10 +117,10 @@ struct padata_cpumask { * @reorder_objects: Number of objects waiting in the reorder queues. * @refcnt: Number of objects holding a reference on this parallel_data. * @max_seq_nr: Maximal used sequence number. + * @cpu: Next CPU to be processed. * @cpumask: The cpumasks in use for parallel and serial workers. + * @reorder_work: work struct for reordering. * @lock: Reorder lock. - * @processed: Number of already processed objects. - * @timer: Reorder timer. */ struct parallel_data { struct padata_instance *pinst; @@ -134,10 +129,10 @@ struct parallel_data { atomic_t reorder_objects; atomic_t refcnt; atomic_t seq_nr; + int cpu; struct padata_cpumask cpumask; + struct work_struct reorder_work; spinlock_t lock ____cacheline_aligned; - unsigned int processed; - struct timer_list timer; }; /** diff --git a/kernel/padata.c b/kernel/padata.c index 52a1d3fd13b5..0b9c39730d6d 100644 --- a/kernel/padata.c +++ b/kernel/padata.c @@ -166,23 +166,12 @@ EXPORT_SYMBOL(padata_do_parallel); */ static struct padata_priv *padata_get_next(struct parallel_data *pd) { - int cpu, num_cpus; - unsigned int next_nr, next_index; struct padata_parallel_queue *next_queue; struct padata_priv *padata; struct padata_list *reorder; + int cpu = pd->cpu; - num_cpus = cpumask_weight(pd->cpumask.pcpu); - - /* - * Calculate the percpu reorder queue and the sequence - * number of the next object. - */ - next_nr = pd->processed; - next_index = next_nr % num_cpus; - cpu = padata_index_to_cpu(pd, next_index); next_queue = per_cpu_ptr(pd->pqueue, cpu); - reorder = &next_queue->reorder; spin_lock(&reorder->lock); @@ -193,7 +182,8 @@ static struct padata_priv *padata_get_next(struct parallel_data *pd) list_del_init(&padata->list); atomic_dec(&pd->reorder_objects); - pd->processed++; + pd->cpu = cpumask_next_wrap(cpu, pd->cpumask.pcpu, -1, + false); spin_unlock(&reorder->lock); goto out; @@ -216,6 +206,7 @@ static void padata_reorder(struct parallel_data *pd) struct padata_priv *padata; struct padata_serial_queue *squeue; struct padata_instance *pinst = pd->pinst; + struct padata_parallel_queue *next_queue; /* * We need to ensure that only one cpu can work on dequeueing of @@ -247,7 +238,6 @@ static void padata_reorder(struct parallel_data *pd) * so exit immediately. */ if (PTR_ERR(padata) == -ENODATA) { - del_timer(&pd->timer); spin_unlock_bh(&pd->lock); return; } @@ -266,70 +256,29 @@ static void padata_reorder(struct parallel_data *pd) /* * The next object that needs serialization might have arrived to - * the reorder queues in the meantime, we will be called again - * from the timer function if no one else cares for it. + * the reorder queues in the meantime. * - * Ensure reorder_objects is read after pd->lock is dropped so we see - * an increment from another task in padata_do_serial. Pairs with + * Ensure reorder queue is read after pd->lock is dropped so we see + * new objects from another task in padata_do_serial. Pairs with * smp_mb__after_atomic in padata_do_serial. */ smp_mb(); - if (atomic_read(&pd->reorder_objects) - && !(pinst->flags & PADATA_RESET)) - mod_timer(&pd->timer, jiffies + HZ); - else - del_timer(&pd->timer); - return; + next_queue = per_cpu_ptr(pd->pqueue, pd->cpu); + if (!list_empty(&next_queue->reorder.list)) + queue_work(pinst->wq, &pd->reorder_work); } static void invoke_padata_reorder(struct work_struct *work) { - struct padata_parallel_queue *pqueue; struct parallel_data *pd; local_bh_disable(); - pqueue = container_of(work, struct padata_parallel_queue, reorder_work); - pd = pqueue->pd; + pd = container_of(work, struct parallel_data, reorder_work); padata_reorder(pd); local_bh_enable(); } -static void padata_reorder_timer(unsigned long arg) -{ - struct parallel_data *pd = (struct parallel_data *)arg; - unsigned int weight; - int target_cpu, cpu; - - cpu = get_cpu(); - - /* We don't lock pd here to not interfere with parallel processing - * padata_reorder() calls on other CPUs. We just need any CPU out of - * the cpumask.pcpu set. It would be nice if it's the right one but - * it doesn't matter if we're off to the next one by using an outdated - * pd->processed value. - */ - weight = cpumask_weight(pd->cpumask.pcpu); - target_cpu = padata_index_to_cpu(pd, pd->processed % weight); - - /* ensure to call the reorder callback on the correct CPU */ - if (cpu != target_cpu) { - struct padata_parallel_queue *pqueue; - struct padata_instance *pinst; - - /* The timer function is serialized wrt itself -- no locking - * needed. - */ - pinst = pd->pinst; - pqueue = per_cpu_ptr(pd->pqueue, target_cpu); - queue_work_on(target_cpu, pinst->wq, &pqueue->reorder_work); - } else { - padata_reorder(pd); - } - - put_cpu(); -} - static void padata_serial_worker(struct work_struct *serial_work) { struct padata_serial_queue *squeue; @@ -383,9 +332,8 @@ void padata_do_serial(struct padata_priv *padata) cpu = get_cpu(); - /* We need to run on the same CPU padata_do_parallel(.., padata, ..) - * was called on -- or, at least, enqueue the padata object into the - * correct per-cpu queue. + /* We need to enqueue the padata object into the correct + * per-cpu queue. */ if (cpu != padata->cpu) { reorder_via_wq = 1; @@ -395,12 +343,12 @@ void padata_do_serial(struct padata_priv *padata) pqueue = per_cpu_ptr(pd->pqueue, cpu); spin_lock(&pqueue->reorder.lock); - atomic_inc(&pd->reorder_objects); list_add_tail(&padata->list, &pqueue->reorder.list); + atomic_inc(&pd->reorder_objects); spin_unlock(&pqueue->reorder.lock); /* - * Ensure the atomic_inc of reorder_objects above is ordered correctly + * Ensure the addition to the reorder list is ordered correctly * with the trylock of pd->lock in padata_reorder. Pairs with smp_mb * in padata_reorder. */ @@ -408,13 +356,7 @@ void padata_do_serial(struct padata_priv *padata) put_cpu(); - /* If we're running on the wrong CPU, call padata_reorder() via a - * kernel worker. - */ - if (reorder_via_wq) - queue_work_on(cpu, pd->pinst->wq, &pqueue->reorder_work); - else - padata_reorder(pd); + padata_reorder(pd); } EXPORT_SYMBOL(padata_do_serial); @@ -470,14 +412,12 @@ static void padata_init_pqueues(struct parallel_data *pd) continue; } - pqueue->pd = pd; pqueue->cpu_index = cpu_index; cpu_index++; __padata_list_init(&pqueue->reorder); __padata_list_init(&pqueue->parallel); INIT_WORK(&pqueue->work, padata_parallel_worker); - INIT_WORK(&pqueue->reorder_work, invoke_padata_reorder); atomic_set(&pqueue->num_obj, 0); } } @@ -505,12 +445,13 @@ static struct parallel_data *padata_alloc_pd(struct padata_instance *pinst, padata_init_pqueues(pd); padata_init_squeues(pd); - setup_timer(&pd->timer, padata_reorder_timer, (unsigned long)pd); atomic_set(&pd->seq_nr, -1); atomic_set(&pd->reorder_objects, 0); atomic_set(&pd->refcnt, 1); pd->pinst = pinst; spin_lock_init(&pd->lock); + pd->cpu = cpumask_first(pcpumask); + INIT_WORK(&pd->reorder_work, invoke_padata_reorder); return pd; From 52a3af1c9321ff2bc7d91b2465af9843f1afabf3 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Thu, 21 May 2020 16:48:46 -0400 Subject: [PATCH 116/387] padata: initialize pd->cpu with effective cpumask [ Upstream commit ec9c7d19336ee98ecba8de80128aa405c45feebb ] Exercising CPU hotplug on a 5.2 kernel with recent padata fixes from cryptodev-2.6.git in an 8-CPU kvm guest... # modprobe tcrypt alg="pcrypt(rfc4106(gcm(aes)))" type=3 # echo 0 > /sys/devices/system/cpu/cpu1/online # echo c > /sys/kernel/pcrypt/pencrypt/parallel_cpumask # modprobe tcrypt mode=215 ...caused the following crash: BUG: kernel NULL pointer dereference, address: 0000000000000000 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 0 P4D 0 Oops: 0000 [#1] SMP PTI CPU: 2 PID: 134 Comm: kworker/2:2 Not tainted 5.2.0-padata-base+ #7 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0- Workqueue: pencrypt padata_parallel_worker RIP: 0010:padata_reorder+0xcb/0x180 ... Call Trace: padata_do_serial+0x57/0x60 pcrypt_aead_enc+0x3a/0x50 [pcrypt] padata_parallel_worker+0x9b/0xe0 process_one_work+0x1b5/0x3f0 worker_thread+0x4a/0x3c0 ... In padata_alloc_pd, pd->cpu is set using the user-supplied cpumask instead of the effective cpumask, and in this case cpumask_first picked an offline CPU. The offline CPU's reorder->list.next is NULL in padata_reorder because the list wasn't initialized in padata_init_pqueues, which only operates on CPUs in the effective mask. Fix by using the effective mask in padata_alloc_pd. Fixes: 6fc4dbcf0276 ("padata: Replace delayed timer with immediate workqueue in padata_reorder") Signed-off-by: Daniel Jordan Cc: Herbert Xu Cc: Steffen Klassert Cc: linux-crypto@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Herbert Xu Signed-off-by: Daniel Jordan Signed-off-by: Sasha Levin --- kernel/padata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/padata.c b/kernel/padata.c index 0b9c39730d6d..1030e6cfc08c 100644 --- a/kernel/padata.c +++ b/kernel/padata.c @@ -450,7 +450,7 @@ static struct parallel_data *padata_alloc_pd(struct padata_instance *pinst, atomic_set(&pd->refcnt, 1); pd->pinst = pinst; spin_lock_init(&pd->lock); - pd->cpu = cpumask_first(pcpumask); + pd->cpu = cpumask_first(pd->cpumask.pcpu); INIT_WORK(&pd->reorder_work, invoke_padata_reorder); return pd; From bae3b5078a8782865316d4a3fc3c1f95d063cd3a Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Thu, 21 May 2020 16:48:47 -0400 Subject: [PATCH 117/387] padata: purge get_cpu and reorder_via_wq from padata_do_serial [ Upstream commit 065cf577135a4977931c7a1e1edf442bfd9773dd ] With the removal of the padata timer, padata_do_serial no longer needs special CPU handling, so remove it. Signed-off-by: Daniel Jordan Cc: Herbert Xu Cc: Steffen Klassert Cc: linux-crypto@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Herbert Xu Signed-off-by: Daniel Jordan Signed-off-by: Sasha Levin --- kernel/padata.c | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/kernel/padata.c b/kernel/padata.c index 1030e6cfc08c..e82f066d63ac 100644 --- a/kernel/padata.c +++ b/kernel/padata.c @@ -323,24 +323,9 @@ static void padata_serial_worker(struct work_struct *serial_work) */ void padata_do_serial(struct padata_priv *padata) { - int cpu; - struct padata_parallel_queue *pqueue; - struct parallel_data *pd; - int reorder_via_wq = 0; - - pd = padata->pd; - - cpu = get_cpu(); - - /* We need to enqueue the padata object into the correct - * per-cpu queue. - */ - if (cpu != padata->cpu) { - reorder_via_wq = 1; - cpu = padata->cpu; - } - - pqueue = per_cpu_ptr(pd->pqueue, cpu); + struct parallel_data *pd = padata->pd; + struct padata_parallel_queue *pqueue = per_cpu_ptr(pd->pqueue, + padata->cpu); spin_lock(&pqueue->reorder.lock); list_add_tail(&padata->list, &pqueue->reorder.list); @@ -354,8 +339,6 @@ void padata_do_serial(struct padata_priv *padata) */ smp_mb__after_atomic(); - put_cpu(); - padata_reorder(pd); } EXPORT_SYMBOL(padata_do_serial); From a5233a3fee3b6afb9aed3aa8db81e271a6dca9ef Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 21 May 2020 15:44:34 +0100 Subject: [PATCH 118/387] arm64: fix the flush_icache_range arguments in machine_kexec Commit d51c214541c5154dda3037289ee895ea3ded5ebd upstream. The second argument is the end "pointer", not the length. Fixes: d28f6df1305a ("arm64/kexec: Add core kexec support") Cc: # 4.8.x- Signed-off-by: Christoph Hellwig Signed-off-by: Catalin Marinas Signed-off-by: Sasha Levin --- arch/arm64/kernel/machine_kexec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c index bc96c8a7fc79..3e4b778f16a5 100644 --- a/arch/arm64/kernel/machine_kexec.c +++ b/arch/arm64/kernel/machine_kexec.c @@ -177,7 +177,8 @@ void machine_kexec(struct kimage *kimage) /* Flush the reboot_code_buffer in preparation for its execution. */ __flush_dcache_area(reboot_code_buffer, arm64_relocate_new_kernel_size); flush_icache_range((uintptr_t)reboot_code_buffer, - arm64_relocate_new_kernel_size); + (uintptr_t)reboot_code_buffer + + arm64_relocate_new_kernel_size); /* Flush the kimage list and its buffers. */ kexec_list_flush(kimage); From f76905ce52653e8a821963c35d9013cff19b1399 Mon Sep 17 00:00:00 2001 From: Kevin Hao Date: Tue, 8 Oct 2019 19:29:34 +0800 Subject: [PATCH 119/387] watchdog: Fix the race between the release of watchdog_core_data and cdev commit 72139dfa2464e43957d330266994740bb7be2535 upstream. The struct cdev is embedded in the struct watchdog_core_data. In the current code, we manage the watchdog_core_data with a kref, but the cdev is manged by a kobject. There is no any relationship between this kref and kobject. So it is possible that the watchdog_core_data is freed before the cdev is entirely released. We can easily get the following call trace with CONFIG_DEBUG_KOBJECT_RELEASE and CONFIG_DEBUG_OBJECTS_TIMERS enabled. ODEBUG: free active (active state 0) object type: timer_list hint: delayed_work_timer_fn+0x0/0x38 WARNING: CPU: 23 PID: 1028 at lib/debugobjects.c:481 debug_print_object+0xb0/0xf0 Modules linked in: softdog(-) deflate ctr twofish_generic twofish_common camellia_generic serpent_generic blowfish_generic blowfish_common cast5_generic cast_common cmac xcbc af_key sch_fq_codel openvswitch nsh nf_conncount nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 CPU: 23 PID: 1028 Comm: modprobe Not tainted 5.3.0-next-20190924-yoctodev-standard+ #180 Hardware name: Marvell OcteonTX CN96XX board (DT) pstate: 00400009 (nzcv daif +PAN -UAO) pc : debug_print_object+0xb0/0xf0 lr : debug_print_object+0xb0/0xf0 sp : ffff80001cbcfc70 x29: ffff80001cbcfc70 x28: ffff800010ea2128 x27: ffff800010bad000 x26: 0000000000000000 x25: ffff80001103c640 x24: ffff80001107b268 x23: ffff800010bad9e8 x22: ffff800010ea2128 x21: ffff000bc2c62af8 x20: ffff80001103c600 x19: ffff800010e867d8 x18: 0000000000000060 x17: 0000000000000000 x16: 0000000000000000 x15: ffff000bd7240470 x14: 6e6968207473696c x13: 5f72656d6974203a x12: 6570797420746365 x11: 6a626f2029302065 x10: 7461747320657669 x9 : 7463612820657669 x8 : 3378302f3078302b x7 : 0000000000001d7a x6 : ffff800010fd5889 x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000 x2 : ffff000bff948548 x1 : 276a1c9e1edc2300 x0 : 0000000000000000 Call trace: debug_print_object+0xb0/0xf0 debug_check_no_obj_freed+0x1e8/0x210 kfree+0x1b8/0x368 watchdog_cdev_unregister+0x88/0xc8 watchdog_dev_unregister+0x38/0x48 watchdog_unregister_device+0xa8/0x100 softdog_exit+0x18/0xfec4 [softdog] __arm64_sys_delete_module+0x174/0x200 el0_svc_handler+0xd0/0x1c8 el0_svc+0x8/0xc This is a common issue when using cdev embedded in a struct. Fortunately, we already have a mechanism to solve this kind of issue. Please see commit 233ed09d7fda ("chardev: add helper function to register char devs with a struct device") for more detail. In this patch, we choose to embed the struct device into the watchdog_core_data, and use the API provided by the commit 233ed09d7fda to make sure that the release of watchdog_core_data and cdev are in sequence. Signed-off-by: Kevin Hao Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20191008112934.29669-1-haokexin@gmail.com Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck [bwh: Backported to 4.9: - There's no reboot notifier here - Adjust context] Signed-off-by: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- drivers/watchdog/watchdog_dev.c | 67 +++++++++++++++------------------ 1 file changed, 30 insertions(+), 37 deletions(-) diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c index 9e17d933ea94..3167f276c4c2 100644 --- a/drivers/watchdog/watchdog_dev.c +++ b/drivers/watchdog/watchdog_dev.c @@ -38,7 +38,6 @@ #include /* For __init/__exit/... */ #include /* For timeout functions */ #include /* For printk/panic/... */ -#include /* For data references */ #include /* For handling misc devices */ #include /* For module stuff/... */ #include /* For mutexes */ @@ -53,14 +52,14 @@ /* * struct watchdog_core_data - watchdog core internal data - * @kref: Reference count. + * @dev: The watchdog's internal device * @cdev: The watchdog's Character device. * @wdd: Pointer to watchdog device. * @lock: Lock for watchdog core. * @status: Watchdog core internal status bits. */ struct watchdog_core_data { - struct kref kref; + struct device dev; struct cdev cdev; struct watchdog_device *wdd; struct mutex lock; @@ -794,7 +793,7 @@ static int watchdog_open(struct inode *inode, struct file *file) file->private_data = wd_data; if (!hw_running) - kref_get(&wd_data->kref); + get_device(&wd_data->dev); /* dev/watchdog is a virtual (and thus non-seekable) filesystem */ return nonseekable_open(inode, file); @@ -806,11 +805,11 @@ out_clear: return err; } -static void watchdog_core_data_release(struct kref *kref) +static void watchdog_core_data_release(struct device *dev) { struct watchdog_core_data *wd_data; - wd_data = container_of(kref, struct watchdog_core_data, kref); + wd_data = container_of(dev, struct watchdog_core_data, dev); kfree(wd_data); } @@ -870,7 +869,7 @@ done: */ if (!running) { module_put(wd_data->cdev.owner); - kref_put(&wd_data->kref, watchdog_core_data_release); + put_device(&wd_data->dev); } return 0; } @@ -889,17 +888,22 @@ static struct miscdevice watchdog_miscdev = { .fops = &watchdog_fops, }; +static struct class watchdog_class = { + .name = "watchdog", + .owner = THIS_MODULE, + .dev_groups = wdt_groups, +}; + /* * watchdog_cdev_register: register watchdog character device * @wdd: watchdog device - * @devno: character device number * * Register a watchdog character device including handling the legacy * /dev/watchdog node. /dev/watchdog is actually a miscdevice and * thus we set it up like that. */ -static int watchdog_cdev_register(struct watchdog_device *wdd, dev_t devno) +static int watchdog_cdev_register(struct watchdog_device *wdd) { struct watchdog_core_data *wd_data; int err; @@ -907,7 +911,6 @@ static int watchdog_cdev_register(struct watchdog_device *wdd, dev_t devno) wd_data = kzalloc(sizeof(struct watchdog_core_data), GFP_KERNEL); if (!wd_data) return -ENOMEM; - kref_init(&wd_data->kref); mutex_init(&wd_data->lock); wd_data->wdd = wdd; @@ -934,23 +937,33 @@ static int watchdog_cdev_register(struct watchdog_device *wdd, dev_t devno) } } + device_initialize(&wd_data->dev); + wd_data->dev.devt = MKDEV(MAJOR(watchdog_devt), wdd->id); + wd_data->dev.class = &watchdog_class; + wd_data->dev.parent = wdd->parent; + wd_data->dev.groups = wdd->groups; + wd_data->dev.release = watchdog_core_data_release; + dev_set_drvdata(&wd_data->dev, wdd); + dev_set_name(&wd_data->dev, "watchdog%d", wdd->id); + /* Fill in the data structures */ cdev_init(&wd_data->cdev, &watchdog_fops); - wd_data->cdev.owner = wdd->ops->owner; /* Add the device */ - err = cdev_add(&wd_data->cdev, devno, 1); + err = cdev_device_add(&wd_data->cdev, &wd_data->dev); if (err) { pr_err("watchdog%d unable to add device %d:%d\n", wdd->id, MAJOR(watchdog_devt), wdd->id); if (wdd->id == 0) { misc_deregister(&watchdog_miscdev); old_wd_data = NULL; - kref_put(&wd_data->kref, watchdog_core_data_release); + put_device(&wd_data->dev); } return err; } + wd_data->cdev.owner = wdd->ops->owner; + /* Record time of most recent heartbeat as 'just before now'. */ wd_data->last_hw_keepalive = jiffies - 1; @@ -960,7 +973,7 @@ static int watchdog_cdev_register(struct watchdog_device *wdd, dev_t devno) */ if (watchdog_hw_running(wdd)) { __module_get(wdd->ops->owner); - kref_get(&wd_data->kref); + get_device(&wd_data->dev); queue_delayed_work(watchdog_wq, &wd_data->work, 0); } @@ -979,7 +992,7 @@ static void watchdog_cdev_unregister(struct watchdog_device *wdd) { struct watchdog_core_data *wd_data = wdd->wd_data; - cdev_del(&wd_data->cdev); + cdev_device_del(&wd_data->cdev, &wd_data->dev); if (wdd->id == 0) { misc_deregister(&watchdog_miscdev); old_wd_data = NULL; @@ -992,15 +1005,9 @@ static void watchdog_cdev_unregister(struct watchdog_device *wdd) cancel_delayed_work_sync(&wd_data->work); - kref_put(&wd_data->kref, watchdog_core_data_release); + put_device(&wd_data->dev); } -static struct class watchdog_class = { - .name = "watchdog", - .owner = THIS_MODULE, - .dev_groups = wdt_groups, -}; - /* * watchdog_dev_register: register a watchdog device * @wdd: watchdog device @@ -1012,27 +1019,14 @@ static struct class watchdog_class = { int watchdog_dev_register(struct watchdog_device *wdd) { - struct device *dev; - dev_t devno; int ret; - devno = MKDEV(MAJOR(watchdog_devt), wdd->id); - - ret = watchdog_cdev_register(wdd, devno); + ret = watchdog_cdev_register(wdd); if (ret) return ret; - dev = device_create_with_groups(&watchdog_class, wdd->parent, - devno, wdd, wdd->groups, - "watchdog%d", wdd->id); - if (IS_ERR(dev)) { - watchdog_cdev_unregister(wdd); - return PTR_ERR(dev); - } - ret = watchdog_register_pretimeout(wdd); if (ret) { - device_destroy(&watchdog_class, devno); watchdog_cdev_unregister(wdd); } @@ -1050,7 +1044,6 @@ int watchdog_dev_register(struct watchdog_device *wdd) void watchdog_dev_unregister(struct watchdog_device *wdd) { watchdog_unregister_pretimeout(wdd); - device_destroy(&watchdog_class, wdd->wd_data->cdev.dev); watchdog_cdev_unregister(wdd); } From 18dc6fbbd9d7416b69cff63a1568365836ec22eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Sloth=20T=C3=B8nnesen?= Date: Fri, 22 May 2020 00:39:16 +0100 Subject: [PATCH 120/387] net: l2tp: export debug flags to UAPI commit 41c43fbee68f4f9a2a9675d83bca91c77862d7f0 upstream. Move the L2TP_MSG_* definitions to UAPI, as it is part of the netlink API. Signed-off-by: Asbjoern Sloth Toennesen Signed-off-by: David S. Miller Signed-off-by: Giuliano Procida Signed-off-by: Greg Kroah-Hartman --- include/uapi/linux/l2tp.h | 17 ++++++++++++++++- net/l2tp/l2tp_core.h | 10 ---------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/include/uapi/linux/l2tp.h b/include/uapi/linux/l2tp.h index 4bd27d0270a2..bb2d62037037 100644 --- a/include/uapi/linux/l2tp.h +++ b/include/uapi/linux/l2tp.h @@ -108,7 +108,7 @@ enum { L2TP_ATTR_VLAN_ID, /* u16 */ L2TP_ATTR_COOKIE, /* 0, 4 or 8 bytes */ L2TP_ATTR_PEER_COOKIE, /* 0, 4 or 8 bytes */ - L2TP_ATTR_DEBUG, /* u32 */ + L2TP_ATTR_DEBUG, /* u32, enum l2tp_debug_flags */ L2TP_ATTR_RECV_SEQ, /* u8 */ L2TP_ATTR_SEND_SEQ, /* u8 */ L2TP_ATTR_LNS_MODE, /* u8 */ @@ -175,6 +175,21 @@ enum l2tp_seqmode { L2TP_SEQ_ALL = 2, }; +/** + * enum l2tp_debug_flags - debug message categories for L2TP tunnels/sessions + * + * @L2TP_MSG_DEBUG: verbose debug (if compiled in) + * @L2TP_MSG_CONTROL: userspace - kernel interface + * @L2TP_MSG_SEQ: sequence numbers + * @L2TP_MSG_DATA: data packets + */ +enum l2tp_debug_flags { + L2TP_MSG_DEBUG = (1 << 0), + L2TP_MSG_CONTROL = (1 << 1), + L2TP_MSG_SEQ = (1 << 2), + L2TP_MSG_DATA = (1 << 3), +}; + /* * NETLINK_GENERIC related info */ diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h index 7c2037184b6c..092698a8f74b 100644 --- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h @@ -23,16 +23,6 @@ #define L2TP_HASH_BITS_2 8 #define L2TP_HASH_SIZE_2 (1 << L2TP_HASH_BITS_2) -/* Debug message categories for the DEBUG socket option */ -enum { - L2TP_MSG_DEBUG = (1 << 0), /* verbose debug (if - * compiled in) */ - L2TP_MSG_CONTROL = (1 << 1), /* userspace - kernel - * interface */ - L2TP_MSG_SEQ = (1 << 2), /* sequence numbers */ - L2TP_MSG_DATA = (1 << 3), /* data packets */ -}; - struct sk_buff; struct l2tp_stats { From cc84b4ddee15d4082da6653ea5548c04ff32057b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Sloth=20T=C3=B8nnesen?= Date: Fri, 22 May 2020 00:39:17 +0100 Subject: [PATCH 121/387] net: l2tp: deprecate PPPOL2TP_MSG_* in favour of L2TP_MSG_* commit 47c3e7783be4e142b861d34b5c2e223330b05d8a upstream. PPPOL2TP_MSG_* and L2TP_MSG_* are duplicates, and are being used interchangeably in the kernel, so let's standardize on L2TP_MSG_* internally, and keep PPPOL2TP_MSG_* defined in UAPI for compatibility. Signed-off-by: Asbjoern Sloth Toennesen Signed-off-by: David S. Miller Signed-off-by: Giuliano Procida Signed-off-by: Greg Kroah-Hartman --- Documentation/networking/l2tp.txt | 8 ++++---- include/uapi/linux/if_pppol2tp.h | 13 ++++++------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/Documentation/networking/l2tp.txt b/Documentation/networking/l2tp.txt index 4650a00ed012..9bc271cdc9a8 100644 --- a/Documentation/networking/l2tp.txt +++ b/Documentation/networking/l2tp.txt @@ -177,10 +177,10 @@ setsockopt on the PPPoX socket to set a debug mask. The following debug mask bits are available: -PPPOL2TP_MSG_DEBUG verbose debug (if compiled in) -PPPOL2TP_MSG_CONTROL userspace - kernel interface -PPPOL2TP_MSG_SEQ sequence numbers handling -PPPOL2TP_MSG_DATA data packets +L2TP_MSG_DEBUG verbose debug (if compiled in) +L2TP_MSG_CONTROL userspace - kernel interface +L2TP_MSG_SEQ sequence numbers handling +L2TP_MSG_DATA data packets If enabled, files under a l2tp debugfs directory can be used to dump kernel state about L2TP tunnels and sessions. To access it, the diff --git a/include/uapi/linux/if_pppol2tp.h b/include/uapi/linux/if_pppol2tp.h index 4bd1f55d6377..6418c4d10241 100644 --- a/include/uapi/linux/if_pppol2tp.h +++ b/include/uapi/linux/if_pppol2tp.h @@ -18,6 +18,7 @@ #include #include #include +#include /* Structure used to connect() the socket to a particular tunnel UDP * socket over IPv4. @@ -90,14 +91,12 @@ enum { PPPOL2TP_SO_REORDERTO = 5, }; -/* Debug message categories for the DEBUG socket option */ +/* Debug message categories for the DEBUG socket option (deprecated) */ enum { - PPPOL2TP_MSG_DEBUG = (1 << 0), /* verbose debug (if - * compiled in) */ - PPPOL2TP_MSG_CONTROL = (1 << 1), /* userspace - kernel - * interface */ - PPPOL2TP_MSG_SEQ = (1 << 2), /* sequence numbers */ - PPPOL2TP_MSG_DATA = (1 << 3), /* data packets */ + PPPOL2TP_MSG_DEBUG = L2TP_MSG_DEBUG, + PPPOL2TP_MSG_CONTROL = L2TP_MSG_CONTROL, + PPPOL2TP_MSG_SEQ = L2TP_MSG_SEQ, + PPPOL2TP_MSG_DATA = L2TP_MSG_DATA, }; From 6df792e20933d5ef670457d67a6bb9f497344bcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Sloth=20T=C3=B8nnesen?= Date: Fri, 22 May 2020 00:39:18 +0100 Subject: [PATCH 122/387] net: l2tp: ppp: change PPPOL2TP_MSG_* => L2TP_MSG_* commit fba40c632c6473fa89660e870a6042c0fe733f8c upstream. Signed-off-by: Asbjoern Sloth Toennesen Signed-off-by: David S. Miller Signed-off-by: Giuliano Procida Signed-off-by: Greg Kroah-Hartman --- net/l2tp/l2tp_ppp.c | 54 ++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index d919b3e6b548..809606f2d54a 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c @@ -231,14 +231,14 @@ static void pppol2tp_recv(struct l2tp_session *session, struct sk_buff *skb, int if (sk->sk_state & PPPOX_BOUND) { struct pppox_sock *po; - l2tp_dbg(session, PPPOL2TP_MSG_DATA, + l2tp_dbg(session, L2TP_MSG_DATA, "%s: recv %d byte data frame, passing to ppp\n", session->name, data_len); po = pppox_sk(sk); ppp_input(&po->chan, skb); } else { - l2tp_dbg(session, PPPOL2TP_MSG_DATA, + l2tp_dbg(session, L2TP_MSG_DATA, "%s: recv %d byte data frame, passing to L2TP socket\n", session->name, data_len); @@ -251,7 +251,7 @@ static void pppol2tp_recv(struct l2tp_session *session, struct sk_buff *skb, int return; no_sock: - l2tp_info(session, PPPOL2TP_MSG_DATA, "%s: no socket\n", session->name); + l2tp_info(session, L2TP_MSG_DATA, "%s: no socket\n", session->name); kfree_skb(skb); } @@ -782,7 +782,7 @@ out_no_ppp: /* This is how we get the session context from the socket. */ sk->sk_user_data = session; sk->sk_state = PPPOX_CONNECTED; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: created\n", + l2tp_info(session, L2TP_MSG_CONTROL, "%s: created\n", session->name); end: @@ -833,7 +833,7 @@ static int pppol2tp_session_create(struct net *net, u32 tunnel_id, u32 session_i ps = l2tp_session_priv(session); ps->tunnel_sock = tunnel->sock; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: created\n", + l2tp_info(session, L2TP_MSG_CONTROL, "%s: created\n", session->name); error = 0; @@ -995,7 +995,7 @@ static int pppol2tp_session_ioctl(struct l2tp_session *session, struct l2tp_tunnel *tunnel = session->tunnel; struct pppol2tp_ioc_stats stats; - l2tp_dbg(session, PPPOL2TP_MSG_CONTROL, + l2tp_dbg(session, L2TP_MSG_CONTROL, "%s: pppol2tp_session_ioctl(cmd=%#x, arg=%#lx)\n", session->name, cmd, arg); @@ -1018,7 +1018,7 @@ static int pppol2tp_session_ioctl(struct l2tp_session *session, if (copy_to_user((void __user *) arg, &ifr, sizeof(struct ifreq))) break; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: get mtu=%d\n", + l2tp_info(session, L2TP_MSG_CONTROL, "%s: get mtu=%d\n", session->name, session->mtu); err = 0; break; @@ -1034,7 +1034,7 @@ static int pppol2tp_session_ioctl(struct l2tp_session *session, session->mtu = ifr.ifr_mtu; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: set mtu=%d\n", + l2tp_info(session, L2TP_MSG_CONTROL, "%s: set mtu=%d\n", session->name, session->mtu); err = 0; break; @@ -1048,7 +1048,7 @@ static int pppol2tp_session_ioctl(struct l2tp_session *session, if (put_user(session->mru, (int __user *) arg)) break; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: get mru=%d\n", + l2tp_info(session, L2TP_MSG_CONTROL, "%s: get mru=%d\n", session->name, session->mru); err = 0; break; @@ -1063,7 +1063,7 @@ static int pppol2tp_session_ioctl(struct l2tp_session *session, break; session->mru = val; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: set mru=%d\n", + l2tp_info(session, L2TP_MSG_CONTROL, "%s: set mru=%d\n", session->name, session->mru); err = 0; break; @@ -1073,7 +1073,7 @@ static int pppol2tp_session_ioctl(struct l2tp_session *session, if (put_user(ps->flags, (int __user *) arg)) break; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: get flags=%d\n", + l2tp_info(session, L2TP_MSG_CONTROL, "%s: get flags=%d\n", session->name, ps->flags); err = 0; break; @@ -1083,7 +1083,7 @@ static int pppol2tp_session_ioctl(struct l2tp_session *session, if (get_user(val, (int __user *) arg)) break; ps->flags = val; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: set flags=%d\n", + l2tp_info(session, L2TP_MSG_CONTROL, "%s: set flags=%d\n", session->name, ps->flags); err = 0; break; @@ -1100,7 +1100,7 @@ static int pppol2tp_session_ioctl(struct l2tp_session *session, if (copy_to_user((void __user *) arg, &stats, sizeof(stats))) break; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: get L2TP stats\n", + l2tp_info(session, L2TP_MSG_CONTROL, "%s: get L2TP stats\n", session->name); err = 0; break; @@ -1128,7 +1128,7 @@ static int pppol2tp_tunnel_ioctl(struct l2tp_tunnel *tunnel, struct sock *sk; struct pppol2tp_ioc_stats stats; - l2tp_dbg(tunnel, PPPOL2TP_MSG_CONTROL, + l2tp_dbg(tunnel, L2TP_MSG_CONTROL, "%s: pppol2tp_tunnel_ioctl(cmd=%#x, arg=%#lx)\n", tunnel->name, cmd, arg); @@ -1171,7 +1171,7 @@ static int pppol2tp_tunnel_ioctl(struct l2tp_tunnel *tunnel, err = -EFAULT; break; } - l2tp_info(tunnel, PPPOL2TP_MSG_CONTROL, "%s: get L2TP stats\n", + l2tp_info(tunnel, L2TP_MSG_CONTROL, "%s: get L2TP stats\n", tunnel->name); err = 0; break; @@ -1261,7 +1261,7 @@ static int pppol2tp_tunnel_setsockopt(struct sock *sk, switch (optname) { case PPPOL2TP_SO_DEBUG: tunnel->debug = val; - l2tp_info(tunnel, PPPOL2TP_MSG_CONTROL, "%s: set debug=%x\n", + l2tp_info(tunnel, L2TP_MSG_CONTROL, "%s: set debug=%x\n", tunnel->name, tunnel->debug); break; @@ -1289,7 +1289,7 @@ static int pppol2tp_session_setsockopt(struct sock *sk, break; } session->recv_seq = val ? -1 : 0; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, + l2tp_info(session, L2TP_MSG_CONTROL, "%s: set recv_seq=%d\n", session->name, session->recv_seq); break; @@ -1307,7 +1307,7 @@ static int pppol2tp_session_setsockopt(struct sock *sk, PPPOL2TP_L2TP_HDR_SIZE_NOSEQ; } l2tp_session_set_header_len(session, session->tunnel->version); - l2tp_info(session, PPPOL2TP_MSG_CONTROL, + l2tp_info(session, L2TP_MSG_CONTROL, "%s: set send_seq=%d\n", session->name, session->send_seq); break; @@ -1318,20 +1318,20 @@ static int pppol2tp_session_setsockopt(struct sock *sk, break; } session->lns_mode = val ? -1 : 0; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, + l2tp_info(session, L2TP_MSG_CONTROL, "%s: set lns_mode=%d\n", session->name, session->lns_mode); break; case PPPOL2TP_SO_DEBUG: session->debug = val; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: set debug=%x\n", + l2tp_info(session, L2TP_MSG_CONTROL, "%s: set debug=%x\n", session->name, session->debug); break; case PPPOL2TP_SO_REORDERTO: session->reorder_timeout = msecs_to_jiffies(val); - l2tp_info(session, PPPOL2TP_MSG_CONTROL, + l2tp_info(session, L2TP_MSG_CONTROL, "%s: set reorder_timeout=%d\n", session->name, session->reorder_timeout); break; @@ -1412,7 +1412,7 @@ static int pppol2tp_tunnel_getsockopt(struct sock *sk, switch (optname) { case PPPOL2TP_SO_DEBUG: *val = tunnel->debug; - l2tp_info(tunnel, PPPOL2TP_MSG_CONTROL, "%s: get debug=%x\n", + l2tp_info(tunnel, L2TP_MSG_CONTROL, "%s: get debug=%x\n", tunnel->name, tunnel->debug); break; @@ -1435,31 +1435,31 @@ static int pppol2tp_session_getsockopt(struct sock *sk, switch (optname) { case PPPOL2TP_SO_RECVSEQ: *val = session->recv_seq; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, + l2tp_info(session, L2TP_MSG_CONTROL, "%s: get recv_seq=%d\n", session->name, *val); break; case PPPOL2TP_SO_SENDSEQ: *val = session->send_seq; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, + l2tp_info(session, L2TP_MSG_CONTROL, "%s: get send_seq=%d\n", session->name, *val); break; case PPPOL2TP_SO_LNSMODE: *val = session->lns_mode; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, + l2tp_info(session, L2TP_MSG_CONTROL, "%s: get lns_mode=%d\n", session->name, *val); break; case PPPOL2TP_SO_DEBUG: *val = session->debug; - l2tp_info(session, PPPOL2TP_MSG_CONTROL, "%s: get debug=%d\n", + l2tp_info(session, L2TP_MSG_CONTROL, "%s: get debug=%d\n", session->name, *val); break; case PPPOL2TP_SO_REORDERTO: *val = (int) jiffies_to_msecs(session->reorder_timeout); - l2tp_info(session, PPPOL2TP_MSG_CONTROL, + l2tp_info(session, L2TP_MSG_CONTROL, "%s: get reorder_timeout=%d\n", session->name, *val); break; From b25415f9f0d539c587a80a608c3e2211f1c079af Mon Sep 17 00:00:00 2001 From: "R. Parameswaran" Date: Fri, 22 May 2020 00:39:19 +0100 Subject: [PATCH 123/387] New kernel function to get IP overhead on a socket. commit 113c3075931a334f899008f6c753abe70a3a9323 upstream. A new function, kernel_sock_ip_overhead(), is provided to calculate the cumulative overhead imposed by the IP Header and IP options, if any, on a socket's payload. The new function returns an overhead of zero for sockets that do not belong to the IPv4 or IPv6 address families. This is used in the L2TP code path to compute the total outer IP overhead on the L2TP tunnel socket when calculating the default MTU for Ethernet pseudowires. Signed-off-by: R. Parameswaran Signed-off-by: David S. Miller Signed-off-by: Giuliano Procida Signed-off-by: Greg Kroah-Hartman --- include/linux/net.h | 3 +++ net/socket.c | 46 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/include/linux/net.h b/include/linux/net.h index cd0c8bd0a1de..2c8b092f3f17 100644 --- a/include/linux/net.h +++ b/include/linux/net.h @@ -298,6 +298,9 @@ int kernel_sendpage(struct socket *sock, struct page *page, int offset, int kernel_sock_ioctl(struct socket *sock, int cmd, unsigned long arg); int kernel_sock_shutdown(struct socket *sock, enum sock_shutdown_cmd how); +/* Following routine returns the IP overhead imposed by a socket. */ +u32 kernel_sock_ip_overhead(struct sock *sk); + #define MODULE_ALIAS_NETPROTO(proto) \ MODULE_ALIAS("net-pf-" __stringify(proto)) diff --git a/net/socket.c b/net/socket.c index 65afc8ec68d4..4892719a8a66 100644 --- a/net/socket.c +++ b/net/socket.c @@ -3321,3 +3321,49 @@ int kernel_sock_shutdown(struct socket *sock, enum sock_shutdown_cmd how) return sock->ops->shutdown(sock, how); } EXPORT_SYMBOL(kernel_sock_shutdown); + +/* This routine returns the IP overhead imposed by a socket i.e. + * the length of the underlying IP header, depending on whether + * this is an IPv4 or IPv6 socket and the length from IP options turned + * on at the socket. + */ +u32 kernel_sock_ip_overhead(struct sock *sk) +{ + struct inet_sock *inet; + struct ip_options_rcu *opt; + u32 overhead = 0; + bool owned_by_user; +#if IS_ENABLED(CONFIG_IPV6) + struct ipv6_pinfo *np; + struct ipv6_txoptions *optv6 = NULL; +#endif /* IS_ENABLED(CONFIG_IPV6) */ + + if (!sk) + return overhead; + + owned_by_user = sock_owned_by_user(sk); + switch (sk->sk_family) { + case AF_INET: + inet = inet_sk(sk); + overhead += sizeof(struct iphdr); + opt = rcu_dereference_protected(inet->inet_opt, + owned_by_user); + if (opt) + overhead += opt->opt.optlen; + return overhead; +#if IS_ENABLED(CONFIG_IPV6) + case AF_INET6: + np = inet6_sk(sk); + overhead += sizeof(struct ipv6hdr); + if (np) + optv6 = rcu_dereference_protected(np->opt, + owned_by_user); + if (optv6) + overhead += (optv6->opt_flen + optv6->opt_nflen); + return overhead; +#endif /* IS_ENABLED(CONFIG_IPV6) */ + default: /* Returns 0 overhead if the socket is not ipv4 or ipv6 */ + return overhead; + } +} +EXPORT_SYMBOL(kernel_sock_ip_overhead); From fa5b41cda1bede3df441ccc3ab2a3cbcc0eb153b Mon Sep 17 00:00:00 2001 From: "R. Parameswaran" Date: Fri, 22 May 2020 00:39:20 +0100 Subject: [PATCH 124/387] L2TP:Adjust intf MTU, add underlay L3, L2 hdrs. commit b784e7ebfce8cfb16c6f95e14e8532d0768ab7ff upstream. Existing L2TP kernel code does not derive the optimal MTU for Ethernet pseudowires and instead leaves this to a userspace L2TP daemon or operator. If an MTU is not specified, the existing kernel code chooses an MTU that does not take account of all tunnel header overheads, which can lead to unwanted IP fragmentation. When L2TP is used without a control plane (userspace daemon), we would prefer that the kernel does a better job of choosing a default pseudowire MTU, taking account of all tunnel header overheads, including IP header options, if any. This patch addresses this. Change-set here uses the new kernel function, kernel_sock_ip_overhead(), to factor the outer IP overhead on the L2TP tunnel socket (including IP Options, if any) when calculating the default MTU for an Ethernet pseudowire, along with consideration of the inner Ethernet header. Signed-off-by: R. Parameswaran Signed-off-by: David S. Miller Signed-off-by: Giuliano Procida Signed-off-by: Greg Kroah-Hartman --- net/l2tp/l2tp_eth.c | 55 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index eecc64e138de..f0efbf1e9a49 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c @@ -30,6 +30,9 @@ #include #include #include +#include +#include +#include #include "l2tp_core.h" @@ -206,6 +209,53 @@ static void l2tp_eth_show(struct seq_file *m, void *arg) } #endif +static void l2tp_eth_adjust_mtu(struct l2tp_tunnel *tunnel, + struct l2tp_session *session, + struct net_device *dev) +{ + unsigned int overhead = 0; + struct dst_entry *dst; + u32 l3_overhead = 0; + + /* if the encap is UDP, account for UDP header size */ + if (tunnel->encap == L2TP_ENCAPTYPE_UDP) { + overhead += sizeof(struct udphdr); + dev->needed_headroom += sizeof(struct udphdr); + } + if (session->mtu != 0) { + dev->mtu = session->mtu; + dev->needed_headroom += session->hdr_len; + return; + } + l3_overhead = kernel_sock_ip_overhead(tunnel->sock); + if (l3_overhead == 0) { + /* L3 Overhead couldn't be identified, this could be + * because tunnel->sock was NULL or the socket's + * address family was not IPv4 or IPv6, + * dev mtu stays at 1500. + */ + return; + } + /* Adjust MTU, factor overhead - underlay L3, overlay L2 hdr + * UDP overhead, if any, was already factored in above. + */ + overhead += session->hdr_len + ETH_HLEN + l3_overhead; + + /* If PMTU discovery was enabled, use discovered MTU on L2TP device */ + dst = sk_dst_get(tunnel->sock); + if (dst) { + /* dst_mtu will use PMTU if found, else fallback to intf MTU */ + u32 pmtu = dst_mtu(dst); + + if (pmtu != 0) + dev->mtu = pmtu; + dst_release(dst); + } + session->mtu = dev->mtu - overhead; + dev->mtu = session->mtu; + dev->needed_headroom += session->hdr_len; +} + static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg) { struct net_device *dev; @@ -249,10 +299,7 @@ static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 p } dev_net_set(dev, net); - if (session->mtu == 0) - session->mtu = dev->mtu - session->hdr_len; - dev->mtu = session->mtu; - dev->needed_headroom += session->hdr_len; + l2tp_eth_adjust_mtu(tunnel, session, dev); priv = netdev_priv(dev); priv->dev = dev; From 6729e7334c230a08eac5c55e5c0ee81952df5ba8 Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Fri, 22 May 2020 00:39:21 +0100 Subject: [PATCH 125/387] l2tp: remove useless duplicate session detection in l2tp_netlink commit af87ae465abdc070de0dc35d6c6a9e7a8cd82987 upstream. There's no point in checking for duplicate sessions at the beginning of l2tp_nl_cmd_session_create(); the ->session_create() callbacks already return -EEXIST when the session already exists. Furthermore, even if l2tp_session_find() returns NULL, a new session might be created right after the test. So relying on ->session_create() to avoid duplicate session is the only sane behaviour. Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller Signed-off-by: Giuliano Procida Signed-off-by: Greg Kroah-Hartman --- net/l2tp/l2tp_netlink.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c index d6fccfdca201..36651b60d776 100644 --- a/net/l2tp/l2tp_netlink.c +++ b/net/l2tp/l2tp_netlink.c @@ -513,11 +513,6 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf goto out; } session_id = nla_get_u32(info->attrs[L2TP_ATTR_SESSION_ID]); - session = l2tp_session_find(net, tunnel, session_id); - if (session) { - ret = -EEXIST; - goto out; - } if (!info->attrs[L2TP_ATTR_PEER_SESSION_ID]) { ret = -EINVAL; From e27738d0c5b109f07998f35548ba0a622f156693 Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Fri, 22 May 2020 00:39:22 +0100 Subject: [PATCH 126/387] l2tp: remove l2tp_session_find() commit 55a3ce3b9d98f752df9e2cfb1cba7e715522428a upstream. This function isn't used anymore. Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller Signed-off-by: Giuliano Procida Signed-off-by: Greg Kroah-Hartman --- net/l2tp/l2tp_core.c | 51 +------------------------------------------- net/l2tp/l2tp_core.h | 3 --- 2 files changed, 1 insertion(+), 53 deletions(-) diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 7c3da29fad8e..440065462a69 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -216,27 +216,6 @@ static void l2tp_tunnel_sock_put(struct sock *sk) sock_put(sk); } -/* Lookup a session by id in the global session list - */ -static struct l2tp_session *l2tp_session_find_2(struct net *net, u32 session_id) -{ - struct l2tp_net *pn = l2tp_pernet(net); - struct hlist_head *session_list = - l2tp_session_id_hash_2(pn, session_id); - struct l2tp_session *session; - - rcu_read_lock_bh(); - hlist_for_each_entry_rcu(session, session_list, global_hlist) { - if (session->session_id == session_id) { - rcu_read_unlock_bh(); - return session; - } - } - rcu_read_unlock_bh(); - - return NULL; -} - /* Session hash list. * The session_id SHOULD be random according to RFC2661, but several * L2TP implementations (Cisco and Microsoft) use incrementing @@ -249,35 +228,7 @@ l2tp_session_id_hash(struct l2tp_tunnel *tunnel, u32 session_id) return &tunnel->session_hlist[hash_32(session_id, L2TP_HASH_BITS)]; } -/* Lookup a session by id - */ -struct l2tp_session *l2tp_session_find(struct net *net, struct l2tp_tunnel *tunnel, u32 session_id) -{ - struct hlist_head *session_list; - struct l2tp_session *session; - - /* In L2TPv3, session_ids are unique over all tunnels and we - * sometimes need to look them up before we know the - * tunnel. - */ - if (tunnel == NULL) - return l2tp_session_find_2(net, session_id); - - session_list = l2tp_session_id_hash(tunnel, session_id); - read_lock_bh(&tunnel->hlist_lock); - hlist_for_each_entry(session, session_list, hlist) { - if (session->session_id == session_id) { - read_unlock_bh(&tunnel->hlist_lock); - return session; - } - } - read_unlock_bh(&tunnel->hlist_lock); - - return NULL; -} -EXPORT_SYMBOL_GPL(l2tp_session_find); - -/* Like l2tp_session_find() but takes a reference on the returned session. +/* Lookup a session. A new reference is held on the returned session. * Optionally calls session->ref() too if do_ref is true. */ struct l2tp_session *l2tp_session_get(struct net *net, diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h index 092698a8f74b..e38db6a807f5 100644 --- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h @@ -234,9 +234,6 @@ out: struct l2tp_session *l2tp_session_get(struct net *net, struct l2tp_tunnel *tunnel, u32 session_id, bool do_ref); -struct l2tp_session *l2tp_session_find(struct net *net, - struct l2tp_tunnel *tunnel, - u32 session_id); struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth, bool do_ref); struct l2tp_session *l2tp_session_get_by_ifname(struct net *net, char *ifname, From eb61cabde73d8824145bcd7dec729987a50baa27 Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Fri, 22 May 2020 00:39:23 +0100 Subject: [PATCH 127/387] l2tp: define parameters of l2tp_session_get*() as "const" commit 9aaef50c44f132e040dcd7686c8e78a3390037c5 upstream. Make l2tp_pernet()'s parameter constant, so that l2tp_session_get*() can declare their "net" variable as "const". Also constify "ifname" in l2tp_session_get_by_ifname(). Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller Signed-off-by: Giuliano Procida Signed-off-by: Greg Kroah-Hartman --- net/l2tp/l2tp_core.c | 7 ++++--- net/l2tp/l2tp_core.h | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 440065462a69..be8d7b2b8790 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -119,7 +119,7 @@ static inline struct l2tp_tunnel *l2tp_tunnel(struct sock *sk) return sk->sk_user_data; } -static inline struct l2tp_net *l2tp_pernet(struct net *net) +static inline struct l2tp_net *l2tp_pernet(const struct net *net) { BUG_ON(!net); @@ -231,7 +231,7 @@ l2tp_session_id_hash(struct l2tp_tunnel *tunnel, u32 session_id) /* Lookup a session. A new reference is held on the returned session. * Optionally calls session->ref() too if do_ref is true. */ -struct l2tp_session *l2tp_session_get(struct net *net, +struct l2tp_session *l2tp_session_get(const struct net *net, struct l2tp_tunnel *tunnel, u32 session_id, bool do_ref) { @@ -306,7 +306,8 @@ EXPORT_SYMBOL_GPL(l2tp_session_get_nth); /* Lookup a session by interface name. * This is very inefficient but is only used by management interfaces. */ -struct l2tp_session *l2tp_session_get_by_ifname(struct net *net, char *ifname, +struct l2tp_session *l2tp_session_get_by_ifname(const struct net *net, + const char *ifname, bool do_ref) { struct l2tp_net *pn = l2tp_pernet(net); diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h index e38db6a807f5..3a3d96df6071 100644 --- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h @@ -231,12 +231,13 @@ out: return tunnel; } -struct l2tp_session *l2tp_session_get(struct net *net, +struct l2tp_session *l2tp_session_get(const struct net *net, struct l2tp_tunnel *tunnel, u32 session_id, bool do_ref); struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth, bool do_ref); -struct l2tp_session *l2tp_session_get_by_ifname(struct net *net, char *ifname, +struct l2tp_session *l2tp_session_get_by_ifname(const struct net *net, + const char *ifname, bool do_ref); struct l2tp_tunnel *l2tp_tunnel_find(struct net *net, u32 tunnel_id); struct l2tp_tunnel *l2tp_tunnel_find_nth(struct net *net, int nth); From d4504d1eba9563ca60bf87194a68faee1e6fa11e Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Fri, 22 May 2020 00:39:24 +0100 Subject: [PATCH 128/387] l2tp: define parameters of l2tp_tunnel_find*() as "const" commit 2f858b928bf5a8174911aaec76b8b72a9ca0533d upstream. l2tp_tunnel_find() and l2tp_tunnel_find_nth() don't modify "net". Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller Signed-off-by: Giuliano Procida Signed-off-by: Greg Kroah-Hartman --- net/l2tp/l2tp_core.c | 4 ++-- net/l2tp/l2tp_core.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index be8d7b2b8790..a9d4d42e2ef6 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -378,7 +378,7 @@ exist: /* Lookup a tunnel by id */ -struct l2tp_tunnel *l2tp_tunnel_find(struct net *net, u32 tunnel_id) +struct l2tp_tunnel *l2tp_tunnel_find(const struct net *net, u32 tunnel_id) { struct l2tp_tunnel *tunnel; struct l2tp_net *pn = l2tp_pernet(net); @@ -396,7 +396,7 @@ struct l2tp_tunnel *l2tp_tunnel_find(struct net *net, u32 tunnel_id) } EXPORT_SYMBOL_GPL(l2tp_tunnel_find); -struct l2tp_tunnel *l2tp_tunnel_find_nth(struct net *net, int nth) +struct l2tp_tunnel *l2tp_tunnel_find_nth(const struct net *net, int nth) { struct l2tp_net *pn = l2tp_pernet(net); struct l2tp_tunnel *tunnel; diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h index 3a3d96df6071..2f9a09097e30 100644 --- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h @@ -239,8 +239,8 @@ struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth, struct l2tp_session *l2tp_session_get_by_ifname(const struct net *net, const char *ifname, bool do_ref); -struct l2tp_tunnel *l2tp_tunnel_find(struct net *net, u32 tunnel_id); -struct l2tp_tunnel *l2tp_tunnel_find_nth(struct net *net, int nth); +struct l2tp_tunnel *l2tp_tunnel_find(const struct net *net, u32 tunnel_id); +struct l2tp_tunnel *l2tp_tunnel_find_nth(const struct net *net, int nth); int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32 peer_tunnel_id, struct l2tp_tunnel_cfg *cfg, From 11a083724be9f877e9490b7c807cd897b9e6819d Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Fri, 22 May 2020 00:39:25 +0100 Subject: [PATCH 129/387] l2tp: initialise session's refcount before making it reachable commit 9ee369a405c57613d7c83a3967780c3e30c52ecc upstream. Sessions must be fully initialised before calling l2tp_session_add_to_tunnel(). Otherwise, there's a short time frame where partially initialised sessions can be accessed by external users. Backporting Notes l2tp_core.c: moving code that had been converted from atomic to refcount_t by an earlier change (which isn't being included in this patch series). Fixes: dbdbc73b4478 ("l2tp: fix duplicate session creation") Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller Signed-off-by: Giuliano Procida Signed-off-by: Greg Kroah-Hartman --- net/l2tp/l2tp_core.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index a9d4d42e2ef6..7f72957405b8 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -1847,6 +1847,8 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn l2tp_session_set_header_len(session, tunnel->version); + l2tp_session_inc_refcount(session); + err = l2tp_session_add_to_tunnel(tunnel, session); if (err) { kfree(session); @@ -1854,10 +1856,6 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn return ERR_PTR(err); } - /* Bump the reference count. The session context is deleted - * only when this drops to zero. - */ - l2tp_session_inc_refcount(session); l2tp_tunnel_inc_refcount(tunnel); /* Ensure tunnel socket isn't deleted */ From 523e6d7f31868172536d63280a6d10d2d5a94e95 Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Fri, 22 May 2020 00:39:26 +0100 Subject: [PATCH 130/387] l2tp: hold tunnel while looking up sessions in l2tp_netlink commit 54652eb12c1b72e9602d09cb2821d5760939190f upstream. l2tp_tunnel_find() doesn't take a reference on the returned tunnel. Therefore, it's unsafe to use it because the returned tunnel can go away on us anytime. Fix this by defining l2tp_tunnel_get(), which works like l2tp_tunnel_find(), but takes a reference on the returned tunnel. Caller then has to drop this reference using l2tp_tunnel_dec_refcount(). As l2tp_tunnel_dec_refcount() needs to be moved to l2tp_core.h, let's simplify the patch and not move the L2TP_REFCNT_DEBUG part. This code has been broken (not even compiling) in May 2012 by commit a4ca44fa578c ("net: l2tp: Standardize logging styles") and fixed more than two years later by commit 29abe2fda54f ("l2tp: fix missing line continuation"). So it doesn't appear to be used by anyone. Same thing for l2tp_tunnel_free(); instead of moving it to l2tp_core.h, let's just simplify things and call kfree_rcu() directly in l2tp_tunnel_dec_refcount(). Extra assertions and debugging code provided by l2tp_tunnel_free() didn't help catching any of the reference counting and socket handling issues found while working on this series. Backporting Notes l2tp_core.c: This patch deletes some code / moves some code to l2tp_core.h and follows the patch (not including in this series) that switched from atomic to refcount_t. Moved code changed back to atomic. Fixes: 309795f4bec2 ("l2tp: Add netlink control API for L2TP") Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller Signed-off-by: Giuliano Procida Signed-off-by: Greg Kroah-Hartman --- net/l2tp/l2tp_core.c | 66 +++++++++++++---------------------------- net/l2tp/l2tp_core.h | 13 ++++++++ net/l2tp/l2tp_netlink.c | 6 ++-- 3 files changed, 38 insertions(+), 47 deletions(-) diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 7f72957405b8..5d1eb253a0b1 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -112,7 +112,6 @@ struct l2tp_net { spinlock_t l2tp_session_hlist_lock; }; -static void l2tp_tunnel_free(struct l2tp_tunnel *tunnel); static inline struct l2tp_tunnel *l2tp_tunnel(struct sock *sk) { @@ -126,39 +125,6 @@ static inline struct l2tp_net *l2tp_pernet(const struct net *net) return net_generic(net, l2tp_net_id); } -/* Tunnel reference counts. Incremented per session that is added to - * the tunnel. - */ -static inline void l2tp_tunnel_inc_refcount_1(struct l2tp_tunnel *tunnel) -{ - atomic_inc(&tunnel->ref_count); -} - -static inline void l2tp_tunnel_dec_refcount_1(struct l2tp_tunnel *tunnel) -{ - if (atomic_dec_and_test(&tunnel->ref_count)) - l2tp_tunnel_free(tunnel); -} -#ifdef L2TP_REFCNT_DEBUG -#define l2tp_tunnel_inc_refcount(_t) \ -do { \ - pr_debug("l2tp_tunnel_inc_refcount: %s:%d %s: cnt=%d\n", \ - __func__, __LINE__, (_t)->name, \ - atomic_read(&_t->ref_count)); \ - l2tp_tunnel_inc_refcount_1(_t); \ -} while (0) -#define l2tp_tunnel_dec_refcount(_t) \ -do { \ - pr_debug("l2tp_tunnel_dec_refcount: %s:%d %s: cnt=%d\n", \ - __func__, __LINE__, (_t)->name, \ - atomic_read(&_t->ref_count)); \ - l2tp_tunnel_dec_refcount_1(_t); \ -} while (0) -#else -#define l2tp_tunnel_inc_refcount(t) l2tp_tunnel_inc_refcount_1(t) -#define l2tp_tunnel_dec_refcount(t) l2tp_tunnel_dec_refcount_1(t) -#endif - /* Session hash global list for L2TPv3. * The session_id SHOULD be random according to RFC3931, but several * L2TP implementations use incrementing session_ids. So we do a real @@ -228,6 +194,27 @@ l2tp_session_id_hash(struct l2tp_tunnel *tunnel, u32 session_id) return &tunnel->session_hlist[hash_32(session_id, L2TP_HASH_BITS)]; } +/* Lookup a tunnel. A new reference is held on the returned tunnel. */ +struct l2tp_tunnel *l2tp_tunnel_get(const struct net *net, u32 tunnel_id) +{ + const struct l2tp_net *pn = l2tp_pernet(net); + struct l2tp_tunnel *tunnel; + + rcu_read_lock_bh(); + list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) { + if (tunnel->tunnel_id == tunnel_id) { + l2tp_tunnel_inc_refcount(tunnel); + rcu_read_unlock_bh(); + + return tunnel; + } + } + rcu_read_unlock_bh(); + + return NULL; +} +EXPORT_SYMBOL_GPL(l2tp_tunnel_get); + /* Lookup a session. A new reference is held on the returned session. * Optionally calls session->ref() too if do_ref is true. */ @@ -1346,17 +1333,6 @@ static void l2tp_udp_encap_destroy(struct sock *sk) } } -/* Really kill the tunnel. - * Come here only when all sessions have been cleared from the tunnel. - */ -static void l2tp_tunnel_free(struct l2tp_tunnel *tunnel) -{ - BUG_ON(atomic_read(&tunnel->ref_count) != 0); - BUG_ON(tunnel->sock != NULL); - l2tp_info(tunnel, L2TP_MSG_CONTROL, "%s: free...\n", tunnel->name); - kfree_rcu(tunnel, rcu); -} - /* Workqueue tunnel deletion function */ static void l2tp_tunnel_del_work(struct work_struct *work) { diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h index 2f9a09097e30..f747deaf6e09 100644 --- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h @@ -231,6 +231,8 @@ out: return tunnel; } +struct l2tp_tunnel *l2tp_tunnel_get(const struct net *net, u32 tunnel_id); + struct l2tp_session *l2tp_session_get(const struct net *net, struct l2tp_tunnel *tunnel, u32 session_id, bool do_ref); @@ -269,6 +271,17 @@ int l2tp_nl_register_ops(enum l2tp_pwtype pw_type, void l2tp_nl_unregister_ops(enum l2tp_pwtype pw_type); int l2tp_ioctl(struct sock *sk, int cmd, unsigned long arg); +static inline void l2tp_tunnel_inc_refcount(struct l2tp_tunnel *tunnel) +{ + atomic_inc(&tunnel->ref_count); +} + +static inline void l2tp_tunnel_dec_refcount(struct l2tp_tunnel *tunnel) +{ + if (atomic_dec_and_test(&tunnel->ref_count)) + kfree_rcu(tunnel, rcu); +} + /* Session reference counts. Incremented when code obtains a reference * to a session. */ diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c index 36651b60d776..0a27f7e976f3 100644 --- a/net/l2tp/l2tp_netlink.c +++ b/net/l2tp/l2tp_netlink.c @@ -72,10 +72,12 @@ static struct l2tp_session *l2tp_nl_session_get(struct genl_info *info, (info->attrs[L2TP_ATTR_CONN_ID])) { tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]); session_id = nla_get_u32(info->attrs[L2TP_ATTR_SESSION_ID]); - tunnel = l2tp_tunnel_find(net, tunnel_id); - if (tunnel) + tunnel = l2tp_tunnel_get(net, tunnel_id); + if (tunnel) { session = l2tp_session_get(net, tunnel, session_id, do_ref); + l2tp_tunnel_dec_refcount(tunnel); + } } return session; From 0b21fa707d1fc1b229020c468fefa0aa46d9e266 Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Fri, 22 May 2020 00:39:27 +0100 Subject: [PATCH 131/387] l2tp: hold tunnel while processing genl delete command commit bb0a32ce4389e17e47e198d2cddaf141561581ad upstream. l2tp_nl_cmd_tunnel_delete() needs to take a reference on the tunnel, to prevent it from being concurrently freed by l2tp_tunnel_destruct(). Fixes: 309795f4bec2 ("l2tp: Add netlink control API for L2TP") Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller Signed-off-by: Giuliano Procida Signed-off-by: Greg Kroah-Hartman --- net/l2tp/l2tp_netlink.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c index 0a27f7e976f3..93148a215e7c 100644 --- a/net/l2tp/l2tp_netlink.c +++ b/net/l2tp/l2tp_netlink.c @@ -280,8 +280,8 @@ static int l2tp_nl_cmd_tunnel_delete(struct sk_buff *skb, struct genl_info *info } tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]); - tunnel = l2tp_tunnel_find(net, tunnel_id); - if (tunnel == NULL) { + tunnel = l2tp_tunnel_get(net, tunnel_id); + if (!tunnel) { ret = -ENODEV; goto out; } @@ -291,6 +291,8 @@ static int l2tp_nl_cmd_tunnel_delete(struct sk_buff *skb, struct genl_info *info l2tp_tunnel_delete(tunnel); + l2tp_tunnel_dec_refcount(tunnel); + out: return ret; } From 00cf4055d5a14584833a2b355d846a56f74ce96b Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Fri, 22 May 2020 00:39:28 +0100 Subject: [PATCH 132/387] l2tp: hold tunnel while handling genl tunnel updates commit 8c0e421525c9eb50d68e8f633f703ca31680b746 upstream. We need to make sure the tunnel is not going to be destroyed by l2tp_tunnel_destruct() concurrently. Fixes: 309795f4bec2 ("l2tp: Add netlink control API for L2TP") Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller Signed-off-by: Giuliano Procida Signed-off-by: Greg Kroah-Hartman --- net/l2tp/l2tp_netlink.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c index 93148a215e7c..e454f23f31fb 100644 --- a/net/l2tp/l2tp_netlink.c +++ b/net/l2tp/l2tp_netlink.c @@ -310,8 +310,8 @@ static int l2tp_nl_cmd_tunnel_modify(struct sk_buff *skb, struct genl_info *info } tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]); - tunnel = l2tp_tunnel_find(net, tunnel_id); - if (tunnel == NULL) { + tunnel = l2tp_tunnel_get(net, tunnel_id); + if (!tunnel) { ret = -ENODEV; goto out; } @@ -322,6 +322,8 @@ static int l2tp_nl_cmd_tunnel_modify(struct sk_buff *skb, struct genl_info *info ret = l2tp_tunnel_notify(&l2tp_nl_family, info, tunnel, L2TP_CMD_TUNNEL_MODIFY); + l2tp_tunnel_dec_refcount(tunnel); + out: return ret; } From 4c15cdb962d27d5b095fd444156c0746993df377 Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Fri, 22 May 2020 00:39:29 +0100 Subject: [PATCH 133/387] l2tp: hold tunnel while handling genl TUNNEL_GET commands commit 4e4b21da3acc68a7ea55f850cacc13706b7480e9 upstream. Use l2tp_tunnel_get() instead of l2tp_tunnel_find() so that we get a reference on the tunnel, preventing l2tp_tunnel_destruct() from freeing it from under us. Also move l2tp_tunnel_get() below nlmsg_new() so that we only take the reference when needed. Fixes: 309795f4bec2 ("l2tp: Add netlink control API for L2TP") Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller Signed-off-by: Giuliano Procida Signed-off-by: Greg Kroah-Hartman --- net/l2tp/l2tp_netlink.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c index e454f23f31fb..8f39086de144 100644 --- a/net/l2tp/l2tp_netlink.c +++ b/net/l2tp/l2tp_netlink.c @@ -436,34 +436,37 @@ static int l2tp_nl_cmd_tunnel_get(struct sk_buff *skb, struct genl_info *info) if (!info->attrs[L2TP_ATTR_CONN_ID]) { ret = -EINVAL; - goto out; + goto err; } tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]); - tunnel = l2tp_tunnel_find(net, tunnel_id); - if (tunnel == NULL) { - ret = -ENODEV; - goto out; - } - msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) { ret = -ENOMEM; - goto out; + goto err; + } + + tunnel = l2tp_tunnel_get(net, tunnel_id); + if (!tunnel) { + ret = -ENODEV; + goto err_nlmsg; } ret = l2tp_nl_tunnel_send(msg, info->snd_portid, info->snd_seq, NLM_F_ACK, tunnel, L2TP_CMD_TUNNEL_GET); if (ret < 0) - goto err_out; + goto err_nlmsg_tunnel; + + l2tp_tunnel_dec_refcount(tunnel); return genlmsg_unicast(net, msg, info->snd_portid); -err_out: +err_nlmsg_tunnel: + l2tp_tunnel_dec_refcount(tunnel); +err_nlmsg: nlmsg_free(msg); - -out: +err: return ret; } From e20c980a2bf6991507d70ff7d221af394db07c76 Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Fri, 22 May 2020 00:39:30 +0100 Subject: [PATCH 134/387] l2tp: hold tunnel used while creating sessions with netlink commit e702c1204eb57788ef189c839c8c779368267d70 upstream. Use l2tp_tunnel_get() to retrieve tunnel, so that it can't go away on us. Otherwise l2tp_tunnel_destruct() might release the last reference count concurrently, thus freeing the tunnel while we're using it. Fixes: 309795f4bec2 ("l2tp: Add netlink control API for L2TP") Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller Signed-off-by: Giuliano Procida Signed-off-by: Greg Kroah-Hartman --- net/l2tp/l2tp_netlink.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c index 8f39086de144..5ea5d3ffa309 100644 --- a/net/l2tp/l2tp_netlink.c +++ b/net/l2tp/l2tp_netlink.c @@ -510,8 +510,9 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf ret = -EINVAL; goto out; } + tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]); - tunnel = l2tp_tunnel_find(net, tunnel_id); + tunnel = l2tp_tunnel_get(net, tunnel_id); if (!tunnel) { ret = -ENODEV; goto out; @@ -519,24 +520,24 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf if (!info->attrs[L2TP_ATTR_SESSION_ID]) { ret = -EINVAL; - goto out; + goto out_tunnel; } session_id = nla_get_u32(info->attrs[L2TP_ATTR_SESSION_ID]); if (!info->attrs[L2TP_ATTR_PEER_SESSION_ID]) { ret = -EINVAL; - goto out; + goto out_tunnel; } peer_session_id = nla_get_u32(info->attrs[L2TP_ATTR_PEER_SESSION_ID]); if (!info->attrs[L2TP_ATTR_PW_TYPE]) { ret = -EINVAL; - goto out; + goto out_tunnel; } cfg.pw_type = nla_get_u16(info->attrs[L2TP_ATTR_PW_TYPE]); if (cfg.pw_type >= __L2TP_PWTYPE_MAX) { ret = -EINVAL; - goto out; + goto out_tunnel; } if (tunnel->version > 2) { @@ -555,7 +556,7 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf u16 len = nla_len(info->attrs[L2TP_ATTR_COOKIE]); if (len > 8) { ret = -EINVAL; - goto out; + goto out_tunnel; } cfg.cookie_len = len; memcpy(&cfg.cookie[0], nla_data(info->attrs[L2TP_ATTR_COOKIE]), len); @@ -564,7 +565,7 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf u16 len = nla_len(info->attrs[L2TP_ATTR_PEER_COOKIE]); if (len > 8) { ret = -EINVAL; - goto out; + goto out_tunnel; } cfg.peer_cookie_len = len; memcpy(&cfg.peer_cookie[0], nla_data(info->attrs[L2TP_ATTR_PEER_COOKIE]), len); @@ -607,7 +608,7 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf if ((l2tp_nl_cmd_ops[cfg.pw_type] == NULL) || (l2tp_nl_cmd_ops[cfg.pw_type]->session_create == NULL)) { ret = -EPROTONOSUPPORT; - goto out; + goto out_tunnel; } /* Check that pseudowire-specific params are present */ @@ -617,7 +618,7 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf case L2TP_PWTYPE_ETH_VLAN: if (!info->attrs[L2TP_ATTR_VLAN_ID]) { ret = -EINVAL; - goto out; + goto out_tunnel; } break; case L2TP_PWTYPE_ETH: @@ -645,6 +646,8 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf } } +out_tunnel: + l2tp_tunnel_dec_refcount(tunnel); out: return ret; } From 880cd40d130cf08df6e1be87e5e8a082cac60cda Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Fri, 22 May 2020 00:39:31 +0100 Subject: [PATCH 135/387] l2tp: prevent creation of sessions on terminated tunnels commit f3c66d4e144a0904ea9b95d23ed9f8eb38c11bfb upstream. l2tp_tunnel_destruct() sets tunnel->sock to NULL, then removes the tunnel from the pernet list and finally closes all its sessions. Therefore, it's possible to add a session to a tunnel that is still reachable, but for which tunnel->sock has already been reset. This can make l2tp_session_create() dereference a NULL pointer when calling sock_hold(tunnel->sock). This patch adds the .acpt_newsess field to struct l2tp_tunnel, which is used by l2tp_tunnel_closeall() to prevent addition of new sessions to tunnels. Resetting tunnel->sock is done after l2tp_tunnel_closeall() returned, so that l2tp_session_add_to_tunnel() can safely take a reference on it when .acpt_newsess is true. The .acpt_newsess field is modified in l2tp_tunnel_closeall(), rather than in l2tp_tunnel_destruct(), so that it benefits all tunnel removal mechanisms. E.g. on UDP tunnels, a session could be added to a tunnel after l2tp_udp_encap_destroy() proceeded. This would prevent the tunnel from being removed because of the references held by this new session on the tunnel and its socket. Even though the session could be removed manually later on, this defeats the purpose of commit 9980d001cec8 ("l2tp: add udp encap socket destroy handler"). Fixes: fd558d186df2 ("l2tp: Split pppol2tp patch into separate l2tp and ppp parts") Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller Signed-off-by: Giuliano Procida Signed-off-by: Greg Kroah-Hartman --- net/l2tp/l2tp_core.c | 43 +++++++++++++++++++++++++++++-------------- net/l2tp/l2tp_core.h | 4 ++++ 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 5d1eb253a0b1..3a7031426b46 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -328,13 +328,21 @@ static int l2tp_session_add_to_tunnel(struct l2tp_tunnel *tunnel, struct hlist_head *g_head; struct hlist_head *head; struct l2tp_net *pn; + int err; head = l2tp_session_id_hash(tunnel, session->session_id); write_lock_bh(&tunnel->hlist_lock); + if (!tunnel->acpt_newsess) { + err = -ENODEV; + goto err_tlock; + } + hlist_for_each_entry(session_walk, head, hlist) - if (session_walk->session_id == session->session_id) - goto exist; + if (session_walk->session_id == session->session_id) { + err = -EEXIST; + goto err_tlock; + } if (tunnel->version == L2TP_HDR_VER_3) { pn = l2tp_pernet(tunnel->l2tp_net); @@ -342,12 +350,21 @@ static int l2tp_session_add_to_tunnel(struct l2tp_tunnel *tunnel, session->session_id); spin_lock_bh(&pn->l2tp_session_hlist_lock); - hlist_for_each_entry(session_walk, g_head, global_hlist) - if (session_walk->session_id == session->session_id) - goto exist_glob; + hlist_for_each_entry(session_walk, g_head, global_hlist) + if (session_walk->session_id == session->session_id) { + err = -EEXIST; + goto err_tlock_pnlock; + } + + l2tp_tunnel_inc_refcount(tunnel); + sock_hold(tunnel->sock); hlist_add_head_rcu(&session->global_hlist, g_head); + spin_unlock_bh(&pn->l2tp_session_hlist_lock); + } else { + l2tp_tunnel_inc_refcount(tunnel); + sock_hold(tunnel->sock); } hlist_add_head(&session->hlist, head); @@ -355,12 +372,12 @@ static int l2tp_session_add_to_tunnel(struct l2tp_tunnel *tunnel, return 0; -exist_glob: +err_tlock_pnlock: spin_unlock_bh(&pn->l2tp_session_hlist_lock); -exist: +err_tlock: write_unlock_bh(&tunnel->hlist_lock); - return -EEXIST; + return err; } /* Lookup a tunnel by id @@ -1246,7 +1263,6 @@ static void l2tp_tunnel_destruct(struct sock *sk) /* Remove hooks into tunnel socket */ sk->sk_destruct = tunnel->old_sk_destruct; sk->sk_user_data = NULL; - tunnel->sock = NULL; /* Remove the tunnel struct from the tunnel list */ pn = l2tp_pernet(tunnel->l2tp_net); @@ -1256,6 +1272,8 @@ static void l2tp_tunnel_destruct(struct sock *sk) atomic_dec(&l2tp_tunnel_count); l2tp_tunnel_closeall(tunnel); + + tunnel->sock = NULL; l2tp_tunnel_dec_refcount(tunnel); /* Call the original destructor */ @@ -1280,6 +1298,7 @@ void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel) tunnel->name); write_lock_bh(&tunnel->hlist_lock); + tunnel->acpt_newsess = false; for (hash = 0; hash < L2TP_HASH_SIZE; hash++) { again: hlist_for_each_safe(walk, tmp, &tunnel->session_hlist[hash]) { @@ -1583,6 +1602,7 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32 tunnel->magic = L2TP_TUNNEL_MAGIC; sprintf(&tunnel->name[0], "tunl %u", tunnel_id); rwlock_init(&tunnel->hlist_lock); + tunnel->acpt_newsess = true; /* The net we belong to */ tunnel->l2tp_net = net; @@ -1832,11 +1852,6 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn return ERR_PTR(err); } - l2tp_tunnel_inc_refcount(tunnel); - - /* Ensure tunnel socket isn't deleted */ - sock_hold(tunnel->sock); - /* Ignore management session in session count value */ if (session->session_id != 0) atomic_inc(&l2tp_session_count); diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h index f747deaf6e09..39a952962593 100644 --- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h @@ -162,6 +162,10 @@ struct l2tp_tunnel { struct rcu_head rcu; rwlock_t hlist_lock; /* protect session_hlist */ + bool acpt_newsess; /* Indicates whether this + * tunnel accepts new sessions. + * Protected by hlist_lock. + */ struct hlist_head session_hlist[L2TP_HASH_SIZE]; /* hashed list of sessions, * hashed by id */ From feaed88dccc4742805c41260040103fa8a7f0df2 Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Fri, 22 May 2020 00:39:32 +0100 Subject: [PATCH 136/387] l2tp: pass tunnel pointer to ->session_create() commit f026bc29a8e093edfbb2a77700454b285c97e8ad upstream. Using l2tp_tunnel_find() in pppol2tp_session_create() and l2tp_eth_create() is racy, because no reference is held on the returned session. These functions are only used to implement the ->session_create callback which is run by l2tp_nl_cmd_session_create(). Therefore searching for the parent tunnel isn't necessary because l2tp_nl_cmd_session_create() already has a pointer to it and holds a reference. This patch modifies ->session_create()'s prototype to directly pass the the parent tunnel as parameter, thus avoiding searching for it in pppol2tp_session_create() and l2tp_eth_create(). Since we have to touch the ->session_create() call in l2tp_nl_cmd_session_create(), let's also remove the useless conditional: we know that ->session_create isn't NULL at this point because it's already been checked earlier in this same function. Finally, one might be tempted to think that the removed l2tp_tunnel_find() calls were harmless because they would return the same tunnel as the one held by l2tp_nl_cmd_session_create() anyway. But that tunnel might be removed and a new one created with same tunnel Id before the l2tp_tunnel_find() call. In this case l2tp_tunnel_find() would return the new tunnel which wouldn't be protected by the reference held by l2tp_nl_cmd_session_create(). Fixes: 309795f4bec2 ("l2tp: Add netlink control API for L2TP") Fixes: d9e31d17ceba ("l2tp: Add L2TP ethernet pseudowire support") Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller Signed-off-by: Giuliano Procida Signed-off-by: Greg Kroah-Hartman --- net/l2tp/l2tp_core.h | 4 +++- net/l2tp/l2tp_eth.c | 11 +++-------- net/l2tp/l2tp_netlink.c | 8 ++++---- net/l2tp/l2tp_ppp.c | 19 +++++++------------ 4 files changed, 17 insertions(+), 25 deletions(-) diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h index 39a952962593..fac92fda574d 100644 --- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h @@ -201,7 +201,9 @@ struct l2tp_tunnel { }; struct l2tp_nl_cmd_ops { - int (*session_create)(struct net *net, u32 tunnel_id, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg); + int (*session_create)(struct net *net, struct l2tp_tunnel *tunnel, + u32 session_id, u32 peer_session_id, + struct l2tp_session_cfg *cfg); int (*session_delete)(struct l2tp_session *session); }; diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index f0efbf1e9a49..4c122494f022 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c @@ -256,23 +256,18 @@ static void l2tp_eth_adjust_mtu(struct l2tp_tunnel *tunnel, dev->needed_headroom += session->hdr_len; } -static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg) +static int l2tp_eth_create(struct net *net, struct l2tp_tunnel *tunnel, + u32 session_id, u32 peer_session_id, + struct l2tp_session_cfg *cfg) { struct net_device *dev; char name[IFNAMSIZ]; - struct l2tp_tunnel *tunnel; struct l2tp_session *session; struct l2tp_eth *priv; struct l2tp_eth_sess *spriv; int rc; struct l2tp_eth_net *pn; - tunnel = l2tp_tunnel_find(net, tunnel_id); - if (!tunnel) { - rc = -ENODEV; - goto out; - } - if (cfg->ifname) { dev = dev_get_by_name(net, cfg->ifname); if (dev) { diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c index 5ea5d3ffa309..47d7bdff8be8 100644 --- a/net/l2tp/l2tp_netlink.c +++ b/net/l2tp/l2tp_netlink.c @@ -632,10 +632,10 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf break; } - ret = -EPROTONOSUPPORT; - if (l2tp_nl_cmd_ops[cfg.pw_type]->session_create) - ret = (*l2tp_nl_cmd_ops[cfg.pw_type]->session_create)(net, tunnel_id, - session_id, peer_session_id, &cfg); + ret = l2tp_nl_cmd_ops[cfg.pw_type]->session_create(net, tunnel, + session_id, + peer_session_id, + &cfg); if (ret >= 0) { session = l2tp_session_get(net, tunnel, session_id, false); diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index 809606f2d54a..c8f877bfb00f 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c @@ -795,25 +795,20 @@ end: #ifdef CONFIG_L2TP_V3 -/* Called when creating sessions via the netlink interface. - */ -static int pppol2tp_session_create(struct net *net, u32 tunnel_id, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg) +/* Called when creating sessions via the netlink interface. */ +static int pppol2tp_session_create(struct net *net, struct l2tp_tunnel *tunnel, + u32 session_id, u32 peer_session_id, + struct l2tp_session_cfg *cfg) { int error; - struct l2tp_tunnel *tunnel; struct l2tp_session *session; struct pppol2tp_session *ps; - tunnel = l2tp_tunnel_find(net, tunnel_id); - - /* Error if we can't find the tunnel */ - error = -ENOENT; - if (tunnel == NULL) - goto out; - /* Error if tunnel socket is not prepped */ - if (tunnel->sock == NULL) + if (!tunnel->sock) { + error = -ENOENT; goto out; + } /* Default MTU values. */ if (cfg->mtu == 0) From 1ede832fb82fbda56c1bd7c57fb581dfab9c6e49 Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Fri, 22 May 2020 00:39:33 +0100 Subject: [PATCH 137/387] l2tp: fix l2tp_eth module loading commit 9f775ead5e570e7e19015b9e4e2f3dd6e71a5935 upstream. The l2tp_eth module crashes if its netlink callbacks are run when the pernet data aren't initialised. We should normally register_pernet_device() before the genl callbacks. However, the pernet data only maintain a list of l2tpeth interfaces, and this list is never used. So let's just drop pernet handling instead. Fixes: d9e31d17ceba ("l2tp: Add L2TP ethernet pseudowire support") Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller Signed-off-by: Giuliano Procida Signed-off-by: Greg Kroah-Hartman --- net/l2tp/l2tp_eth.c | 51 ++------------------------------------------- 1 file changed, 2 insertions(+), 49 deletions(-) diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index 4c122494f022..d22a39c0c486 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c @@ -44,7 +44,6 @@ struct l2tp_eth { struct net_device *dev; struct sock *tunnel_sock; struct l2tp_session *session; - struct list_head list; atomic_long_t tx_bytes; atomic_long_t tx_packets; atomic_long_t tx_dropped; @@ -58,17 +57,6 @@ struct l2tp_eth_sess { struct net_device *dev; }; -/* per-net private data for this module */ -static unsigned int l2tp_eth_net_id; -struct l2tp_eth_net { - struct list_head l2tp_eth_dev_list; - spinlock_t l2tp_eth_lock; -}; - -static inline struct l2tp_eth_net *l2tp_eth_pernet(struct net *net) -{ - return net_generic(net, l2tp_eth_net_id); -} static int l2tp_eth_dev_init(struct net_device *dev) { @@ -84,12 +72,6 @@ static int l2tp_eth_dev_init(struct net_device *dev) static void l2tp_eth_dev_uninit(struct net_device *dev) { - struct l2tp_eth *priv = netdev_priv(dev); - struct l2tp_eth_net *pn = l2tp_eth_pernet(dev_net(dev)); - - spin_lock(&pn->l2tp_eth_lock); - list_del_init(&priv->list); - spin_unlock(&pn->l2tp_eth_lock); dev_put(dev); } @@ -266,7 +248,6 @@ static int l2tp_eth_create(struct net *net, struct l2tp_tunnel *tunnel, struct l2tp_eth *priv; struct l2tp_eth_sess *spriv; int rc; - struct l2tp_eth_net *pn; if (cfg->ifname) { dev = dev_get_by_name(net, cfg->ifname); @@ -299,7 +280,6 @@ static int l2tp_eth_create(struct net *net, struct l2tp_tunnel *tunnel, priv = netdev_priv(dev); priv->dev = dev; priv->session = session; - INIT_LIST_HEAD(&priv->list); priv->tunnel_sock = tunnel->sock; session->recv_skb = l2tp_eth_dev_recv; @@ -320,10 +300,6 @@ static int l2tp_eth_create(struct net *net, struct l2tp_tunnel *tunnel, strlcpy(session->ifname, dev->name, IFNAMSIZ); dev_hold(dev); - pn = l2tp_eth_pernet(dev_net(dev)); - spin_lock(&pn->l2tp_eth_lock); - list_add(&priv->list, &pn->l2tp_eth_dev_list); - spin_unlock(&pn->l2tp_eth_lock); return 0; @@ -336,22 +312,6 @@ out: return rc; } -static __net_init int l2tp_eth_init_net(struct net *net) -{ - struct l2tp_eth_net *pn = net_generic(net, l2tp_eth_net_id); - - INIT_LIST_HEAD(&pn->l2tp_eth_dev_list); - spin_lock_init(&pn->l2tp_eth_lock); - - return 0; -} - -static struct pernet_operations l2tp_eth_net_ops = { - .init = l2tp_eth_init_net, - .id = &l2tp_eth_net_id, - .size = sizeof(struct l2tp_eth_net), -}; - static const struct l2tp_nl_cmd_ops l2tp_eth_nl_cmd_ops = { .session_create = l2tp_eth_create, @@ -365,25 +325,18 @@ static int __init l2tp_eth_init(void) err = l2tp_nl_register_ops(L2TP_PWTYPE_ETH, &l2tp_eth_nl_cmd_ops); if (err) - goto out; - - err = register_pernet_device(&l2tp_eth_net_ops); - if (err) - goto out_unreg; + goto err; pr_info("L2TP ethernet pseudowire support (L2TPv3)\n"); return 0; -out_unreg: - l2tp_nl_unregister_ops(L2TP_PWTYPE_ETH); -out: +err: return err; } static void __exit l2tp_eth_exit(void) { - unregister_pernet_device(&l2tp_eth_net_ops); l2tp_nl_unregister_ops(L2TP_PWTYPE_ETH); } From 12b5fb58ac993c24210cf8cbc72d407d3a4e6490 Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Fri, 22 May 2020 00:39:34 +0100 Subject: [PATCH 138/387] l2tp: don't register sessions in l2tp_session_create() commit 3953ae7b218df4d1e544b98a393666f9ae58a78c upstream. Sessions created by l2tp_session_create() aren't fully initialised: some pseudo-wire specific operations need to be done before making the session usable. Therefore the PPP and Ethernet pseudo-wires continue working on the returned l2tp session while it's already been exposed to the rest of the system. This can lead to various issues. In particular, the session may enter the deletion process before having been fully initialised, which will confuse the session removal code. This patch moves session registration out of l2tp_session_create(), so that callers can control when the session is exposed to the rest of the system. This is done by the new l2tp_session_register() function. Only pppol2tp_session_create() can be easily converted to avoid modifying its session after registration (the debug message is dropped in order to avoid the need for holding a reference on the session). For pppol2tp_connect() and l2tp_eth_create()), more work is needed. That'll be done in followup patches. For now, let's just register the session right after its creation, like it was done before. The only difference is that we can easily take a reference on the session before registering it, so, at least, we're sure it's not going to be freed while we're working on it. Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller Signed-off-by: Giuliano Procida Signed-off-by: Greg Kroah-Hartman --- net/l2tp/l2tp_core.c | 21 +++++++-------------- net/l2tp/l2tp_core.h | 3 +++ net/l2tp/l2tp_eth.c | 9 +++++++++ net/l2tp/l2tp_ppp.c | 23 +++++++++++++++++------ 4 files changed, 36 insertions(+), 20 deletions(-) diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 3a7031426b46..36c7f616294a 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -321,8 +321,8 @@ struct l2tp_session *l2tp_session_get_by_ifname(const struct net *net, } EXPORT_SYMBOL_GPL(l2tp_session_get_by_ifname); -static int l2tp_session_add_to_tunnel(struct l2tp_tunnel *tunnel, - struct l2tp_session *session) +int l2tp_session_register(struct l2tp_session *session, + struct l2tp_tunnel *tunnel) { struct l2tp_session *session_walk; struct hlist_head *g_head; @@ -370,6 +370,10 @@ static int l2tp_session_add_to_tunnel(struct l2tp_tunnel *tunnel, hlist_add_head(&session->hlist, head); write_unlock_bh(&tunnel->hlist_lock); + /* Ignore management session in session count value */ + if (session->session_id != 0) + atomic_inc(&l2tp_session_count); + return 0; err_tlock_pnlock: @@ -379,6 +383,7 @@ err_tlock: return err; } +EXPORT_SYMBOL_GPL(l2tp_session_register); /* Lookup a tunnel by id */ @@ -1788,7 +1793,6 @@ EXPORT_SYMBOL_GPL(l2tp_session_set_header_len); struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunnel, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg) { struct l2tp_session *session; - int err; session = kzalloc(sizeof(struct l2tp_session) + priv_size, GFP_KERNEL); if (session != NULL) { @@ -1845,17 +1849,6 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn l2tp_session_inc_refcount(session); - err = l2tp_session_add_to_tunnel(tunnel, session); - if (err) { - kfree(session); - - return ERR_PTR(err); - } - - /* Ignore management session in session count value */ - if (session->session_id != 0) - atomic_inc(&l2tp_session_count); - return session; } diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h index fac92fda574d..2b9b6fb67ae9 100644 --- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h @@ -259,6 +259,9 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunnel, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg); +int l2tp_session_register(struct l2tp_session *session, + struct l2tp_tunnel *tunnel); + void __l2tp_session_unhash(struct l2tp_session *session); int l2tp_session_delete(struct l2tp_session *session); void l2tp_session_free(struct l2tp_session *session); diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index d22a39c0c486..5902d088b44f 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c @@ -267,6 +267,13 @@ static int l2tp_eth_create(struct net *net, struct l2tp_tunnel *tunnel, goto out; } + l2tp_session_inc_refcount(session); + rc = l2tp_session_register(session, tunnel); + if (rc < 0) { + kfree(session); + goto out; + } + dev = alloc_netdev(sizeof(*priv), name, NET_NAME_UNKNOWN, l2tp_eth_dev_setup); if (!dev) { @@ -298,6 +305,7 @@ static int l2tp_eth_create(struct net *net, struct l2tp_tunnel *tunnel, __module_get(THIS_MODULE); /* Must be done after register_netdev() */ strlcpy(session->ifname, dev->name, IFNAMSIZ); + l2tp_session_dec_refcount(session); dev_hold(dev); @@ -308,6 +316,7 @@ out_del_dev: spriv->dev = NULL; out_del_session: l2tp_session_delete(session); + l2tp_session_dec_refcount(session); out: return rc; } diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index c8f877bfb00f..e617993939d4 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c @@ -722,6 +722,14 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, error = PTR_ERR(session); goto end; } + + l2tp_session_inc_refcount(session); + error = l2tp_session_register(session, tunnel); + if (error < 0) { + kfree(session); + goto end; + } + drop_refcnt = true; } /* Associate session with its PPPoL2TP socket */ @@ -807,7 +815,7 @@ static int pppol2tp_session_create(struct net *net, struct l2tp_tunnel *tunnel, /* Error if tunnel socket is not prepped */ if (!tunnel->sock) { error = -ENOENT; - goto out; + goto err; } /* Default MTU values. */ @@ -822,18 +830,21 @@ static int pppol2tp_session_create(struct net *net, struct l2tp_tunnel *tunnel, peer_session_id, cfg); if (IS_ERR(session)) { error = PTR_ERR(session); - goto out; + goto err; } ps = l2tp_session_priv(session); ps->tunnel_sock = tunnel->sock; - l2tp_info(session, L2TP_MSG_CONTROL, "%s: created\n", - session->name); + error = l2tp_session_register(session, tunnel); + if (error < 0) + goto err_sess; - error = 0; + return 0; -out: +err_sess: + kfree(session); +err: return error; } From 96985edde9dfe3c1a5b0251842ca400274b287ed Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Fri, 22 May 2020 00:39:35 +0100 Subject: [PATCH 139/387] l2tp: initialise l2tp_eth sessions before registering them commit ee28de6bbd78c2e18111a0aef43ea746f28d2073 upstream. Sessions must be initialised before being made externally visible by l2tp_session_register(). Otherwise the session may be concurrently deleted before being initialised, which can confuse the deletion path and eventually lead to kernel oops. Therefore, we need to move l2tp_session_register() down in l2tp_eth_create(), but also handle the intermediate step where only the session or the netdevice has been registered. We can't just call l2tp_session_register() in ->ndo_init() because we'd have no way to properly undo this operation in ->ndo_uninit(). Instead, let's register the session and the netdevice in two different steps and protect the session's device pointer with RCU. And now that we allow the session's .dev field to be NULL, we don't need to prevent the netdevice from being removed anymore. So we can drop the dev_hold() and dev_put() calls in l2tp_eth_create() and l2tp_eth_dev_uninit(). Backporting Notes l2tp_eth.c: In l2tp_eth_create the "out" label was renamed to "err". There was one extra occurrence of "goto out" to update. Fixes: d9e31d17ceba ("l2tp: Add L2TP ethernet pseudowire support") Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller Signed-off-by: Giuliano Procida Signed-off-by: Greg Kroah-Hartman --- net/l2tp/l2tp_eth.c | 108 +++++++++++++++++++++++++++++++------------- 1 file changed, 76 insertions(+), 32 deletions(-) diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index 5902d088b44f..60764ac2ddea 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c @@ -54,7 +54,7 @@ struct l2tp_eth { /* via l2tp_session_priv() */ struct l2tp_eth_sess { - struct net_device *dev; + struct net_device __rcu *dev; }; @@ -72,7 +72,14 @@ static int l2tp_eth_dev_init(struct net_device *dev) static void l2tp_eth_dev_uninit(struct net_device *dev) { - dev_put(dev); + struct l2tp_eth *priv = netdev_priv(dev); + struct l2tp_eth_sess *spriv; + + spriv = l2tp_session_priv(priv->session); + RCU_INIT_POINTER(spriv->dev, NULL); + /* No need for synchronize_net() here. We're called by + * unregister_netdev*(), which does the synchronisation for us. + */ } static int l2tp_eth_dev_xmit(struct sk_buff *skb, struct net_device *dev) @@ -126,8 +133,8 @@ static void l2tp_eth_dev_setup(struct net_device *dev) static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb, int data_len) { struct l2tp_eth_sess *spriv = l2tp_session_priv(session); - struct net_device *dev = spriv->dev; - struct l2tp_eth *priv = netdev_priv(dev); + struct net_device *dev; + struct l2tp_eth *priv; if (session->debug & L2TP_MSG_DATA) { unsigned int length; @@ -151,16 +158,25 @@ static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb, skb_dst_drop(skb); nf_reset(skb); + rcu_read_lock(); + dev = rcu_dereference(spriv->dev); + if (!dev) + goto error_rcu; + + priv = netdev_priv(dev); if (dev_forward_skb(dev, skb) == NET_RX_SUCCESS) { atomic_long_inc(&priv->rx_packets); atomic_long_add(data_len, &priv->rx_bytes); } else { atomic_long_inc(&priv->rx_errors); } + rcu_read_unlock(); + return; +error_rcu: + rcu_read_unlock(); error: - atomic_long_inc(&priv->rx_errors); kfree_skb(skb); } @@ -171,11 +187,15 @@ static void l2tp_eth_delete(struct l2tp_session *session) if (session) { spriv = l2tp_session_priv(session); - dev = spriv->dev; + + rtnl_lock(); + dev = rtnl_dereference(spriv->dev); if (dev) { - unregister_netdev(dev); - spriv->dev = NULL; + unregister_netdevice(dev); + rtnl_unlock(); module_put(THIS_MODULE); + } else { + rtnl_unlock(); } } } @@ -185,9 +205,20 @@ static void l2tp_eth_show(struct seq_file *m, void *arg) { struct l2tp_session *session = arg; struct l2tp_eth_sess *spriv = l2tp_session_priv(session); - struct net_device *dev = spriv->dev; + struct net_device *dev; + + rcu_read_lock(); + dev = rcu_dereference(spriv->dev); + if (!dev) { + rcu_read_unlock(); + return; + } + dev_hold(dev); + rcu_read_unlock(); seq_printf(m, " interface %s\n", dev->name); + + dev_put(dev); } #endif @@ -254,7 +285,7 @@ static int l2tp_eth_create(struct net *net, struct l2tp_tunnel *tunnel, if (dev) { dev_put(dev); rc = -EEXIST; - goto out; + goto err; } strlcpy(name, cfg->ifname, IFNAMSIZ); } else @@ -264,21 +295,14 @@ static int l2tp_eth_create(struct net *net, struct l2tp_tunnel *tunnel, peer_session_id, cfg); if (IS_ERR(session)) { rc = PTR_ERR(session); - goto out; - } - - l2tp_session_inc_refcount(session); - rc = l2tp_session_register(session, tunnel); - if (rc < 0) { - kfree(session); - goto out; + goto err; } dev = alloc_netdev(sizeof(*priv), name, NET_NAME_UNKNOWN, l2tp_eth_dev_setup); if (!dev) { rc = -ENOMEM; - goto out_del_session; + goto err_sess; } dev_net_set(dev, net); @@ -296,28 +320,48 @@ static int l2tp_eth_create(struct net *net, struct l2tp_tunnel *tunnel, #endif spriv = l2tp_session_priv(session); - spriv->dev = dev; - rc = register_netdev(dev); - if (rc < 0) - goto out_del_dev; + l2tp_session_inc_refcount(session); + + rtnl_lock(); + + /* Register both device and session while holding the rtnl lock. This + * ensures that l2tp_eth_delete() will see that there's a device to + * unregister, even if it happened to run before we assign spriv->dev. + */ + rc = l2tp_session_register(session, tunnel); + if (rc < 0) { + rtnl_unlock(); + goto err_sess_dev; + } + + rc = register_netdevice(dev); + if (rc < 0) { + rtnl_unlock(); + l2tp_session_delete(session); + l2tp_session_dec_refcount(session); + free_netdev(dev); + + return rc; + } - __module_get(THIS_MODULE); - /* Must be done after register_netdev() */ strlcpy(session->ifname, dev->name, IFNAMSIZ); + rcu_assign_pointer(spriv->dev, dev); + + rtnl_unlock(); + l2tp_session_dec_refcount(session); - dev_hold(dev); + __module_get(THIS_MODULE); return 0; -out_del_dev: - free_netdev(dev); - spriv->dev = NULL; -out_del_session: - l2tp_session_delete(session); +err_sess_dev: l2tp_session_dec_refcount(session); -out: + free_netdev(dev); +err_sess: + kfree(session); +err: return rc; } From 5803ecd7f6ac6f747582e775caa62ac9d0489261 Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Fri, 22 May 2020 00:39:36 +0100 Subject: [PATCH 140/387] l2tp: protect sock pointer of struct pppol2tp_session with RCU commit ee40fb2e1eb5bc0ddd3f2f83c6e39a454ef5a741 upstream. pppol2tp_session_create() registers sessions that can't have their corresponding socket initialised. This socket has to be created by userspace, then connected to the session by pppol2tp_connect(). Therefore, we need to protect the pppol2tp socket pointer of L2TP sessions, so that it can safely be updated when userspace is connecting or closing the socket. This will eventually allow pppol2tp_connect() to avoid generating transient states while initialising its parts of the session. To this end, this patch protects the pppol2tp socket pointer using RCU. The pppol2tp socket pointer is still set in pppol2tp_connect(), but only once we know the function isn't going to fail. It's eventually reset by pppol2tp_release(), which now has to wait for a grace period to elapse before it can drop the last reference on the socket. This ensures that pppol2tp_session_get_sock() can safely grab a reference on the socket, even after ps->sk is reset to NULL but before this operation actually gets visible from pppol2tp_session_get_sock(). The rest is standard RCU conversion: pppol2tp_recv(), which already runs in atomic context, is simply enclosed by rcu_read_lock() and rcu_read_unlock(), while other functions are converted to use pppol2tp_session_get_sock() followed by sock_put(). pppol2tp_session_setsockopt() is a special case. It used to retrieve the pppol2tp socket from the L2TP session, which itself was retrieved from the pppol2tp socket. Therefore we can just avoid dereferencing ps->sk and directly use the original socket pointer instead. With all users of ps->sk now handling NULL and concurrent updates, the L2TP ->ref() and ->deref() callbacks aren't needed anymore. Therefore, rather than converting pppol2tp_session_sock_hold() and pppol2tp_session_sock_put(), we can just drop them. Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller Signed-off-by: Giuliano Procida Signed-off-by: Greg Kroah-Hartman --- net/l2tp/l2tp_ppp.c | 154 +++++++++++++++++++++++++++++--------------- 1 file changed, 101 insertions(+), 53 deletions(-) diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index e617993939d4..9eb07c1a993e 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c @@ -122,8 +122,11 @@ struct pppol2tp_session { int owner; /* pid that opened the socket */ - struct sock *sock; /* Pointer to the session + struct mutex sk_lock; /* Protects .sk */ + struct sock __rcu *sk; /* Pointer to the session * PPPoX socket */ + struct sock *__sk; /* Copy of .sk, for cleanup */ + struct rcu_head rcu; /* For asynchronous release */ struct sock *tunnel_sock; /* Pointer to the tunnel UDP * socket */ int flags; /* accessed by PPPIOCGFLAGS. @@ -138,6 +141,24 @@ static const struct ppp_channel_ops pppol2tp_chan_ops = { static const struct proto_ops pppol2tp_ops; +/* Retrieves the pppol2tp socket associated to a session. + * A reference is held on the returned socket, so this function must be paired + * with sock_put(). + */ +static struct sock *pppol2tp_session_get_sock(struct l2tp_session *session) +{ + struct pppol2tp_session *ps = l2tp_session_priv(session); + struct sock *sk; + + rcu_read_lock(); + sk = rcu_dereference(ps->sk); + if (sk) + sock_hold(sk); + rcu_read_unlock(); + + return sk; +} + /* Helpers to obtain tunnel/session contexts from sockets. */ static inline struct l2tp_session *pppol2tp_sock_to_session(struct sock *sk) @@ -224,7 +245,8 @@ static void pppol2tp_recv(struct l2tp_session *session, struct sk_buff *skb, int /* If the socket is bound, send it in to PPP's input queue. Otherwise * queue it on the session socket. */ - sk = ps->sock; + rcu_read_lock(); + sk = rcu_dereference(ps->sk); if (sk == NULL) goto no_sock; @@ -247,30 +269,16 @@ static void pppol2tp_recv(struct l2tp_session *session, struct sk_buff *skb, int kfree_skb(skb); } } + rcu_read_unlock(); return; no_sock: + rcu_read_unlock(); l2tp_info(session, L2TP_MSG_DATA, "%s: no socket\n", session->name); kfree_skb(skb); } -static void pppol2tp_session_sock_hold(struct l2tp_session *session) -{ - struct pppol2tp_session *ps = l2tp_session_priv(session); - - if (ps->sock) - sock_hold(ps->sock); -} - -static void pppol2tp_session_sock_put(struct l2tp_session *session) -{ - struct pppol2tp_session *ps = l2tp_session_priv(session); - - if (ps->sock) - sock_put(ps->sock); -} - /************************************************************************ * Transmit handling ***********************************************************************/ @@ -431,14 +439,16 @@ abort: */ static void pppol2tp_session_close(struct l2tp_session *session) { - struct pppol2tp_session *ps = l2tp_session_priv(session); - struct sock *sk = ps->sock; - struct socket *sock = sk->sk_socket; + struct sock *sk; BUG_ON(session->magic != L2TP_SESSION_MAGIC); - if (sock) - inet_shutdown(sock, SEND_SHUTDOWN); + sk = pppol2tp_session_get_sock(session); + if (sk) { + if (sk->sk_socket) + inet_shutdown(sk->sk_socket, SEND_SHUTDOWN); + sock_put(sk); + } /* Don't let the session go away before our socket does */ l2tp_session_inc_refcount(session); @@ -461,6 +471,14 @@ static void pppol2tp_session_destruct(struct sock *sk) } } +static void pppol2tp_put_sk(struct rcu_head *head) +{ + struct pppol2tp_session *ps; + + ps = container_of(head, typeof(*ps), rcu); + sock_put(ps->__sk); +} + /* Called when the PPPoX socket (session) is closed. */ static int pppol2tp_release(struct socket *sock) @@ -486,11 +504,24 @@ static int pppol2tp_release(struct socket *sock) session = pppol2tp_sock_to_session(sk); - /* Purge any queued data */ if (session != NULL) { + struct pppol2tp_session *ps; + __l2tp_session_unhash(session); l2tp_session_queue_purge(session); - sock_put(sk); + + ps = l2tp_session_priv(session); + mutex_lock(&ps->sk_lock); + ps->__sk = rcu_dereference_protected(ps->sk, + lockdep_is_held(&ps->sk_lock)); + RCU_INIT_POINTER(ps->sk, NULL); + mutex_unlock(&ps->sk_lock); + call_rcu(&ps->rcu, pppol2tp_put_sk); + + /* Rely on the sock_put() call at the end of the function for + * dropping the reference held by pppol2tp_sock_to_session(). + * The last reference will be dropped by pppol2tp_put_sk(). + */ } release_sock(sk); @@ -557,12 +588,14 @@ out: static void pppol2tp_show(struct seq_file *m, void *arg) { struct l2tp_session *session = arg; - struct pppol2tp_session *ps = l2tp_session_priv(session); + struct sock *sk; - if (ps) { - struct pppox_sock *po = pppox_sk(ps->sock); - if (po) - seq_printf(m, " interface %s\n", ppp_dev_name(&po->chan)); + sk = pppol2tp_session_get_sock(session); + if (sk) { + struct pppox_sock *po = pppox_sk(sk); + + seq_printf(m, " interface %s\n", ppp_dev_name(&po->chan)); + sock_put(sk); } } #endif @@ -700,13 +733,17 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, /* Using a pre-existing session is fine as long as it hasn't * been connected yet. */ - if (ps->sock) { + mutex_lock(&ps->sk_lock); + if (rcu_dereference_protected(ps->sk, + lockdep_is_held(&ps->sk_lock))) { + mutex_unlock(&ps->sk_lock); error = -EEXIST; goto end; } /* consistency checks */ if (ps->tunnel_sock != tunnel->sock) { + mutex_unlock(&ps->sk_lock); error = -EEXIST; goto end; } @@ -723,19 +760,21 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, goto end; } + ps = l2tp_session_priv(session); + mutex_init(&ps->sk_lock); l2tp_session_inc_refcount(session); + + mutex_lock(&ps->sk_lock); error = l2tp_session_register(session, tunnel); if (error < 0) { + mutex_unlock(&ps->sk_lock); kfree(session); goto end; } drop_refcnt = true; } - /* Associate session with its PPPoL2TP socket */ - ps = l2tp_session_priv(session); ps->owner = current->pid; - ps->sock = sk; ps->tunnel_sock = tunnel->sock; session->recv_skb = pppol2tp_recv; @@ -744,12 +783,6 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, session->show = pppol2tp_show; #endif - /* We need to know each time a skb is dropped from the reorder - * queue. - */ - session->ref = pppol2tp_session_sock_hold; - session->deref = pppol2tp_session_sock_put; - /* If PMTU discovery was enabled, use the MTU that was discovered */ dst = sk_dst_get(tunnel->sock); if (dst != NULL) { @@ -783,12 +816,17 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, po->chan.mtu = session->mtu; error = ppp_register_net_channel(sock_net(sk), &po->chan); - if (error) + if (error) { + mutex_unlock(&ps->sk_lock); goto end; + } out_no_ppp: /* This is how we get the session context from the socket. */ sk->sk_user_data = session; + rcu_assign_pointer(ps->sk, sk); + mutex_unlock(&ps->sk_lock); + sk->sk_state = PPPOX_CONNECTED; l2tp_info(session, L2TP_MSG_CONTROL, "%s: created\n", session->name); @@ -834,6 +872,7 @@ static int pppol2tp_session_create(struct net *net, struct l2tp_tunnel *tunnel, } ps = l2tp_session_priv(session); + mutex_init(&ps->sk_lock); ps->tunnel_sock = tunnel->sock; error = l2tp_session_register(session, tunnel); @@ -1005,12 +1044,10 @@ static int pppol2tp_session_ioctl(struct l2tp_session *session, "%s: pppol2tp_session_ioctl(cmd=%#x, arg=%#lx)\n", session->name, cmd, arg); - sk = ps->sock; + sk = pppol2tp_session_get_sock(session); if (!sk) return -EBADR; - sock_hold(sk); - switch (cmd) { case SIOCGIFMTU: err = -ENXIO; @@ -1286,7 +1323,6 @@ static int pppol2tp_session_setsockopt(struct sock *sk, int optname, int val) { int err = 0; - struct pppol2tp_session *ps = l2tp_session_priv(session); switch (optname) { case PPPOL2TP_SO_RECVSEQ: @@ -1307,8 +1343,8 @@ static int pppol2tp_session_setsockopt(struct sock *sk, } session->send_seq = val ? -1 : 0; { - struct sock *ssk = ps->sock; - struct pppox_sock *po = pppox_sk(ssk); + struct pppox_sock *po = pppox_sk(sk); + po->chan.hdrlen = val ? PPPOL2TP_L2TP_HDR_SIZE_SEQ : PPPOL2TP_L2TP_HDR_SIZE_NOSEQ; } @@ -1644,8 +1680,9 @@ static void pppol2tp_seq_session_show(struct seq_file *m, void *v) { struct l2tp_session *session = v; struct l2tp_tunnel *tunnel = session->tunnel; - struct pppol2tp_session *ps = l2tp_session_priv(session); - struct pppox_sock *po = pppox_sk(ps->sock); + unsigned char state; + char user_data_ok; + struct sock *sk; u32 ip = 0; u16 port = 0; @@ -1655,6 +1692,15 @@ static void pppol2tp_seq_session_show(struct seq_file *m, void *v) port = ntohs(inet->inet_sport); } + sk = pppol2tp_session_get_sock(session); + if (sk) { + state = sk->sk_state; + user_data_ok = (session == sk->sk_user_data) ? 'Y' : 'N'; + } else { + state = 0; + user_data_ok = 'N'; + } + seq_printf(m, " SESSION '%s' %08X/%d %04X/%04X -> " "%04X/%04X %d %c\n", session->name, ip, port, @@ -1662,9 +1708,7 @@ static void pppol2tp_seq_session_show(struct seq_file *m, void *v) session->session_id, tunnel->peer_tunnel_id, session->peer_session_id, - ps->sock->sk_state, - (session == ps->sock->sk_user_data) ? - 'Y' : 'N'); + state, user_data_ok); seq_printf(m, " %d/%d/%c/%c/%s %08x %u\n", session->mtu, session->mru, session->recv_seq ? 'R' : '-', @@ -1681,8 +1725,12 @@ static void pppol2tp_seq_session_show(struct seq_file *m, void *v) atomic_long_read(&session->stats.rx_bytes), atomic_long_read(&session->stats.rx_errors)); - if (po) + if (sk) { + struct pppox_sock *po = pppox_sk(sk); + seq_printf(m, " interface %s\n", ppp_dev_name(&po->chan)); + sock_put(sk); + } } static int pppol2tp_seq_show(struct seq_file *m, void *v) From ad6c13e25f89f41d417b9280ca7065175ead1a94 Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Fri, 22 May 2020 00:39:37 +0100 Subject: [PATCH 141/387] l2tp: initialise PPP sessions before registering them commit f98be6c6359e7e4a61aaefb9964c1db31cb9ec0c upstream. pppol2tp_connect() initialises L2TP sessions after they've been exposed to the rest of the system by l2tp_session_register(). This puts sessions into transient states that are the source of several races, in particular with session's deletion path. This patch centralises the initialisation code into pppol2tp_session_init(), which is called before the registration phase. The only field that can't be set before session registration is the pppol2tp socket pointer, which has already been converted to RCU. So pppol2tp_connect() should now be race-free. The session's .session_close() callback is now set before registration. Therefore, it's always called when l2tp_core deletes the session, even if it was created by pppol2tp_session_create() and hasn't been plugged to a pppol2tp socket yet. That'd prevent session free because the extra reference taken by pppol2tp_session_close() wouldn't be dropped by the socket's ->sk_destruct() callback (pppol2tp_session_destruct()). We could set .session_close() only while connecting a session to its pppol2tp socket, or teach pppol2tp_session_close() to avoid grabbing a reference when the session isn't connected, but that'd require adding some form of synchronisation to be race free. Instead of that, we can just let the pppol2tp socket hold a reference on the session as soon as it starts depending on it (that is, in pppol2tp_connect()). Then we don't need to utilise pppol2tp_session_close() to hold a reference at the last moment to prevent l2tp_core from dropping it. When releasing the socket, pppol2tp_release() now deletes the session using the standard l2tp_session_delete() function, instead of merely removing it from hash tables. l2tp_session_delete() drops the reference the sessions holds on itself, but also makes sure it doesn't remove a session twice. So it can safely be called, even if l2tp_core already tried, or is concurrently trying, to remove the session. Finally, pppol2tp_session_destruct() drops the reference held by the socket. Fixes: fd558d186df2 ("l2tp: Split pppol2tp patch into separate l2tp and ppp parts") Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller Signed-off-by: Giuliano Procida Signed-off-by: Greg Kroah-Hartman --- net/l2tp/l2tp_ppp.c | 69 +++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index 9eb07c1a993e..979fa868a4f1 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c @@ -449,9 +449,6 @@ static void pppol2tp_session_close(struct l2tp_session *session) inet_shutdown(sk->sk_socket, SEND_SHUTDOWN); sock_put(sk); } - - /* Don't let the session go away before our socket does */ - l2tp_session_inc_refcount(session); } /* Really kill the session socket. (Called from sock_put() if @@ -507,8 +504,7 @@ static int pppol2tp_release(struct socket *sock) if (session != NULL) { struct pppol2tp_session *ps; - __l2tp_session_unhash(session); - l2tp_session_queue_purge(session); + l2tp_session_delete(session); ps = l2tp_session_priv(session); mutex_lock(&ps->sk_lock); @@ -600,6 +596,35 @@ static void pppol2tp_show(struct seq_file *m, void *arg) } #endif +static void pppol2tp_session_init(struct l2tp_session *session) +{ + struct pppol2tp_session *ps; + struct dst_entry *dst; + + session->recv_skb = pppol2tp_recv; + session->session_close = pppol2tp_session_close; +#if IS_ENABLED(CONFIG_L2TP_DEBUGFS) + session->show = pppol2tp_show; +#endif + + ps = l2tp_session_priv(session); + mutex_init(&ps->sk_lock); + ps->tunnel_sock = session->tunnel->sock; + ps->owner = current->pid; + + /* If PMTU discovery was enabled, use the MTU that was discovered */ + dst = sk_dst_get(session->tunnel->sock); + if (dst) { + u32 pmtu = dst_mtu(dst); + + if (pmtu) { + session->mtu = pmtu - PPPOL2TP_HEADER_OVERHEAD; + session->mru = pmtu - PPPOL2TP_HEADER_OVERHEAD; + } + dst_release(dst); + } +} + /* connect() handler. Attach a PPPoX socket to a tunnel UDP socket */ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, @@ -611,7 +636,6 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, struct l2tp_session *session = NULL; struct l2tp_tunnel *tunnel; struct pppol2tp_session *ps; - struct dst_entry *dst; struct l2tp_session_cfg cfg = { 0, }; int error = 0; u32 tunnel_id, peer_tunnel_id; @@ -760,8 +784,8 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, goto end; } + pppol2tp_session_init(session); ps = l2tp_session_priv(session); - mutex_init(&ps->sk_lock); l2tp_session_inc_refcount(session); mutex_lock(&ps->sk_lock); @@ -774,26 +798,6 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, drop_refcnt = true; } - ps->owner = current->pid; - ps->tunnel_sock = tunnel->sock; - - session->recv_skb = pppol2tp_recv; - session->session_close = pppol2tp_session_close; -#if IS_ENABLED(CONFIG_L2TP_DEBUGFS) - session->show = pppol2tp_show; -#endif - - /* If PMTU discovery was enabled, use the MTU that was discovered */ - dst = sk_dst_get(tunnel->sock); - if (dst != NULL) { - u32 pmtu = dst_mtu(dst); - - if (pmtu != 0) - session->mtu = session->mru = pmtu - - PPPOL2TP_HEADER_OVERHEAD; - dst_release(dst); - } - /* Special case: if source & dest session_id == 0x0000, this * socket is being created to manage the tunnel. Just set up * the internal context for use by ioctl() and sockopt() @@ -827,6 +831,12 @@ out_no_ppp: rcu_assign_pointer(ps->sk, sk); mutex_unlock(&ps->sk_lock); + /* Keep the reference we've grabbed on the session: sk doesn't expect + * the session to disappear. pppol2tp_session_destruct() is responsible + * for dropping it. + */ + drop_refcnt = false; + sk->sk_state = PPPOX_CONNECTED; l2tp_info(session, L2TP_MSG_CONTROL, "%s: created\n", session->name); @@ -848,7 +858,6 @@ static int pppol2tp_session_create(struct net *net, struct l2tp_tunnel *tunnel, { int error; struct l2tp_session *session; - struct pppol2tp_session *ps; /* Error if tunnel socket is not prepped */ if (!tunnel->sock) { @@ -871,9 +880,7 @@ static int pppol2tp_session_create(struct net *net, struct l2tp_tunnel *tunnel, goto err; } - ps = l2tp_session_priv(session); - mutex_init(&ps->sk_lock); - ps->tunnel_sock = tunnel->sock; + pppol2tp_session_init(session); error = l2tp_session_register(session, tunnel); if (error < 0) From bf77564f845b4ac67003044244220aa3414c8474 Mon Sep 17 00:00:00 2001 From: Brent Lu Date: Mon, 18 May 2020 12:30:38 +0800 Subject: [PATCH 142/387] ALSA: pcm: fix incorrect hw_base increase commit e7513c5786f8b33f0c107b3759e433bc6cbb2efa upstream. There is a corner case that ALSA keeps increasing the hw_ptr but DMA already stop working/updating the position for a long time. In following log we can see the position returned from DMA driver does not move at all but the hw_ptr got increased at some point of time so snd_pcm_avail() will return a large number which seems to be a buffer underrun event from user space program point of view. The program thinks there is space in the buffer and fill more data. [ 418.510086] sound pcmC0D5p: pos 96 hw_ptr 96 appl_ptr 4096 avail 12368 [ 418.510149] sound pcmC0D5p: pos 96 hw_ptr 96 appl_ptr 6910 avail 9554 ... [ 418.681052] sound pcmC0D5p: pos 96 hw_ptr 96 appl_ptr 15102 avail 1362 [ 418.681130] sound pcmC0D5p: pos 96 hw_ptr 96 appl_ptr 16464 avail 0 [ 418.726515] sound pcmC0D5p: pos 96 hw_ptr 16464 appl_ptr 16464 avail 16368 This is because the hw_base will be increased by runtime->buffer_size frames unconditionally if the hw_ptr is not updated for over half of buffer time. As the hw_base increases, so does the hw_ptr increased by the same number. The avail value returned from snd_pcm_avail() could exceed the limit (buffer_size) easily becase the hw_ptr itself got increased by same buffer_size samples when the corner case happens. In following log, the buffer_size is 16368 samples but the avail is 21810 samples so CRAS server complains about it. [ 418.851755] sound pcmC0D5p: pos 96 hw_ptr 16464 appl_ptr 27390 avail 5442 [ 418.926491] sound pcmC0D5p: pos 96 hw_ptr 32832 appl_ptr 27390 avail 21810 cras_server[1907]: pcm_avail returned frames larger than buf_size: sof-glkda7219max: :0,5: 21810 > 16368 By updating runtime->hw_ptr_jiffies each time the HWSYNC is called, the hw_base will keep the same when buffer stall happens at long as the interval between each HWSYNC call is shorter than half of buffer time. Following is a log captured by a patched kernel. The hw_base/hw_ptr value is fixed in this corner case and user space program should be aware of the buffer stall and handle it. [ 293.525543] sound pcmC0D5p: pos 96 hw_ptr 96 appl_ptr 4096 avail 12368 [ 293.525606] sound pcmC0D5p: pos 96 hw_ptr 96 appl_ptr 6880 avail 9584 [ 293.525975] sound pcmC0D5p: pos 96 hw_ptr 96 appl_ptr 10976 avail 5488 [ 293.611178] sound pcmC0D5p: pos 96 hw_ptr 96 appl_ptr 15072 avail 1392 [ 293.696429] sound pcmC0D5p: pos 96 hw_ptr 96 appl_ptr 16464 avail 0 ... [ 381.139517] sound pcmC0D5p: pos 96 hw_ptr 96 appl_ptr 16464 avail 0 Signed-off-by: Brent Lu Reviewed-by: Jaroslav Kysela Cc: Link: https://lore.kernel.org/r/1589776238-23877-1-git-send-email-brent.lu@intel.com Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/core/pcm_lib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index f09ae7efc695..f0052c06d065 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -456,6 +456,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, no_delta_check: if (runtime->status->hw_ptr == new_hw_ptr) { + runtime->hw_ptr_jiffies = curr_jiffies; update_audio_tstamp(substream, &curr_tstamp, &audio_tstamp); return 0; } From 6ec8ac2b45c0d92fb5650b60feb19d9c4c17b70d Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sat, 16 May 2020 23:42:05 +0200 Subject: [PATCH 143/387] dmaengine: tegra210-adma: Fix an error handling path in 'tegra_adma_probe()' commit 3a5fd0dbd87853f8bd2ea275a5b3b41d6686e761 upstream. Commit b53611fb1ce9 ("dmaengine: tegra210-adma: Fix crash during probe") has moved some code in the probe function and reordered the error handling path accordingly. However, a goto has been missed. Fix it and goto the right label if 'dma_async_device_register()' fails, so that all resources are released. Fixes: b53611fb1ce9 ("dmaengine: tegra210-adma: Fix crash during probe") Signed-off-by: Christophe JAILLET Reviewed-by: Jon Hunter Acked-by: Thierry Reding Link: https://lore.kernel.org/r/20200516214205.276266-1-christophe.jaillet@wanadoo.fr Signed-off-by: Vinod Koul Signed-off-by: Greg Kroah-Hartman --- drivers/dma/tegra210-adma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/tegra210-adma.c b/drivers/dma/tegra210-adma.c index 2d4aeba579f7..c16c06b3dd2f 100644 --- a/drivers/dma/tegra210-adma.c +++ b/drivers/dma/tegra210-adma.c @@ -793,7 +793,7 @@ static int tegra_adma_probe(struct platform_device *pdev) ret = dma_async_device_register(&tdma->dma_dev); if (ret < 0) { dev_err(&pdev->dev, "ADMA registration failed: %d\n", ret); - goto irq_dispose; + goto rpm_put; } ret = of_dma_controller_register(pdev->dev.of_node, From e6cfc1098ef08ba5d1398f1d9c21530538d9005b Mon Sep 17 00:00:00 2001 From: "R. Parameswaran" Date: Wed, 12 Apr 2017 18:31:04 -0700 Subject: [PATCH 144/387] l2tp: device MTU setup, tunnel socket needs a lock commit 57240d007816486131bee88cd474c2a71f0fe224 upstream. The MTU overhead calculation in L2TP device set-up merged via commit b784e7ebfce8cfb16c6f95e14e8532d0768ab7ff needs to be adjusted to lock the tunnel socket while referencing the sub-data structures to derive the socket's IP overhead. Reported-by: Guillaume Nault Tested-by: Guillaume Nault Signed-off-by: R. Parameswaran Signed-off-by: David S. Miller Cc: Giuliano Procida Signed-off-by: Greg Kroah-Hartman --- include/linux/net.h | 2 +- net/l2tp/l2tp_eth.c | 2 ++ net/socket.c | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/include/linux/net.h b/include/linux/net.h index 2c8b092f3f17..54270c4707cf 100644 --- a/include/linux/net.h +++ b/include/linux/net.h @@ -298,7 +298,7 @@ int kernel_sendpage(struct socket *sock, struct page *page, int offset, int kernel_sock_ioctl(struct socket *sock, int cmd, unsigned long arg); int kernel_sock_shutdown(struct socket *sock, enum sock_shutdown_cmd how); -/* Following routine returns the IP overhead imposed by a socket. */ +/* Routine returns the IP overhead imposed by a (caller-protected) socket. */ u32 kernel_sock_ip_overhead(struct sock *sk); #define MODULE_ALIAS_NETPROTO(proto) \ diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index 60764ac2ddea..8b8fc2337960 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c @@ -240,7 +240,9 @@ static void l2tp_eth_adjust_mtu(struct l2tp_tunnel *tunnel, dev->needed_headroom += session->hdr_len; return; } + lock_sock(tunnel->sock); l3_overhead = kernel_sock_ip_overhead(tunnel->sock); + release_sock(tunnel->sock); if (l3_overhead == 0) { /* L3 Overhead couldn't be identified, this could be * because tunnel->sock was NULL or the socket's diff --git a/net/socket.c b/net/socket.c index 4892719a8a66..88abc72df2a6 100644 --- a/net/socket.c +++ b/net/socket.c @@ -3325,7 +3325,7 @@ EXPORT_SYMBOL(kernel_sock_shutdown); /* This routine returns the IP overhead imposed by a socket i.e. * the length of the underlying IP header, depending on whether * this is an IPv4 or IPv6 socket and the length from IP options turned - * on at the socket. + * on at the socket. Assumes that the caller has a lock on the socket. */ u32 kernel_sock_ip_overhead(struct sock *sk) { From bd44630a88e86d1f7cea808d1264a82ce6d1d522 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 3 Apr 2019 09:40:16 +0200 Subject: [PATCH 145/387] x86/uaccess, ubsan: Fix UBSAN vs. SMAP commit d08965a27e84ca090b504844d50c24fc98587b11 upstream. UBSAN can insert extra code in random locations; including AC=1 sections. Typically this code is not safe and needs wrapping. So far, only __ubsan_handle_type_mismatch* have been observed in AC=1 sections and therefore only those are annotated. Signed-off-by: Peter Zijlstra (Intel) Cc: Borislav Petkov Cc: Dmitry Vyukov Cc: Josh Poimboeuf Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Signed-off-by: Ingo Molnar [stable backport: only take the lib/Makefile change to resolve gcc-10 build issues] Signed-off-by: Greg Kroah-Hartman --- lib/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Makefile b/lib/Makefile index 452d2956a5a2..26fadc5d8310 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -230,5 +230,6 @@ obj-$(CONFIG_UCS2_STRING) += ucs2_string.o obj-$(CONFIG_UBSAN) += ubsan.o UBSAN_SANITIZE_ubsan.o := n +CFLAGS_ubsan.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector) obj-$(CONFIG_SBITMAP) += sbitmap.o From eff8c0335c31624795ce687845e5a66be9c3a73f Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 2 Aug 2019 21:48:58 -0700 Subject: [PATCH 146/387] ubsan: build ubsan.c more conservatively commit af700eaed0564d5d3963a7a51cb0843629d7fe3d upstream. objtool points out several conditions that it does not like, depending on the combination with other configuration options and compiler variants: stack protector: lib/ubsan.o: warning: objtool: __ubsan_handle_type_mismatch()+0xbf: call to __stack_chk_fail() with UACCESS enabled lib/ubsan.o: warning: objtool: __ubsan_handle_type_mismatch_v1()+0xbe: call to __stack_chk_fail() with UACCESS enabled stackleak plugin: lib/ubsan.o: warning: objtool: __ubsan_handle_type_mismatch()+0x4a: call to stackleak_track_stack() with UACCESS enabled lib/ubsan.o: warning: objtool: __ubsan_handle_type_mismatch_v1()+0x4a: call to stackleak_track_stack() with UACCESS enabled kasan: lib/ubsan.o: warning: objtool: __ubsan_handle_type_mismatch()+0x25: call to memcpy() with UACCESS enabled lib/ubsan.o: warning: objtool: __ubsan_handle_type_mismatch_v1()+0x25: call to memcpy() with UACCESS enabled The stackleak and kasan options just need to be disabled for this file as we do for other files already. For the stack protector, we already attempt to disable it, but this fails on clang because the check is mixed with the gcc specific -fno-conserve-stack option. According to Andrey Ryabinin, that option is not even needed, dropping it here fixes the stackprotector issue. Link: http://lkml.kernel.org/r/20190722125139.1335385-1-arnd@arndb.de Link: https://lore.kernel.org/lkml/20190617123109.667090-1-arnd@arndb.de/t/ Link: https://lore.kernel.org/lkml/20190722091050.2188664-1-arnd@arndb.de/t/ Fixes: d08965a27e84 ("x86/uaccess, ubsan: Fix UBSAN vs. SMAP") Signed-off-by: Arnd Bergmann Reviewed-by: Andrey Ryabinin Cc: Josh Poimboeuf Cc: Peter Zijlstra Cc: Arnd Bergmann Cc: Borislav Petkov Cc: Dmitry Vyukov Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Kees Cook Cc: Matthew Wilcox Cc: Ard Biesheuvel Cc: Andy Shevchenko Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- lib/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Makefile b/lib/Makefile index 26fadc5d8310..7a55c5205281 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -230,6 +230,7 @@ obj-$(CONFIG_UCS2_STRING) += ucs2_string.o obj-$(CONFIG_UBSAN) += ubsan.o UBSAN_SANITIZE_ubsan.o := n -CFLAGS_ubsan.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector) +KASAN_SANITIZE_ubsan.o := n +CFLAGS_ubsan.o := $(call cc-option, -fno-stack-protector) $(DISABLE_STACKLEAK_PLUGIN) obj-$(CONFIG_SBITMAP) += sbitmap.o From 5307944aa5e4942670ba9dcf8d9184e49c077ce2 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Sat, 30 Mar 2019 00:17:12 +0000 Subject: [PATCH 147/387] platform/x86: alienware-wmi: fix kfree on potentially uninitialized pointer commit 98e2630284ab741804bd0713e932e725466f2f84 upstream. Currently the kfree of output.pointer can be potentially freeing an uninitalized pointer in the case where out_data is NULL. Fix this by reworking the case where out_data is not-null to perform the ACPI status check and also the kfree of outpoint.pointer in one block and hence ensuring the pointer is only freed when it has been used. Also replace the if (ptr != NULL) idiom with just if (ptr). Fixes: ff0e9f26288d ("platform/x86: alienware-wmi: Correct a memory leak") Signed-off-by: Colin Ian King Signed-off-by: Darren Hart (VMware) Signed-off-by: Greg Kroah-Hartman --- drivers/platform/x86/alienware-wmi.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/platform/x86/alienware-wmi.c b/drivers/platform/x86/alienware-wmi.c index bee2115ecf10..ec7482c7e7eb 100644 --- a/drivers/platform/x86/alienware-wmi.c +++ b/drivers/platform/x86/alienware-wmi.c @@ -504,23 +504,22 @@ static acpi_status alienware_wmax_command(struct wmax_basic_args *in_args, input.length = (acpi_size) sizeof(*in_args); input.pointer = in_args; - if (out_data != NULL) { + if (out_data) { output.length = ACPI_ALLOCATE_BUFFER; output.pointer = NULL; status = wmi_evaluate_method(WMAX_CONTROL_GUID, 1, command, &input, &output); - } else + if (ACPI_SUCCESS(status)) { + obj = (union acpi_object *)output.pointer; + if (obj && obj->type == ACPI_TYPE_INTEGER) + *out_data = (u32)obj->integer.value; + } + kfree(output.pointer); + } else { status = wmi_evaluate_method(WMAX_CONTROL_GUID, 1, command, &input, NULL); - - if (ACPI_SUCCESS(status) && out_data != NULL) { - obj = (union acpi_object *)output.pointer; - if (obj && obj->type == ACPI_TYPE_INTEGER) - *out_data = (u32) obj->integer.value; } - kfree(output.pointer); return status; - } /* From da9de008fb6a9b2c0161712ec4f708f1e96b0327 Mon Sep 17 00:00:00 2001 From: Vishal Verma Date: Wed, 27 Feb 2019 17:06:26 -0700 Subject: [PATCH 148/387] libnvdimm/btt: Remove unnecessary code in btt_freelist_init [ Upstream commit 2f8c9011151337d0bc106693f272f9bddbccfab2 ] We call btt_log_read() twice, once to get the 'old' log entry, and again to get the 'new' entry. However, we have no use for the 'old' entry, so remove it. Cc: Dan Williams Signed-off-by: Vishal Verma Signed-off-by: Dan Williams Signed-off-by: Sasha Levin --- drivers/nvdimm/btt.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c index 0c46ada027cf..e90ecb179622 100644 --- a/drivers/nvdimm/btt.c +++ b/drivers/nvdimm/btt.c @@ -447,9 +447,9 @@ static int btt_log_init(struct arena_info *arena) static int btt_freelist_init(struct arena_info *arena) { - int old, new, ret; + int new, ret; u32 i, map_entry; - struct log_entry log_new, log_old; + struct log_entry log_new; arena->freelist = kcalloc(arena->nfree, sizeof(struct free_entry), GFP_KERNEL); @@ -457,10 +457,6 @@ static int btt_freelist_init(struct arena_info *arena) return -ENOMEM; for (i = 0; i < arena->nfree; i++) { - old = btt_log_read(arena, i, &log_old, LOG_OLD_ENT); - if (old < 0) - return old; - new = btt_log_read(arena, i, &log_new, LOG_NEW_ENT); if (new < 0) return new; From 138545f91bb6b766322007b40bf1200253b8e65b Mon Sep 17 00:00:00 2001 From: Arjun Vynipadath Date: Fri, 9 Nov 2018 14:50:25 +0530 Subject: [PATCH 149/387] cxgb4: free mac_hlist properly [ Upstream commit 2a8d84bf513823ba398f4b2dec41b8decf4041af ] The locally maintained list for tracking hash mac table was not freed during driver remove. Signed-off-by: Arjun Vynipadath Signed-off-by: Ganesh Goudar Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 5478a2ab45c4..821f68baa55c 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -2251,6 +2251,8 @@ static int cxgb_up(struct adapter *adap) static void cxgb_down(struct adapter *adapter) { + struct hash_mac_addr *entry, *tmp; + cancel_work_sync(&adapter->tid_release_task); cancel_work_sync(&adapter->db_full_task); cancel_work_sync(&adapter->db_drop_task); @@ -2259,6 +2261,12 @@ static void cxgb_down(struct adapter *adapter) t4_sge_stop(adapter); t4_free_sge_resources(adapter); + + list_for_each_entry_safe(entry, tmp, &adapter->mac_hlist, list) { + list_del(&entry->list); + kfree(entry); + } + adapter->flags &= ~FULL_INIT_DONE; } From 51077718a61ee9ef654e37811fe5fab5f80e60e8 Mon Sep 17 00:00:00 2001 From: Arjun Vynipadath Date: Tue, 20 Nov 2018 12:11:39 +0530 Subject: [PATCH 150/387] cxgb4/cxgb4vf: Fix mac_hlist initialization and free [ Upstream commit b539ea60f5043b9acd7562f04fa2117f18776cbb ] Null pointer dereference seen when cxgb4vf driver is unloaded without bringing up any interfaces, moving mac_hlist initialization to driver probe and free the mac_hlist in remove to fix the issue. Fixes: 24357e06ba51 ("cxgb4vf: fix memleak in mac_hlist initialization") Signed-off-by: Arjun Vynipadath Signed-off-by: Casey Leedom Signed-off-by: Ganesh Goudar Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- .../net/ethernet/chelsio/cxgb4/cxgb4_main.c | 19 ++++++++++--------- .../ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | 6 +++--- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 821f68baa55c..54b5f61c8ed9 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -2236,8 +2236,6 @@ static int cxgb_up(struct adapter *adap) #if IS_ENABLED(CONFIG_IPV6) update_clip(adap); #endif - /* Initialize hash mac addr list*/ - INIT_LIST_HEAD(&adap->mac_hlist); return err; irq_err: @@ -2251,8 +2249,6 @@ static int cxgb_up(struct adapter *adap) static void cxgb_down(struct adapter *adapter) { - struct hash_mac_addr *entry, *tmp; - cancel_work_sync(&adapter->tid_release_task); cancel_work_sync(&adapter->db_full_task); cancel_work_sync(&adapter->db_drop_task); @@ -2262,11 +2258,6 @@ static void cxgb_down(struct adapter *adapter) t4_sge_stop(adapter); t4_free_sge_resources(adapter); - list_for_each_entry_safe(entry, tmp, &adapter->mac_hlist, list) { - list_del(&entry->list); - kfree(entry); - } - adapter->flags &= ~FULL_INIT_DONE; } @@ -4797,6 +4788,9 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) (is_t5(adapter->params.chip) ? STATMODE_V(0) : T6_STATMODE_V(0))); + /* Initialize hash mac addr list */ + INIT_LIST_HEAD(&adapter->mac_hlist); + for_each_port(adapter, i) { netdev = alloc_etherdev_mq(sizeof(struct port_info), MAX_ETH_QSETS); @@ -5075,6 +5069,7 @@ sriov: static void remove_one(struct pci_dev *pdev) { struct adapter *adapter = pci_get_drvdata(pdev); + struct hash_mac_addr *entry, *tmp; if (!adapter) { pci_release_regions(pdev); @@ -5113,6 +5108,12 @@ static void remove_one(struct pci_dev *pdev) if (adapter->num_uld || adapter->num_ofld_uld) t4_uld_mem_free(adapter); free_some_resources(adapter); + list_for_each_entry_safe(entry, tmp, &adapter->mac_hlist, + list) { + list_del(&entry->list); + kfree(entry); + } + #if IS_ENABLED(CONFIG_IPV6) t4_cleanup_clip_tbl(adapter); #endif diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 9eb3071b69a4..17db5be9d2b7 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -719,9 +719,6 @@ static int adapter_up(struct adapter *adapter) if (adapter->flags & USING_MSIX) name_msix_vecs(adapter); - /* Initialize hash mac addr list*/ - INIT_LIST_HEAD(&adapter->mac_hlist); - adapter->flags |= FULL_INIT_DONE; } @@ -2902,6 +2899,9 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev, if (err) goto err_unmap_bar; + /* Initialize hash mac addr list */ + INIT_LIST_HEAD(&adapter->mac_hlist); + /* * Allocate our "adapter ports" and stitch everything together. */ From f085290608d81f76b36687b595f8eb6d49467e73 Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Fri, 8 May 2020 15:01:25 -0500 Subject: [PATCH 151/387] Revert "gfs2: Don't demote a glock until its revokes are written" [ Upstream commit b14c94908b1b884276a6608dea3d0b1b510338b7 ] This reverts commit df5db5f9ee112e76b5202fbc331f990a0fc316d6. This patch fixes a regression: patch df5db5f9ee112 allowed function run_queue() to bypass its call to do_xmote() if revokes were queued for the glock. That's wrong because its call to do_xmote() is what is responsible for calling the go_sync() glops functions to sync both the ail list and any revokes queued for it. By bypassing the call, gfs2 could get into a stand-off where the glock could not be demoted until its revokes are written back, but the revokes would not be written back because do_xmote() was never called. It "sort of" works, however, because there are other mechanisms like the log flush daemon (logd) that can sync the ail items and revokes, if it deems it necessary. The problem is: without file system pressure, it might never deem it necessary. Signed-off-by: Bob Peterson Signed-off-by: Sasha Levin --- fs/gfs2/glock.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index adc1a97cfe96..efd44d5645d8 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -548,9 +548,6 @@ __acquires(&gl->gl_lockref.lock) goto out_unlock; if (nonblock) goto out_sched; - smp_mb(); - if (atomic_read(&gl->gl_revokes) != 0) - goto out_sched; set_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags); GLOCK_BUG_ON(gl, gl->gl_demote_state == LM_ST_EXCLUSIVE); gl->gl_target = gl->gl_demote_state; From 15e86bf56dc28d43656c5e3a910e689dd7301a40 Mon Sep 17 00:00:00 2001 From: Dragos Bogdan Date: Wed, 29 Apr 2020 10:21:29 +0300 Subject: [PATCH 152/387] staging: iio: ad2s1210: Fix SPI reading commit 5e4f99a6b788047b0b8a7496c2e0c8f372f6edf2 upstream. If the serial interface is used, the 8-bit address should be latched using the rising edge of the WR/FSYNC signal. This basically means that a CS change is required between the first byte sent, and the second one. This change splits the single-transfer transfer of 2 bytes into 2 transfers with a single byte, and CS change in-between. Note fixes tag is not accurate, but reflects a point beyond which there are too many refactors to make backporting straight forward. Fixes: b19e9ad5e2cb ("staging:iio:resolver:ad2s1210 general driver cleanup.") Signed-off-by: Dragos Bogdan Signed-off-by: Alexandru Ardelean Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/resolver/ad2s1210.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c index 598f0faa48c8..0f5eb2bf5f73 100644 --- a/drivers/staging/iio/resolver/ad2s1210.c +++ b/drivers/staging/iio/resolver/ad2s1210.c @@ -126,17 +126,24 @@ static int ad2s1210_config_write(struct ad2s1210_state *st, u8 data) static int ad2s1210_config_read(struct ad2s1210_state *st, unsigned char address) { - struct spi_transfer xfer = { - .len = 2, - .rx_buf = st->rx, - .tx_buf = st->tx, + struct spi_transfer xfers[] = { + { + .len = 1, + .rx_buf = &st->rx[0], + .tx_buf = &st->tx[0], + .cs_change = 1, + }, { + .len = 1, + .rx_buf = &st->rx[1], + .tx_buf = &st->tx[1], + }, }; int ret = 0; ad2s1210_set_mode(MOD_CONFIG, st); st->tx[0] = address | AD2S1210_MSB_IS_HIGH; st->tx[1] = AD2S1210_REG_FAULT; - ret = spi_sync_transfer(st->sdev, &xfer, 1); + ret = spi_sync_transfer(st->sdev, xfers, 2); if (ret < 0) return ret; st->old_data = true; From b193514ac4befbe45cad13abfe8f7df3e1e3e92a Mon Sep 17 00:00:00 2001 From: Oscar Carter Date: Sun, 10 May 2020 12:14:26 +0200 Subject: [PATCH 153/387] staging: greybus: Fix uninitialized scalar variable commit 34625c1931f8204c234c532b446b9f53c69f4b68 upstream. In the "gb_tty_set_termios" function the "newline" variable is declared but not initialized. So the "flow_control" member is not initialized and the OR / AND operations with itself results in an undefined value in this member. The purpose of the code is to set the flow control type, so remove the OR / AND self operator and set the value directly. Addresses-Coverity-ID: 1374016 ("Uninitialized scalar variable") Fixes: e55c25206d5c9 ("greybus: uart: Handle CRTSCTS flag in termios") Signed-off-by: Oscar Carter Cc: stable Link: https://lore.kernel.org/r/20200510101426.23631-1-oscar.carter@gmx.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/uart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c index 2633d2bfb1b4..9ef9cbfd8926 100644 --- a/drivers/staging/greybus/uart.c +++ b/drivers/staging/greybus/uart.c @@ -539,9 +539,9 @@ static void gb_tty_set_termios(struct tty_struct *tty, } if (C_CRTSCTS(tty) && C_BAUD(tty) != B0) - newline.flow_control |= GB_SERIAL_AUTO_RTSCTS_EN; + newline.flow_control = GB_SERIAL_AUTO_RTSCTS_EN; else - newline.flow_control &= ~GB_SERIAL_AUTO_RTSCTS_EN; + newline.flow_control = 0; if (memcmp(&gb_tty->line_coding, &newline, sizeof(newline))) { memcpy(&gb_tty->line_coding, &newline, sizeof(newline)); From 119590e9db9738f274343fac14ad4109d957f364 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 26 Apr 2020 21:44:03 +0200 Subject: [PATCH 154/387] iio: dac: vf610: Fix an error handling path in 'vf610_dac_probe()' commit aad4742fbf0a560c25827adb58695a4497ffc204 upstream. A call to 'vf610_dac_exit()' is missing in an error handling path. Fixes: 1b983bf42fad ("iio: dac: vf610_dac: Add IIO DAC driver for Vybrid SoC") Signed-off-by: Christophe JAILLET Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/dac/vf610_dac.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/iio/dac/vf610_dac.c b/drivers/iio/dac/vf610_dac.c index c4ec7779b394..190a7c1c5604 100644 --- a/drivers/iio/dac/vf610_dac.c +++ b/drivers/iio/dac/vf610_dac.c @@ -235,6 +235,7 @@ static int vf610_dac_probe(struct platform_device *pdev) return 0; error_iio_device_register: + vf610_dac_exit(info); clk_disable_unprepare(info->clk); return ret; From ca2e298cb7ebb1bb3725f6492892057d3b5d70a0 Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Wed, 13 May 2020 01:31:40 +0300 Subject: [PATCH 155/387] mei: release me_cl object reference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit fc9c03ce30f79b71807961bfcb42be191af79873 upstream. Allow me_cl object to be freed by releasing the reference that was acquired by one of the search functions: __mei_me_cl_by_uuid_id() or __mei_me_cl_by_uuid() Cc: Reported-by: 亿一 Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Link: https://lore.kernel.org/r/20200512223140.32186-1-tomas.winkler@intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/client.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 451d417eb451..1c8df33404b0 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -276,6 +276,7 @@ void mei_me_cl_rm_by_uuid(struct mei_device *dev, const uuid_le *uuid) down_write(&dev->me_clients_rwsem); me_cl = __mei_me_cl_by_uuid(dev, uuid); __mei_me_cl_del(dev, me_cl); + mei_me_cl_put(me_cl); up_write(&dev->me_clients_rwsem); } @@ -297,6 +298,7 @@ void mei_me_cl_rm_by_uuid_id(struct mei_device *dev, const uuid_le *uuid, u8 id) down_write(&dev->me_clients_rwsem); me_cl = __mei_me_cl_by_uuid_id(dev, uuid, id); __mei_me_cl_del(dev, me_cl); + mei_me_cl_put(me_cl); up_write(&dev->me_clients_rwsem); } From ba324dbbc25fa83c3e569a5f43b0bd69350ae722 Mon Sep 17 00:00:00 2001 From: John Hubbard Date: Fri, 22 May 2020 22:22:48 -0700 Subject: [PATCH 156/387] rapidio: fix an error in get_user_pages_fast() error handling commit ffca476a0a8d26de767cc41d62b8ca7f540ecfdd upstream. In the case of get_user_pages_fast() returning fewer pages than requested, rio_dma_transfer() does not quite do the right thing. It attempts to release all the pages that were requested, rather than just the pages that were pinned. Fix the error handling so that only the pages that were successfully pinned are released. Fixes: e8de370188d0 ("rapidio: add mport char device driver") Signed-off-by: John Hubbard Signed-off-by: Andrew Morton Reviewed-by: Andrew Morton Cc: Matt Porter Cc: Alexandre Bounine Cc: Sumit Semwal Cc: Dan Carpenter Cc: Link: http://lkml.kernel.org/r/20200517235620.205225-2-jhubbard@nvidia.com Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/rapidio/devices/rio_mport_cdev.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/rapidio/devices/rio_mport_cdev.c b/drivers/rapidio/devices/rio_mport_cdev.c index 28c45db45aba..ebe8e8dc4677 100644 --- a/drivers/rapidio/devices/rio_mport_cdev.c +++ b/drivers/rapidio/devices/rio_mport_cdev.c @@ -905,6 +905,11 @@ rio_dma_transfer(struct file *filp, u32 transfer_mode, rmcd_error("pinned %ld out of %ld pages", pinned, nr_pages); ret = -EFAULT; + /* + * Set nr_pages up to mean "how many pages to unpin, in + * the error handler: + */ + nr_pages = pinned; goto err_pg; } From 5bb2fcf9eb24fe9aea2daafcca1e1694e1d85da0 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Wed, 6 May 2020 05:52:06 +0200 Subject: [PATCH 157/387] iio: sca3000: Remove an erroneous 'get_device()' [ Upstream commit 928edefbc18cd8433f7df235c6e09a9306e7d580 ] This looks really unusual to have a 'get_device()' hidden in a 'dev_err()' call. Remove it. While at it add a missing \n at the end of the message. Fixes: 574fb258d636 ("Staging: IIO: VTI sca3000 series accelerometer driver (spi)") Signed-off-by: Christophe JAILLET Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin --- drivers/staging/iio/accel/sca3000_ring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c index d1cb9b9cf22b..391cbcc4ed77 100644 --- a/drivers/staging/iio/accel/sca3000_ring.c +++ b/drivers/staging/iio/accel/sca3000_ring.c @@ -56,7 +56,7 @@ static int sca3000_read_data(struct sca3000_state *st, st->tx[0] = SCA3000_READ_REG(reg_address_high); ret = spi_sync_transfer(st->us, xfer, ARRAY_SIZE(xfer)); if (ret) { - dev_err(get_device(&st->us->dev), "problem reading register"); + dev_err(&st->us->dev, "problem reading register"); goto error_free_rx; } From 82dddebfe7da9d2670977ab723da2fdac3eff5b0 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 27 May 2020 16:42:03 +0200 Subject: [PATCH 158/387] Linux 4.9.225 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 3e58c142f92f..d17a2ad3cc4d 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 4 PATCHLEVEL = 9 -SUBLEVEL = 224 +SUBLEVEL = 225 EXTRAVERSION = NAME = Roaring Lionus From c2b163fd6901f81643a072fa022ece27d59ee581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= Date: Thu, 28 May 2020 04:44:40 -0700 Subject: [PATCH 159/387] ANDROID: cuttlefish defconfig - enable mount/net/uts namespaces. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These configs are the default for qemu backed kernel net tests. This matches: https://android-review.googlesource.com/c/kernel/configs/+/1320157 R+: require mount/net/uts namespace support Generated via: echo 'CONFIG_NAMESPACES=y' >> arch/arm64/configs/cuttlefish_defconfig make ARCH=arm64 cuttlefish_defconfig make ARCH=arm64 savedefconfig mv defconfig arch/arm64/configs/cuttlefish_defconfig Test: treehugger Bug: 144061615 Signed-off-by: Maciej Żenczykowski Change-Id: I1e15dc04116155ede485dd0458f55ee405fb285c --- arch/arm64/configs/cuttlefish_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig index 5e27eeb23d8a..f1b3aa19524f 100644 --- a/arch/arm64/configs/cuttlefish_defconfig +++ b/arch/arm64/configs/cuttlefish_defconfig @@ -18,6 +18,7 @@ CONFIG_MEMCG=y CONFIG_MEMCG_SWAP=y CONFIG_RT_GROUP_SCHED=y CONFIG_CGROUP_BPF=y +CONFIG_NAMESPACES=y CONFIG_SCHED_AUTOGROUP=y CONFIG_SCHED_TUNE=y CONFIG_DEFAULT_USE_ENERGY_AWARE=y From decc637b580f7b021f020ee573c1419141eceef4 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 19 May 2020 18:24:43 -0700 Subject: [PATCH 160/387] ax25: fix setsockopt(SO_BINDTODEVICE) [ Upstream commit 687775cec056b38a4c8f3291e0dd7a9145f7b667 ] syzbot was able to trigger this trace [1], probably by using a zero optlen. While we are at it, cap optlen to IFNAMSIZ - 1 instead of IFNAMSIZ. [1] BUG: KMSAN: uninit-value in strnlen+0xf9/0x170 lib/string.c:569 CPU: 0 PID: 8807 Comm: syz-executor483 Not tainted 5.7.0-rc4-syzkaller #0 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+0x1c9/0x220 lib/dump_stack.c:118 kmsan_report+0xf7/0x1e0 mm/kmsan/kmsan_report.c:121 __msan_warning+0x58/0xa0 mm/kmsan/kmsan_instr.c:215 strnlen+0xf9/0x170 lib/string.c:569 dev_name_hash net/core/dev.c:207 [inline] netdev_name_node_lookup net/core/dev.c:277 [inline] __dev_get_by_name+0x75/0x2b0 net/core/dev.c:778 ax25_setsockopt+0xfa3/0x1170 net/ax25/af_ax25.c:654 __compat_sys_setsockopt+0x4ed/0x910 net/compat.c:403 __do_compat_sys_setsockopt net/compat.c:413 [inline] __se_compat_sys_setsockopt+0xdd/0x100 net/compat.c:410 __ia32_compat_sys_setsockopt+0x62/0x80 net/compat.c:410 do_syscall_32_irqs_on arch/x86/entry/common.c:339 [inline] do_fast_syscall_32+0x3bf/0x6d0 arch/x86/entry/common.c:398 entry_SYSENTER_compat+0x68/0x77 arch/x86/entry/entry_64_compat.S:139 RIP: 0023:0xf7f57dd9 Code: 90 e8 0b 00 00 00 f3 90 0f ae e8 eb f9 8d 74 26 00 89 3c 24 c3 90 90 90 90 90 90 90 90 90 90 90 90 51 52 55 89 e5 0f 34 cd 80 <5d> 5a 59 c3 90 90 90 90 eb 0d 90 90 90 90 90 90 90 90 90 90 90 90 RSP: 002b:00000000ffae8c1c EFLAGS: 00000217 ORIG_RAX: 000000000000016e RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 0000000000000101 RDX: 0000000000000019 RSI: 0000000020000000 RDI: 0000000000000004 RBP: 0000000000000012 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 Local variable ----devname@ax25_setsockopt created at: ax25_setsockopt+0xe6/0x1170 net/ax25/af_ax25.c:536 ax25_setsockopt+0xe6/0x1170 net/ax25/af_ax25.c:536 Fixes: 1da177e4c3f4 ("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/ax25/af_ax25.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index de55a3f001dc..02be8ee23271 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -639,8 +639,10 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname, break; case SO_BINDTODEVICE: - if (optlen > IFNAMSIZ) - optlen = IFNAMSIZ; + if (optlen > IFNAMSIZ - 1) + optlen = IFNAMSIZ - 1; + + memset(devname, 0, sizeof(devname)); if (copy_from_user(devname, optval, optlen)) { res = -EFAULT; From 72e2d903bda5aeb9ead15bd539f0d4ae048aab9e Mon Sep 17 00:00:00 2001 From: Vadim Fedorenko Date: Wed, 20 May 2020 11:50:48 +0300 Subject: [PATCH 161/387] net: ipip: fix wrong address family in init error path [ Upstream commit 57ebc8f08504f176eb0f25b3e0fde517dec61a4f ] In case of error with MPLS support the code is misusing AF_INET instead of AF_MPLS. Fixes: 1b69e7e6c4da ("ipip: support MPLS over IPv4") Signed-off-by: Vadim Fedorenko Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/ipv4/ipip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 56d71a004dce..bd23a2d01b6c 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -689,7 +689,7 @@ out: rtnl_link_failed: #if IS_ENABLED(CONFIG_MPLS) - xfrm4_tunnel_deregister(&mplsip_handler, AF_INET); + xfrm4_tunnel_deregister(&mplsip_handler, AF_MPLS); xfrm_tunnel_mplsip_failed: #endif From f08aeb334b8511d1589bbb2f5da02cd3e2543751 Mon Sep 17 00:00:00 2001 From: Yuqi Jin Date: Sat, 16 May 2020 11:46:49 +0800 Subject: [PATCH 162/387] net: revert "net: get rid of an signed integer overflow in ip_idents_reserve()" [ Upstream commit a6211caa634da39d861a47437ffcda8b38ef421b ] Commit adb03115f459 ("net: get rid of an signed integer overflow in ip_idents_reserve()") used atomic_cmpxchg to replace "atomic_add_return" inside the function "ip_idents_reserve". The reason was to avoid UBSAN warning. However, this change has caused performance degrade and in GCC-8, fno-strict-overflow is now mapped to -fwrapv -fwrapv-pointer and signed integer overflow is now undefined by default at all optimization levels[1]. Moreover, it was a bug in UBSAN vs -fwrapv /-fno-strict-overflow, so Let's revert it safely. [1] https://gcc.gnu.org/gcc-8/changes.html Suggested-by: Peter Zijlstra Suggested-by: Eric Dumazet Cc: "David S. Miller" Cc: Alexey Kuznetsov Cc: Hideaki YOSHIFUJI Cc: Jakub Kicinski Cc: Jiri Pirko Cc: Arvind Sankar Cc: Peter Zijlstra Cc: Eric Dumazet Cc: Jiong Wang Signed-off-by: Yuqi Jin Signed-off-by: Shaokun Zhang Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/ipv4/route.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 81efd2d3998d..c8c51bd2d695 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -477,18 +477,16 @@ u32 ip_idents_reserve(u32 hash, int segs) atomic_t *p_id = ip_idents + hash % IP_IDENTS_SZ; u32 old = ACCESS_ONCE(*p_tstamp); u32 now = (u32)jiffies; - u32 new, delta = 0; + u32 delta = 0; if (old != now && cmpxchg(p_tstamp, old, now) == old) delta = prandom_u32_max(now - old); - /* Do not use atomic_add_return() as it makes UBSAN unhappy */ - do { - old = (u32)atomic_read(p_id); - new = old + delta + segs; - } while (atomic_cmpxchg(p_id, old, new) != old); - - return new - segs; + /* If UBSAN reports an error there, please make sure your compiler + * supports -fno-strict-overflow before reporting it that was a bug + * in UBSAN, and it has been fixed in GCC-8. + */ + return atomic_add_return(segs + delta, p_id) - segs; } EXPORT_SYMBOL(ip_idents_reserve); From 9a729a479898d82eda151e7759589ef8e440a809 Mon Sep 17 00:00:00 2001 From: Roman Mashak Date: Sun, 17 May 2020 08:46:31 -0400 Subject: [PATCH 163/387] net sched: fix reporting the first-time use timestamp [ Upstream commit b15e62631c5f19fea9895f7632dae9c1b27fe0cd ] When a new action is installed, firstuse field of 'tcf_t' is explicitly set to 0. Value of zero means "new action, not yet used"; as a packet hits the action, 'firstuse' is stamped with the current jiffies value. tcf_tm_dump() should return 0 for firstuse if action has not yet been hit. Fixes: 48d8ee1694dd ("net sched actions: aggregate dumping of actions timeinfo") Cc: Jamal Hadi Salim Signed-off-by: Roman Mashak Acked-by: Jamal Hadi Salim Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- include/net/act_api.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/net/act_api.h b/include/net/act_api.h index 82f3c912a5b1..051b90779708 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -94,7 +94,8 @@ static inline void tcf_tm_dump(struct tcf_t *dtm, const struct tcf_t *stm) { dtm->install = jiffies_to_clock_t(jiffies - stm->install); dtm->lastuse = jiffies_to_clock_t(jiffies - stm->lastuse); - dtm->firstuse = jiffies_to_clock_t(jiffies - stm->firstuse); + dtm->firstuse = stm->firstuse ? + jiffies_to_clock_t(jiffies - stm->firstuse) : 0; dtm->expires = jiffies_to_clock_t(stm->expires); } From 5e350e7c1e8d438f433c8d62f191af2a48731d03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jere=20Lepp=C3=A4nen?= Date: Wed, 20 May 2020 18:15:31 +0300 Subject: [PATCH 164/387] sctp: Start shutdown on association restart if in SHUTDOWN-SENT state and socket is closed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit d3e8e4c11870413789f029a71e72ae6e971fe678 ] Commit bdf6fa52f01b ("sctp: handle association restarts when the socket is closed.") starts shutdown when an association is restarted, if in SHUTDOWN-PENDING state and the socket is closed. However, the rationale stated in that commit applies also when in SHUTDOWN-SENT state - we don't want to move an association to ESTABLISHED state when the socket has been closed, because that results in an association that is unreachable from user space. The problem scenario: 1. Client crashes and/or restarts. 2. Server (using one-to-one socket) calls close(). SHUTDOWN is lost. 3. Client reconnects using the same addresses and ports. 4. Server's association is restarted. The association and the socket move to ESTABLISHED state, even though the server process has closed its descriptor. Also, after step 4 when the server process exits, some resources are leaked in an attempt to release the underlying inet sock structure in ESTABLISHED state: IPv4: Attempt to release TCP socket in state 1 00000000377288c7 Fix by acting the same way as in SHUTDOWN-PENDING state. That is, if an association is restarted in SHUTDOWN-SENT state and the socket is closed, then start shutdown and don't move the association or the socket to ESTABLISHED state. Fixes: bdf6fa52f01b ("sctp: handle association restarts when the socket is closed.") Signed-off-by: Jere Leppänen Acked-by: Marcelo Ricardo Leitner Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/sctp/sm_statefuns.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 1a3c75347f48..146b568962e0 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -1793,12 +1793,13 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(struct net *net, /* Update the content of current association. */ sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc)); sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev)); - if (sctp_state(asoc, SHUTDOWN_PENDING) && + if ((sctp_state(asoc, SHUTDOWN_PENDING) || + sctp_state(asoc, SHUTDOWN_SENT)) && (sctp_sstate(asoc->base.sk, CLOSING) || sock_flag(asoc->base.sk, SOCK_DEAD))) { - /* if were currently in SHUTDOWN_PENDING, but the socket - * has been closed by user, don't transition to ESTABLISHED. - * Instead trigger SHUTDOWN bundled with COOKIE_ACK. + /* If the socket has been closed by user, don't + * transition to ESTABLISHED. Instead trigger SHUTDOWN + * bundled with COOKIE_ACK. */ sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); return sctp_sf_do_9_2_start_shutdown(net, ep, asoc, From b651a0112a36fe4ee02f769c2c87de0ad7498771 Mon Sep 17 00:00:00 2001 From: Moshe Shemesh Date: Tue, 7 Apr 2020 17:38:28 +0300 Subject: [PATCH 165/387] net/mlx5e: Update netdev txq on completions during closure [ Upstream commit 5e911e2c06bd8c17df29147a5e2d4b17fafda024 ] On sq closure when we free its descriptors, we should also update netdev txq on completions which would not arrive. Otherwise if we reopen sqs and attach them back, for example on fw fatal recovery flow, we may get tx timeout. Fixes: 29429f3300a3 ("net/mlx5e: Timeout if SQ doesn't flush during close") Signed-off-by: Moshe Shemesh Reviewed-by: Tariq Toukan Signed-off-by: Saeed Mahameed Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mellanox/mlx5/core/en_tx.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c index 574311018e6f..f0a6b72497da 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c @@ -499,8 +499,9 @@ bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget) static void mlx5e_free_txq_sq_descs(struct mlx5e_sq *sq) { struct mlx5e_tx_wqe_info *wi; + u32 nbytes = 0; + u16 ci, npkts = 0; struct sk_buff *skb; - u16 ci; int i; while (sq->cc != sq->pc) { @@ -521,8 +522,11 @@ static void mlx5e_free_txq_sq_descs(struct mlx5e_sq *sq) } dev_kfree_skb_any(skb); + npkts++; + nbytes += wi->num_bytes; sq->cc += wi->num_wqebbs; } + netdev_tx_completed_queue(sq->txq, npkts, nbytes); } static void mlx5e_free_xdp_sq_descs(struct mlx5e_sq *sq) From 4b55bd396f4809cddb6c9c70db49eaf8d0d3df06 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Tue, 19 May 2020 23:44:16 +0530 Subject: [PATCH 166/387] net: qrtr: Fix passing invalid reference to qrtr_local_enqueue() [ Upstream commit d28ea1fbbf437054ef339afec241019f2c4e2bb6 ] Once the traversal of the list is completed with list_for_each_entry(), the iterator (node) will point to an invalid object. So passing this to qrtr_local_enqueue() which is outside of the iterator block is erroneous eventhough the object is not used. So fix this by passing NULL to qrtr_local_enqueue(). Fixes: bdabad3e363d ("net: Add Qualcomm IPC router") Reported-by: kbuild test robot Reported-by: Julia Lawall Signed-off-by: Manivannan Sadhasivam Reviewed-by: Bjorn Andersson Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/qrtr/qrtr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c index 41547c6e496a..a8253079902f 100644 --- a/net/qrtr/qrtr.c +++ b/net/qrtr/qrtr.c @@ -571,7 +571,7 @@ static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb) } mutex_unlock(&qrtr_node_lock); - qrtr_local_enqueue(node, skb); + qrtr_local_enqueue(NULL, skb); return 0; } From 87959b0f5a5842409ca3ad584a98293873d120d4 Mon Sep 17 00:00:00 2001 From: Moshe Shemesh Date: Fri, 27 Dec 2019 07:01:53 +0200 Subject: [PATCH 167/387] net/mlx5: Add command entry handling completion [ Upstream commit 17d00e839d3b592da9659c1977d45f85b77f986a ] When FW response to commands is very slow and all command entries in use are waiting for completion we can have a race where commands can get timeout before they get out of the queue and handled. Timeout completion on uninitialized command will cause releasing command's buffers before accessing it for initialization and then we will get NULL pointer exception while trying access it. It may also cause releasing buffers of another command since we may have timeout completion before even allocating entry index for this command. Add entry handling completion to avoid this race. Fixes: e126ba97dba9 ("mlx5: Add driver for Mellanox Connect-IB adapters") Signed-off-by: Moshe Shemesh Signed-off-by: Eran Ben Elisha Signed-off-by: Saeed Mahameed Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 15 +++++++++++++++ include/linux/mlx5/driver.h | 1 + 2 files changed, 16 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c index bb142a13d9f2..b6113620cb1a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c @@ -786,6 +786,7 @@ static void cmd_work_handler(struct work_struct *work) int alloc_ret; int cmd_mode; + complete(&ent->handling); sem = ent->page_queue ? &cmd->pages_sem : &cmd->sem; down(sem); if (!ent->page_queue) { @@ -904,6 +905,12 @@ static int wait_func(struct mlx5_core_dev *dev, struct mlx5_cmd_work_ent *ent) struct mlx5_cmd *cmd = &dev->cmd; int err; + if (!wait_for_completion_timeout(&ent->handling, timeout) && + cancel_work_sync(&ent->work)) { + ent->ret = -ECANCELED; + goto out_err; + } + if (cmd->mode == CMD_MODE_POLLING) { wait_for_completion(&ent->done); } else if (!wait_for_completion_timeout(&ent->done, timeout)) { @@ -911,12 +918,17 @@ static int wait_func(struct mlx5_core_dev *dev, struct mlx5_cmd_work_ent *ent) mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true); } +out_err: err = ent->ret; if (err == -ETIMEDOUT) { mlx5_core_warn(dev, "%s(0x%x) timeout. Will cause a leak of a command resource\n", mlx5_command_str(msg_to_opcode(ent->in)), msg_to_opcode(ent->in)); + } else if (err == -ECANCELED) { + mlx5_core_warn(dev, "%s(0x%x) canceled on out of queue timeout.\n", + mlx5_command_str(msg_to_opcode(ent->in)), + msg_to_opcode(ent->in)); } mlx5_core_dbg(dev, "err %d, delivery status %s(%d)\n", err, deliv_status_to_str(ent->status), ent->status); @@ -951,6 +963,7 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in, ent->token = token; + init_completion(&ent->handling); if (!callback) init_completion(&ent->done); @@ -970,6 +983,8 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in, err = wait_func(dev, ent); if (err == -ETIMEDOUT) goto out; + if (err == -ECANCELED) + goto out_free; ds = ent->ts2 - ent->ts1; op = MLX5_GET(mbox_in, in->first.data, opcode); diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index 509e99076c57..6094e4a3a0a4 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h @@ -656,6 +656,7 @@ struct mlx5_cmd_work_ent { struct delayed_work cb_timeout_work; void *context; int idx; + struct completion handling; struct completion done; struct mlx5_cmd *cmd; struct work_struct work; From 6a6237db07083785de882a3147f76bba78d372c0 Mon Sep 17 00:00:00 2001 From: Qiushi Wu Date: Fri, 22 May 2020 16:50:27 -0500 Subject: [PATCH 168/387] net: sun: fix missing release regions in cas_init_one(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 5a730153984dd13f82ffae93d7170d76eba204e9 upstream. In cas_init_one(), "pdev" is requested by "pci_request_regions", but it was not released after a call of the function “pci_write_config_byte” failed. Thus replace the jump target “err_write_cacheline” by "err_out_free_res". Fixes: 1f26dac32057 ("[NET]: Add Sun Cassini driver.") Signed-off-by: Qiushi Wu Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/sun/cassini.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/ethernet/sun/cassini.c b/drivers/net/ethernet/sun/cassini.c index 062bce9acde6..bfe7b55f9714 100644 --- a/drivers/net/ethernet/sun/cassini.c +++ b/drivers/net/ethernet/sun/cassini.c @@ -4980,7 +4980,7 @@ static int cas_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) cas_cacheline_size)) { dev_err(&pdev->dev, "Could not set PCI cache " "line size\n"); - goto err_write_cacheline; + goto err_out_free_res; } } #endif @@ -5151,7 +5151,6 @@ err_out_iounmap: err_out_free_res: pci_release_regions(pdev); -err_write_cacheline: /* Try to restore it in case the error occurred after we * set it. */ From 2256bf0ea08fe75111a8aa8085cbc2b3e7be09a5 Mon Sep 17 00:00:00 2001 From: Qiushi Wu Date: Fri, 22 May 2020 14:07:15 -0500 Subject: [PATCH 169/387] net/mlx4_core: fix a memory leak bug. commit febfd9d3c7f74063e8e630b15413ca91b567f963 upstream. In function mlx4_opreq_action(), pointer "mailbox" is not released, when mlx4_cmd_box() return and error, causing a memory leak bug. Fix this issue by going to "out" label, mlx4_free_cmd_mailbox() can free this pointer. Fixes: fe6f700d6cbb ("net/mlx4_core: Respond to operation request by firmware") Signed-off-by: Qiushi Wu Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mellanox/mlx4/fw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 9af0887c8a29..fe9dc1b3078c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c @@ -2704,7 +2704,7 @@ void mlx4_opreq_action(struct work_struct *work) if (err) { mlx4_err(dev, "Failed to retrieve required operation: %d\n", err); - return; + goto out; } MLX4_GET(modifier, outbox, GET_OP_REQ_MODIFIER_OFFSET); MLX4_GET(token, outbox, GET_OP_REQ_TOKEN_OFFSET); From b3a6fd241fc80874fc60ceac545e703dcb8e685b Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Wed, 15 Feb 2017 05:23:26 +0300 Subject: [PATCH 170/387] uapi: fix linux/if_pppol2tp.h userspace compilation errors commit a725eb15db80643a160310ed6bcfd6c5a6c907f2 upstream. Because of interface limitations, provided by libc cannot be included after , therefore any header that includes cannot be included after . Change uapi/linux/l2tp.h, the last uapi header that includes , to include and instead of and use __SOCK_SIZE__ instead of sizeof(struct sockaddr) the same way as uapi/linux/in.h does, to fix linux/if_pppol2tp.h userspace compilation errors like this: In file included from /usr/include/linux/l2tp.h:12:0, from /usr/include/linux/if_pppol2tp.h:21, /usr/include/netinet/in.h:31:8: error: redefinition of 'struct in_addr' Fixes: 47c3e7783be4 ("net: l2tp: deprecate PPPOL2TP_MSG_* in favour of L2TP_MSG_*") Signed-off-by: Dmitry V. Levin Signed-off-by: David S. Miller Signed-off-by: Asbjoern Sloth Toennesen Signed-off-by: Greg Kroah-Hartman --- include/uapi/linux/l2tp.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/include/uapi/linux/l2tp.h b/include/uapi/linux/l2tp.h index bb2d62037037..80d85053fb06 100644 --- a/include/uapi/linux/l2tp.h +++ b/include/uapi/linux/l2tp.h @@ -9,9 +9,8 @@ #include #include -#ifndef __KERNEL__ -#include -#endif +#include +#include #define IPPROTO_L2TP 115 @@ -31,7 +30,7 @@ struct sockaddr_l2tpip { __u32 l2tp_conn_id; /* Connection ID of tunnel */ /* Pad to size of `struct sockaddr'. */ - unsigned char __pad[sizeof(struct sockaddr) - + unsigned char __pad[__SOCK_SIZE__ - sizeof(__kernel_sa_family_t) - sizeof(__be16) - sizeof(struct in_addr) - sizeof(__u32)]; From d14e9ab0db65a9a5636ba0ef00d6098296877ca5 Mon Sep 17 00:00:00 2001 From: "Kalderon, Michal" Date: Thu, 6 Jul 2017 23:22:11 +0300 Subject: [PATCH 171/387] IB/cma: Fix reference count leak when no ipv4 addresses are set commit 963916fdb3e5ad4af57ac959b5a03bf23f7568ca upstream. Once in_dev_get is called to receive in_device pointer, the in_device reference counter is increased, but if there are no ipv4 addresses configured on the net-device the ifa_list will be null, resulting in a flow that doesn't call in_dev_put to decrease the ref_cnt. This was exposed when running RoCE over ipv6 without any ipv4 addresses configured Fixes: commit 8e3867310c90 ("IB/cma: Fix a race condition in iboe_addr_get_sgid()") Signed-off-by: Michal Kalderon Signed-off-by: Ariel Elior Signed-off-by: Doug Ledford Cc: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- include/rdma/ib_addr.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h index f888263fd757..f4205f935331 100644 --- a/include/rdma/ib_addr.h +++ b/include/rdma/ib_addr.h @@ -208,11 +208,13 @@ static inline void iboe_addr_get_sgid(struct rdma_dev_addr *dev_addr, dev = dev_get_by_index(&init_net, dev_addr->bound_dev_if); if (dev) { ip4 = in_dev_get(dev); - if (ip4 && ip4->ifa_list && ip4->ifa_list->ifa_address) { + if (ip4 && ip4->ifa_list && ip4->ifa_list->ifa_address) ipv6_addr_set_v4mapped(ip4->ifa_list->ifa_address, (struct in6_addr *)gid); + + if (ip4) in_dev_put(ip4); - } + dev_put(dev); } } From 35a237b7ebbc700b07d0110d89adc847e762db8d Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 27 Apr 2020 17:26:05 -0600 Subject: [PATCH 172/387] gpio: tegra: mask GPIO IRQs during IRQ shutdown [ Upstream commit 0cf253eed5d2bdf7bb3152457b38f39b012955f7 ] The driver currently leaves GPIO IRQs unmasked even when the GPIO IRQ client has released the GPIO IRQ. This allows the HW to raise IRQs, and SW to process them, after shutdown. Fix this by masking the IRQ when it's shut down. This is usually taken care of by the irqchip core, but since this driver has a custom irq_shutdown implementation, it must do this explicitly itself. Signed-off-by: Stephen Warren Link: https://lore.kernel.org/r/20200427232605.11608-1-swarren@wwwdotorg.org Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin --- drivers/gpio/gpio-tegra.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index 05d3241ad20b..9d763557a105 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -341,6 +341,7 @@ static void tegra_gpio_irq_shutdown(struct irq_data *d) struct tegra_gpio_info *tgi = bank->tgi; int gpio = d->hwirq; + tegra_gpio_irq_mask(d); gpiochip_unlock_as_irq(&tgi->gc, gpio); } From b79c51eecad710ee3e7c7d57c3228cd9e1027449 Mon Sep 17 00:00:00 2001 From: Chuhong Yuan Date: Thu, 7 May 2020 23:13:20 +0800 Subject: [PATCH 173/387] net: microchip: encx24j600: add missed kthread_stop [ Upstream commit ff8ce319e9c25e920d994cc35236f0bb32dfc8f3 ] This driver calls kthread_run() in probe, but forgets to call kthread_stop() in probe failure and remove. Add the missed kthread_stop() to fix it. Signed-off-by: Chuhong Yuan Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/microchip/encx24j600.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/microchip/encx24j600.c b/drivers/net/ethernet/microchip/encx24j600.c index b14f0305aa31..ad661d1979c7 100644 --- a/drivers/net/ethernet/microchip/encx24j600.c +++ b/drivers/net/ethernet/microchip/encx24j600.c @@ -1058,7 +1058,7 @@ static int encx24j600_spi_probe(struct spi_device *spi) if (unlikely(ret)) { netif_err(priv, probe, ndev, "Error %d initializing card encx24j600 card\n", ret); - goto out_free; + goto out_stop; } eidled = encx24j600_read_reg(priv, EIDLED); @@ -1076,6 +1076,8 @@ static int encx24j600_spi_probe(struct spi_device *spi) out_unregister: unregister_netdev(priv->ndev); +out_stop: + kthread_stop(priv->kworker_task); out_free: free_netdev(ndev); @@ -1088,6 +1090,7 @@ static int encx24j600_spi_remove(struct spi_device *spi) struct encx24j600_priv *priv = dev_get_drvdata(&spi->dev); unregister_netdev(priv->ndev); + kthread_stop(priv->kworker_task); free_netdev(priv->ndev); From e9ec459266b25ab74fcf6bae44b75f741cd6d655 Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Tue, 5 May 2020 11:53:21 -0500 Subject: [PATCH 174/387] gfs2: move privileged user check to gfs2_quota_lock_check [ Upstream commit 4ed0c30811cb4d30ef89850b787a53a84d5d2bcb ] Before this patch, function gfs2_quota_lock checked if it was called from a privileged user, and if so, it bypassed the quota check: superuser can operate outside the quotas. That's the wrong place for the check because the lock/unlock functions are separate from the lock_check function, and you can do lock and unlock without actually checking the quotas. This patch moves the check to gfs2_quota_lock_check. Signed-off-by: Bob Peterson Signed-off-by: Andreas Gruenbacher Signed-off-by: Sasha Levin --- fs/gfs2/quota.c | 3 +-- fs/gfs2/quota.h | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index c2ca9566b764..fb9b1d702351 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c @@ -1039,8 +1039,7 @@ int gfs2_quota_lock(struct gfs2_inode *ip, kuid_t uid, kgid_t gid) u32 x; int error = 0; - if (capable(CAP_SYS_RESOURCE) || - sdp->sd_args.ar_quota != GFS2_QUOTA_ON) + if (sdp->sd_args.ar_quota != GFS2_QUOTA_ON) return 0; error = gfs2_quota_hold(ip, uid, gid); diff --git a/fs/gfs2/quota.h b/fs/gfs2/quota.h index 836f29480be6..e3a6e2404d11 100644 --- a/fs/gfs2/quota.h +++ b/fs/gfs2/quota.h @@ -47,7 +47,8 @@ static inline int gfs2_quota_lock_check(struct gfs2_inode *ip, int ret; ap->allowed = UINT_MAX; /* Assume we are permitted a whole lot */ - if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) + if (capable(CAP_SYS_RESOURCE) || + sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) return 0; ret = gfs2_quota_lock(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE); if (ret) From e88c7721a78c5d62ae1ed08a4ff0da7784dca945 Mon Sep 17 00:00:00 2001 From: Lei Xue Date: Thu, 7 May 2020 08:50:22 -0400 Subject: [PATCH 175/387] cachefiles: Fix race between read_waiter and read_copier involving op->to_do [ Upstream commit 7bb0c5338436dae953622470d52689265867f032 ] There is a potential race in fscache operation enqueuing for reading and copying multiple pages from cachefiles to netfs. The problem can be seen easily on a heavy loaded system (for example many processes reading files continually on an NFS share covered by fscache triggered this problem within a few minutes). The race is due to cachefiles_read_waiter() adding the op to the monitor to_do list and then then drop the object->work_lock spinlock before completing fscache_enqueue_operation(). Once the lock is dropped, cachefiles_read_copier() grabs the op, completes processing it, and makes it through fscache_retrieval_complete() which sets the op->state to the final state of FSCACHE_OP_ST_COMPLETE(4). When cachefiles_read_waiter() finally gets through the remainder of fscache_enqueue_operation() it sees the invalid state, and hits the ASSERTCMP and the following oops is seen: [ 2259.612361] FS-Cache: [ 2259.614785] FS-Cache: Assertion failed [ 2259.618639] FS-Cache: 4 == 5 is false [ 2259.622456] ------------[ cut here ]------------ [ 2259.627190] kernel BUG at fs/fscache/operation.c:70! ... [ 2259.791675] RIP: 0010:[] [] fscache_enqueue_operation+0xff/0x170 [fscache] [ 2259.802059] RSP: 0000:ffffa0263d543be0 EFLAGS: 00010046 [ 2259.807521] RAX: 0000000000000019 RBX: ffffa01a4d390480 RCX: 0000000000000006 [ 2259.814847] RDX: 0000000000000000 RSI: 0000000000000046 RDI: ffffa0263d553890 [ 2259.822176] RBP: ffffa0263d543be8 R08: 0000000000000000 R09: ffffa0263c2d8708 [ 2259.829502] R10: 0000000000001e7f R11: 0000000000000000 R12: ffffa01a4d390480 [ 2259.844483] R13: ffff9fa9546c5920 R14: ffffa0263d543c80 R15: ffffa0293ff9bf10 [ 2259.859554] FS: 00007f4b6efbd700(0000) GS:ffffa0263d540000(0000) knlGS:0000000000000000 [ 2259.875571] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 2259.889117] CR2: 00007f49e1624ff0 CR3: 0000012b38b38000 CR4: 00000000007607e0 [ 2259.904015] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 2259.918764] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 2259.933449] PKRU: 55555554 [ 2259.943654] Call Trace: [ 2259.953592] [ 2259.955577] [] cachefiles_read_waiter+0x92/0xf0 [cachefiles] [ 2259.978039] [] __wake_up_common+0x82/0x120 [ 2259.991392] [] __wake_up_common_lock+0x83/0xc0 [ 2260.004930] [] ? task_rq_unlock+0x20/0x20 [ 2260.017863] [] __wake_up+0x13/0x20 [ 2260.030230] [] __wake_up_bit+0x50/0x70 [ 2260.042535] [] unlock_page+0x2b/0x30 [ 2260.054495] [] page_endio+0x29/0x90 [ 2260.066184] [] mpage_end_io+0x51/0x80 CPU1 cachefiles_read_waiter() 20 static int cachefiles_read_waiter(wait_queue_entry_t *wait, unsigned mode, 21 int sync, void *_key) 22 { ... 61 spin_lock(&object->work_lock); 62 list_add_tail(&monitor->op_link, &op->to_do); 63 spin_unlock(&object->work_lock); 64 65 fscache_enqueue_retrieval(op); 182 static inline void fscache_enqueue_retrieval(struct fscache_retrieval *op) 183 { 184 fscache_enqueue_operation(&op->op); 185 } 58 void fscache_enqueue_operation(struct fscache_operation *op) 59 { 60 struct fscache_cookie *cookie = op->object->cookie; 61 62 _enter("{OBJ%x OP%x,%u}", 63 op->object->debug_id, op->debug_id, atomic_read(&op->usage)); 64 65 ASSERT(list_empty(&op->pend_link)); 66 ASSERT(op->processor != NULL); 67 ASSERT(fscache_object_is_available(op->object)); 68 ASSERTCMP(atomic_read(&op->usage), >, 0); CPU2 cachefiles_read_copier() 168 while (!list_empty(&op->to_do)) { ... 202 fscache_end_io(op, monitor->netfs_page, error); 203 put_page(monitor->netfs_page); 204 fscache_retrieval_complete(op, 1); CPU1 58 void fscache_enqueue_operation(struct fscache_operation *op) 59 { ... 69 ASSERTIFCMP(op->state != FSCACHE_OP_ST_IN_PROGRESS, 70 op->state, ==, FSCACHE_OP_ST_CANCELLED); Signed-off-by: Lei Xue Signed-off-by: Dave Wysochanski Signed-off-by: David Howells Signed-off-by: Sasha Levin --- fs/cachefiles/rdwr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c index 799b59d96fe2..7dba96d5fef1 100644 --- a/fs/cachefiles/rdwr.c +++ b/fs/cachefiles/rdwr.c @@ -64,9 +64,9 @@ static int cachefiles_read_waiter(wait_queue_t *wait, unsigned mode, object = container_of(op->op.object, struct cachefiles_object, fscache); spin_lock(&object->work_lock); list_add_tail(&monitor->op_link, &op->to_do); + fscache_enqueue_retrieval(op); spin_unlock(&object->work_lock); - fscache_enqueue_retrieval(op); fscache_put_retrieval(op); return 0; } From d44df08cff0aab09974e25156f2f70657e3a5e0d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 3 Apr 2020 22:16:51 +0900 Subject: [PATCH 176/387] usb: gadget: legacy: fix redundant initialization warnings [ Upstream commit d13cce757954fa663c69845611957396843ed87a ] Fix the following cppcheck warnings: drivers/usb/gadget/legacy/inode.c:1364:8: style: Redundant initialization for 'value'. The initialized value is overwritten$ value = -EOPNOTSUPP; ^ drivers/usb/gadget/legacy/inode.c:1331:15: note: value is initialized int value = -EOPNOTSUPP; ^ drivers/usb/gadget/legacy/inode.c:1364:8: note: value is overwritten value = -EOPNOTSUPP; ^ drivers/usb/gadget/legacy/inode.c:1817:8: style: Redundant initialization for 'value'. The initialized value is overwritten$ value = -EINVAL; ^ drivers/usb/gadget/legacy/inode.c:1787:18: note: value is initialized ssize_t value = len, length = len; ^ drivers/usb/gadget/legacy/inode.c:1817:8: note: value is overwritten value = -EINVAL; ^ Acked-by: Alan Stern Reported-by: kbuild test robot Signed-off-by: Masahiro Yamada Signed-off-by: Felipe Balbi Signed-off-by: Sasha Levin --- drivers/usb/gadget/legacy/inode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index b8534d3f8bb0..cb02e9ecd8e7 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -1364,7 +1364,6 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) req->buf = dev->rbuf; req->context = NULL; - value = -EOPNOTSUPP; switch (ctrl->bRequest) { case USB_REQ_GET_DESCRIPTOR: @@ -1788,7 +1787,7 @@ static ssize_t dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) { struct dev_data *dev = fd->private_data; - ssize_t value = len, length = len; + ssize_t value, length = len; unsigned total; u32 tag; char *kbuf; From 0d6297d8f734f194112751d0f5d87b504a8d45a7 Mon Sep 17 00:00:00 2001 From: Steve French Date: Wed, 13 May 2020 10:27:16 -0500 Subject: [PATCH 177/387] cifs: Fix null pointer check in cifs_read [ Upstream commit 9bd21d4b1a767c3abebec203342f3820dcb84662 ] Coverity scan noted a redundant null check Coverity-id: 728517 Reported-by: Coverity Signed-off-by: Steve French Reviewed-by: Shyam Prasad N Signed-off-by: Sasha Levin --- fs/cifs/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 09d83275c20b..b2919166855f 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -3293,7 +3293,7 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset) * than it negotiated since it will refuse the read * then. */ - if ((tcon->ses) && !(tcon->ses->capabilities & + if (!(tcon->ses->capabilities & tcon->ses->server->vals->cap_large_files)) { current_read_size = min_t(uint, current_read_size, CIFSMaxBufSize); From f9de95ee9e2a2be621eb432fd3470dacf4d83a35 Mon Sep 17 00:00:00 2001 From: James Hilliard Date: Sat, 18 Apr 2020 21:17:12 -0700 Subject: [PATCH 178/387] Input: usbtouchscreen - add support for BonXeon TP [ Upstream commit e3b4f94ef52ae1592cbe199bd38dbdc0d58b2217 ] Based on available information this uses the singletouch irtouch protocol. This is tested and confirmed to be fully functional on the BonXeon TP hardware I have. Signed-off-by: James Hilliard Link: https://lore.kernel.org/r/20200413184217.55700-1-james.hilliard1@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov Signed-off-by: Sasha Levin --- drivers/input/touchscreen/usbtouchscreen.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 2c41107240de..499402a975b3 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c @@ -197,6 +197,7 @@ static const struct usb_device_id usbtouch_devices[] = { #endif #ifdef CONFIG_TOUCHSCREEN_USB_IRTOUCH + {USB_DEVICE(0x255e, 0x0001), .driver_info = DEVTYPE_IRTOUCH}, {USB_DEVICE(0x595a, 0x0001), .driver_info = DEVTYPE_IRTOUCH}, {USB_DEVICE(0x6615, 0x0001), .driver_info = DEVTYPE_IRTOUCH}, {USB_DEVICE(0x6615, 0x0012), .driver_info = DEVTYPE_IRTOUCH_HIRES}, From ac28649d601c120f1da31ce82e8426d594538094 Mon Sep 17 00:00:00 2001 From: Brendan Shanks Date: Wed, 22 Apr 2020 13:45:12 -0700 Subject: [PATCH 179/387] Input: evdev - call input_flush_device() on release(), not flush() [ Upstream commit 09264098ff153f60866039d60b31d39b66f55a31 ] input_flush_device() should only be called once the struct file is being released and no open descriptors remain, but evdev_flush() was calling it whenever a file descriptor was closed. This caused uploaded force-feedback effects to be erased when a process did a dup()/close() on the event FD, called system(), etc. Call input_flush_device() from evdev_release() instead. Reported-by: Mathieu Maret Signed-off-by: Brendan Shanks Link: https://lore.kernel.org/r/20200421231003.7935-1-bshanks@codeweavers.com Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov Signed-off-by: Sasha Levin --- drivers/input/evdev.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index e9ae3d500a55..700f018df668 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -342,20 +342,6 @@ static int evdev_fasync(int fd, struct file *file, int on) return fasync_helper(fd, file, on, &client->fasync); } -static int evdev_flush(struct file *file, fl_owner_t id) -{ - struct evdev_client *client = file->private_data; - struct evdev *evdev = client->evdev; - - mutex_lock(&evdev->mutex); - - if (evdev->exist && !client->revoked) - input_flush_device(&evdev->handle, file); - - mutex_unlock(&evdev->mutex); - return 0; -} - static void evdev_free(struct device *dev) { struct evdev *evdev = container_of(dev, struct evdev, dev); @@ -469,6 +455,10 @@ static int evdev_release(struct inode *inode, struct file *file) unsigned int i; mutex_lock(&evdev->mutex); + + if (evdev->exist && !client->revoked) + input_flush_device(&evdev->handle, file); + evdev_ungrab(evdev, client); mutex_unlock(&evdev->mutex); @@ -1331,7 +1321,6 @@ static const struct file_operations evdev_fops = { .compat_ioctl = evdev_ioctl_compat, #endif .fasync = evdev_fasync, - .flush = evdev_flush, .llseek = no_llseek, }; From 68b87912e8755ce88d45f170437f33874af88a82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Patron?= Date: Wed, 22 Apr 2020 14:13:09 -0700 Subject: [PATCH 180/387] Input: xpad - add custom init packet for Xbox One S controllers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 764f7f911bf72450c51eb74cbb262ad9933741d8 ] Sending [ 0x05, 0x20, 0x00, 0x0f, 0x06 ] packet for Xbox One S controllers fixes an issue where controller is stuck in Bluetooth mode and not sending any inputs. Signed-off-by: Łukasz Patron Reviewed-by: Cameron Gutman Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20200422075206.18229-1-priv.luk@gmail.com Signed-off-by: Dmitry Torokhov Signed-off-by: Sasha Levin --- drivers/input/joystick/xpad.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 26476a64e663..54a6691d7d87 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -475,6 +475,16 @@ static const u8 xboxone_fw2015_init[] = { 0x05, 0x20, 0x00, 0x01, 0x00 }; +/* + * This packet is required for Xbox One S (0x045e:0x02ea) + * and Xbox One Elite Series 2 (0x045e:0x0b00) pads to + * initialize the controller that was previously used in + * Bluetooth mode. + */ +static const u8 xboxone_s_init[] = { + 0x05, 0x20, 0x00, 0x0f, 0x06 +}; + /* * This packet is required for the Titanfall 2 Xbox One pads * (0x0e6f:0x0165) to finish initialization and for Hori pads @@ -533,6 +543,8 @@ static const struct xboxone_init_packet xboxone_init_packets[] = { XBOXONE_INIT_PKT(0x0e6f, 0x0165, xboxone_hori_init), XBOXONE_INIT_PKT(0x0f0d, 0x0067, xboxone_hori_init), XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_fw2015_init), + XBOXONE_INIT_PKT(0x045e, 0x02ea, xboxone_s_init), + XBOXONE_INIT_PKT(0x045e, 0x0b00, xboxone_s_init), XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init1), XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init2), XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_rumblebegin_init), From dbe1a156cb2a284d0ea91028742e63f60fb019ae Mon Sep 17 00:00:00 2001 From: Kevin Locke Date: Mon, 27 Apr 2020 18:07:20 -0700 Subject: [PATCH 181/387] Input: i8042 - add ThinkPad S230u to i8042 reset list [ Upstream commit 2712c91a54a1058d55c284152b4d93c979b67be6 ] On the Lenovo ThinkPad Twist S230u (3347-4HU) with BIOS version "GDETC1WW (1.81 ) 06/27/2019", the keyboard, Synaptics TouchPad, and TrackPoint either do not function or stop functioning a few minutes after boot. This problem has been noted before, perhaps only occurring with BIOS 1.57 and later.[1][2][3][4][5] Odds of a BIOS fix appear to be low: 1.57 was released over 6 years ago and although the [BIOS changelog] notes "Fixed an issue of UEFI touchpad/trackpoint/keyboard/touchscreen" in 1.58, it appears to be insufficient. Setting i8042.reset=1 or adding 33474HU to the reset list avoids the issue on my system from either warm or cold boot. [1]: https://bugs.launchpad.net/bugs/1210748 [2]: https://bbs.archlinux.org/viewtopic.php?pid=1360425 [3]: https://forums.linuxmint.com/viewtopic.php?f=46&t=41200 [4]: https://forums.linuxmint.com/viewtopic.php?f=49&t=157115 [5]: https://forums.lenovo.com/topic/findpost/27/1337119 [BIOS changelog]: https://download.lenovo.com/pccbbs/mobiles/gduj33uc.txt Signed-off-by: Kevin Locke Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/94f384b0f75f90f71425d7dce7ac82c59ddb87a8.1587702636.git.kevin@kevinlocke.name Signed-off-by: Dmitry Torokhov Signed-off-by: Sasha Levin --- drivers/input/serio/i8042-x86ia64io.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index a4e76084a2af..fd1e79013cf8 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -738,6 +738,13 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "P65xRP"), }, }, + { + /* Lenovo ThinkPad Twist S230u */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "33474HU"), + }, + }, { } }; From a70ac9df36ca00b7c8049ac0626e3859bd65a897 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 28 Apr 2020 16:09:53 -0700 Subject: [PATCH 182/387] Input: synaptics-rmi4 - fix error return code in rmi_driver_probe() [ Upstream commit 5caab2da63207d6d631007f592f5219459e3454d ] Fix to return a negative error code from the input_register_device() error handling case instead of 0, as done elsewhere in this function. Signed-off-by: Wei Yongjun Link: https://lore.kernel.org/r/20200428134948.78343-1-weiyongjun1@huawei.com Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov Signed-off-by: Sasha Levin --- drivers/input/rmi4/rmi_driver.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c index 65038dcc7613..677edbf870a7 100644 --- a/drivers/input/rmi4/rmi_driver.c +++ b/drivers/input/rmi4/rmi_driver.c @@ -991,7 +991,8 @@ static int rmi_driver_probe(struct device *dev) if (data->input) { rmi_driver_set_input_name(rmi_dev, data->input); if (!rmi_dev->xport->input) { - if (input_register_device(data->input)) { + retval = input_register_device(data->input); + if (retval) { dev_err(dev, "%s: Failed to register input device.\n", __func__); goto err_destroy_functions; From 2a8bdb26fe9cb176ff53037eb88150803a486fd3 Mon Sep 17 00:00:00 2001 From: Kaike Wan Date: Mon, 11 May 2020 23:13:28 -0400 Subject: [PATCH 183/387] IB/qib: Call kobject_put() when kobject_init_and_add() fails [ Upstream commit a35cd6447effd5c239b564c80fa109d05ff3d114 ] When kobject_init_and_add() returns an error in the function qib_create_port_files(), the function kobject_put() is not called for the corresponding kobject, which potentially leads to memory leak. This patch fixes the issue by calling kobject_put() even if kobject_init_and_add() fails. In addition, the ppd->diagc_kobj is released along with other kobjects when the sysfs is unregistered. Fixes: f931551bafe1 ("IB/qib: Add new qib driver for QLogic PCIe InfiniBand adapters") Link: https://lore.kernel.org/r/20200512031328.189865.48627.stgit@awfm-01.aw.intel.com Cc: Suggested-by: Lin Yi Reviewed-by: Mike Marciniszyn Signed-off-by: Kaike Wan Signed-off-by: Dennis Dalessandro Reviewed-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe Signed-off-by: Sasha Levin --- drivers/infiniband/hw/qib/qib_sysfs.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/infiniband/hw/qib/qib_sysfs.c b/drivers/infiniband/hw/qib/qib_sysfs.c index 8ce0f6eef89e..b9d653afff8b 100644 --- a/drivers/infiniband/hw/qib/qib_sysfs.c +++ b/drivers/infiniband/hw/qib/qib_sysfs.c @@ -756,7 +756,7 @@ int qib_create_port_files(struct ib_device *ibdev, u8 port_num, qib_dev_err(dd, "Skipping linkcontrol sysfs info, (err %d) port %u\n", ret, port_num); - goto bail; + goto bail_link; } kobject_uevent(&ppd->pport_kobj, KOBJ_ADD); @@ -766,7 +766,7 @@ int qib_create_port_files(struct ib_device *ibdev, u8 port_num, qib_dev_err(dd, "Skipping sl2vl sysfs info, (err %d) port %u\n", ret, port_num); - goto bail_link; + goto bail_sl; } kobject_uevent(&ppd->sl2vl_kobj, KOBJ_ADD); @@ -776,7 +776,7 @@ int qib_create_port_files(struct ib_device *ibdev, u8 port_num, qib_dev_err(dd, "Skipping diag_counters sysfs info, (err %d) port %u\n", ret, port_num); - goto bail_sl; + goto bail_diagc; } kobject_uevent(&ppd->diagc_kobj, KOBJ_ADD); @@ -789,7 +789,7 @@ int qib_create_port_files(struct ib_device *ibdev, u8 port_num, qib_dev_err(dd, "Skipping Congestion Control sysfs info, (err %d) port %u\n", ret, port_num); - goto bail_diagc; + goto bail_cc; } kobject_uevent(&ppd->pport_cc_kobj, KOBJ_ADD); @@ -871,6 +871,7 @@ void qib_verbs_unregister_sysfs(struct qib_devdata *dd) &cc_table_bin_attr); kobject_put(&ppd->pport_cc_kobj); } + kobject_put(&ppd->diagc_kobj); kobject_put(&ppd->sl2vl_kobj); kobject_put(&ppd->pport_kobj); } From 8adb9c12a06275a51add8ea5b6cf5da1e9e77ce8 Mon Sep 17 00:00:00 2001 From: Martyn Welch Date: Fri, 30 Jun 2017 15:43:37 +0200 Subject: [PATCH 184/387] ARM: dts: imx: Correct B850v3 clock assignment [ Upstream commit 1d0c7bb20c083a6e810d2142545b5606f8131080 ] The IPU that drives HDMI must have its pre_sel set to pll2_pfd_396m to avoid stepping on the LVDS output's toes, as the PLL can't be clocked to the pixel clock and to the LVDS serial clock (3.5*pixel clock) at the same time. As we are using ipu1_di0 and ipu2_di0, ensure both are switched to to pll2_pfd2_396m to avoid issues. The LDB driver will switch the required IPU to ldb_di1 when it uses it to drive LVDS. Signed-off-by: Martyn Welch Signed-off-by: Romain Perier Reviewed-by: Fabio Estevam Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin --- arch/arm/boot/dts/imx6q-b850v3.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/imx6q-b850v3.dts b/arch/arm/boot/dts/imx6q-b850v3.dts index 167f7446722a..e5e9a16155d9 100644 --- a/arch/arm/boot/dts/imx6q-b850v3.dts +++ b/arch/arm/boot/dts/imx6q-b850v3.dts @@ -57,7 +57,7 @@ assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, <&clks IMX6QDL_CLK_LDB_DI1_SEL>, <&clks IMX6QDL_CLK_IPU1_DI0_PRE_SEL>, - <&clks IMX6QDL_CLK_IPU1_DI1_PRE_SEL>; + <&clks IMX6QDL_CLK_IPU2_DI0_PRE_SEL>; assigned-clock-parents = <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>, <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>, <&clks IMX6QDL_CLK_PLL2_PFD2_396M>, From 1125e313532e67927dccbe5d9f149f0d7b161a8d Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Tue, 23 Jan 2018 16:03:47 +0100 Subject: [PATCH 185/387] ARM: dts: imx6q-bx50v3: Add internal switch [ Upstream commit e26dead442689a861358f33126210b0f8de615a9 ] B850v3, B650v3 and B450v3 all have a GPIO bit banged MDIO bus to communicate with a Marvell switch. On all devices the switch is connected to a PCI based network card, which needs to be referenced by DT, so this also adds the common PCI root node. Signed-off-by: Sebastian Reichel Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- arch/arm/boot/dts/imx6q-bx50v3.dtsi | 62 +++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/arch/arm/boot/dts/imx6q-bx50v3.dtsi b/arch/arm/boot/dts/imx6q-bx50v3.dtsi index e4a415fd899b..ff8928a0b406 100644 --- a/arch/arm/boot/dts/imx6q-bx50v3.dtsi +++ b/arch/arm/boot/dts/imx6q-bx50v3.dtsi @@ -92,6 +92,56 @@ mux-int-port = <1>; mux-ext-port = <4>; }; + + aliases { + mdio-gpio0 = &mdio0; + }; + + mdio0: mdio-gpio { + compatible = "virtual,mdio-gpio"; + gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>, /* mdc */ + <&gpio2 7 GPIO_ACTIVE_HIGH>; /* mdio */ + + #address-cells = <1>; + #size-cells = <0>; + + switch@0 { + compatible = "marvell,mv88e6085"; /* 88e6240*/ + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + switch_ports: ports { + #address-cells = <1>; + #size-cells = <0>; + }; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + switchphy0: switchphy@0 { + reg = <0>; + }; + + switchphy1: switchphy@1 { + reg = <1>; + }; + + switchphy2: switchphy@2 { + reg = <2>; + }; + + switchphy3: switchphy@3 { + reg = <3>; + }; + + switchphy4: switchphy@4 { + reg = <4>; + }; + }; + }; + }; }; &ecspi5 { @@ -299,3 +349,15 @@ tcxo-clock-frequency = <26000000>; }; }; + +&pcie { + /* Synopsys, Inc. Device */ + pci_root: root@0,0 { + compatible = "pci16c3,abcd"; + reg = <0x00000000 0 0 0 0>; + + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + }; +}; From 2ab343c835f705bce8d184e699e462d4719fa54a Mon Sep 17 00:00:00 2001 From: Robert Beckett Date: Thu, 14 May 2020 19:02:37 +0200 Subject: [PATCH 186/387] ARM: dts/imx6q-bx50v3: Set display interface clock parents [ Upstream commit 665e7c73a7724a393b4ec92d1ae1e029925ef2b7 ] Avoid LDB and IPU DI clocks both using the same parent. LDB requires pasthrough clock to avoid breaking timing while IPU DI does not. Force IPU DI clocks to use IMX6QDL_CLK_PLL2_PFD0_352M as parent and LDB to use IMX6QDL_CLK_PLL5_VIDEO_DIV. This fixes an issue where attempting atomic modeset while using HDMI and display port at the same time causes LDB clock programming to destroy the programming of HDMI that was done during the same modeset. Cc: stable@vger.kernel.org Signed-off-by: Robert Beckett [Use IMX6QDL_CLK_PLL2_PFD0_352M instead of IMX6QDL_CLK_PLL2_PFD2_396M originally chosen by Robert Beckett to avoid affecting eMMC clock by DRM atomic updates] Signed-off-by: Ian Ray [Squash Robert's and Ian's commits for bisectability, update patch description and add stable tag] Signed-off-by: Sebastian Reichel Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin --- arch/arm/boot/dts/imx6q-b450v3.dts | 7 ------- arch/arm/boot/dts/imx6q-b650v3.dts | 7 ------- arch/arm/boot/dts/imx6q-b850v3.dts | 11 ----------- arch/arm/boot/dts/imx6q-bx50v3.dtsi | 15 +++++++++++++++ 4 files changed, 15 insertions(+), 25 deletions(-) diff --git a/arch/arm/boot/dts/imx6q-b450v3.dts b/arch/arm/boot/dts/imx6q-b450v3.dts index 78bfc1a307d6..ebc6e10f8624 100644 --- a/arch/arm/boot/dts/imx6q-b450v3.dts +++ b/arch/arm/boot/dts/imx6q-b450v3.dts @@ -65,13 +65,6 @@ }; }; -&clks { - assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, - <&clks IMX6QDL_CLK_LDB_DI1_SEL>; - assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_USB_OTG>, - <&clks IMX6QDL_CLK_PLL3_USB_OTG>; -}; - &ldb { status = "okay"; diff --git a/arch/arm/boot/dts/imx6q-b650v3.dts b/arch/arm/boot/dts/imx6q-b650v3.dts index d85388725426..681aa612e07f 100644 --- a/arch/arm/boot/dts/imx6q-b650v3.dts +++ b/arch/arm/boot/dts/imx6q-b650v3.dts @@ -65,13 +65,6 @@ }; }; -&clks { - assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, - <&clks IMX6QDL_CLK_LDB_DI1_SEL>; - assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_USB_OTG>, - <&clks IMX6QDL_CLK_PLL3_USB_OTG>; -}; - &ldb { status = "okay"; diff --git a/arch/arm/boot/dts/imx6q-b850v3.dts b/arch/arm/boot/dts/imx6q-b850v3.dts index e5e9a16155d9..8596df4078e9 100644 --- a/arch/arm/boot/dts/imx6q-b850v3.dts +++ b/arch/arm/boot/dts/imx6q-b850v3.dts @@ -53,17 +53,6 @@ }; }; -&clks { - assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, - <&clks IMX6QDL_CLK_LDB_DI1_SEL>, - <&clks IMX6QDL_CLK_IPU1_DI0_PRE_SEL>, - <&clks IMX6QDL_CLK_IPU2_DI0_PRE_SEL>; - assigned-clock-parents = <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>, - <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>, - <&clks IMX6QDL_CLK_PLL2_PFD2_396M>, - <&clks IMX6QDL_CLK_PLL2_PFD2_396M>; -}; - &ldb { fsl,dual-channel; status = "okay"; diff --git a/arch/arm/boot/dts/imx6q-bx50v3.dtsi b/arch/arm/boot/dts/imx6q-bx50v3.dtsi index ff8928a0b406..cee0e19f180f 100644 --- a/arch/arm/boot/dts/imx6q-bx50v3.dtsi +++ b/arch/arm/boot/dts/imx6q-bx50v3.dtsi @@ -361,3 +361,18 @@ #interrupt-cells = <1>; }; }; + +&clks { + assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, + <&clks IMX6QDL_CLK_LDB_DI1_SEL>, + <&clks IMX6QDL_CLK_IPU1_DI0_PRE_SEL>, + <&clks IMX6QDL_CLK_IPU1_DI1_PRE_SEL>, + <&clks IMX6QDL_CLK_IPU2_DI0_PRE_SEL>, + <&clks IMX6QDL_CLK_IPU2_DI1_PRE_SEL>; + assigned-clock-parents = <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>, + <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>, + <&clks IMX6QDL_CLK_PLL2_PFD0_352M>, + <&clks IMX6QDL_CLK_PLL2_PFD0_352M>, + <&clks IMX6QDL_CLK_PLL2_PFD0_352M>, + <&clks IMX6QDL_CLK_PLL2_PFD0_352M>; +}; From 93b7bf07e595b0142b903f96abb6b34501765802 Mon Sep 17 00:00:00 2001 From: Changming Liu Date: Tue, 26 May 2020 00:39:21 +0000 Subject: [PATCH 187/387] ALSA: hwdep: fix a left shifting 1 by 31 UB bug [ Upstream commit fb8cd6481ffd126f35e9e146a0dcf0c4e8899f2e ] The "info.index" variable can be 31 in "1 << info.index". This might trigger an undefined behavior since 1 is signed. Fix this by casting 1 to 1u just to be sure "1u << 31" is defined. Signed-off-by: Changming Liu Cc: Link: https://lore.kernel.org/r/BL0PR06MB4548170B842CB055C9AF695DE5B00@BL0PR06MB4548.namprd06.prod.outlook.com Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/core/hwdep.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c index 36d2416f90d9..96b737adf4d2 100644 --- a/sound/core/hwdep.c +++ b/sound/core/hwdep.c @@ -228,14 +228,14 @@ static int snd_hwdep_dsp_load(struct snd_hwdep *hw, if (copy_from_user(&info, _info, sizeof(info))) return -EFAULT; /* check whether the dsp was already loaded */ - if (hw->dsp_loaded & (1 << info.index)) + if (hw->dsp_loaded & (1u << info.index)) return -EBUSY; if (!access_ok(VERIFY_READ, info.image, info.length)) return -EFAULT; err = hw->ops.dsp_load(hw, &info); if (err < 0) return err; - hw->dsp_loaded |= (1 << info.index); + hw->dsp_loaded |= (1u << info.index); return 0; } From 3049246b669aa45bace38247aae798cb2075c5c5 Mon Sep 17 00:00:00 2001 From: Chris Chiu Date: Tue, 26 May 2020 14:26:13 +0800 Subject: [PATCH 188/387] ALSA: usb-audio: mixer: volume quirk for ESS Technology Asus USB DAC [ Upstream commit 4020d1ccbe55bdf67b31d718d2400506eaf4b43f ] The Asus USB DAC is a USB type-C audio dongle for connecting to the headset and headphone. The volume minimum value -23040 which is 0xa600 in hexadecimal with the resolution value 1 indicates this should be endianness issue caused by the firmware bug. Add a volume quirk to fix the volume control problem. Also fixes this warning: Warning! Unlikely big volume range (=23040), cval->res is probably wrong. [5] FU [Headset Capture Volume] ch = 1, val = -23040/0/1 Warning! Unlikely big volume range (=23040), cval->res is probably wrong. [7] FU [Headset Playback Volume] ch = 1, val = -23040/0/1 Signed-off-by: Chris Chiu Cc: Link: https://lore.kernel.org/r/20200526062613.55401-1-chiu@endlessm.com Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/usb/mixer.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index e2f62362a0b0..024864ce3f76 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -980,6 +980,14 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval, cval->res = 384; } break; + case USB_ID(0x0495, 0x3042): /* ESS Technology Asus USB DAC */ + if ((strstr(kctl->id.name, "Playback Volume") != NULL) || + strstr(kctl->id.name, "Capture Volume") != NULL) { + cval->min >>= 8; + cval->max = 0; + cval->res = 1; + } + break; } } From 8a093d42dab54bfe6fd95d9d1d3f1d8fdf83c142 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Mon, 25 May 2020 12:56:15 -0500 Subject: [PATCH 189/387] exec: Always set cap_ambient in cap_bprm_set_creds [ Upstream commit a4ae32c71fe90794127b32d26d7ad795813b502e ] An invariant of cap_bprm_set_creds is that every field in the new cred structure that cap_bprm_set_creds might set, needs to be set every time to ensure the fields does not get a stale value. The field cap_ambient is not set every time cap_bprm_set_creds is called, which means that if there is a suid or sgid script with an interpreter that has neither the suid nor the sgid bits set the interpreter should be able to accept ambient credentials. Unfortuantely because cap_ambient is not reset to it's original value the interpreter can not accept ambient credentials. Given that the ambient capability set is expected to be controlled by the caller, I don't think this is particularly serious. But it is definitely worth fixing so the code works correctly. I have tested to verify my reading of the code is correct and the interpreter of a sgid can receive ambient capabilities with this change and cannot receive ambient capabilities without this change. Cc: stable@vger.kernel.org Cc: Andy Lutomirski Fixes: 58319057b784 ("capabilities: ambient capabilities") Signed-off-by: "Eric W. Biederman" Signed-off-by: Sasha Levin --- security/commoncap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/security/commoncap.c b/security/commoncap.c index 8df676fbd393..b86aca8d6798 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -497,6 +497,7 @@ int cap_bprm_set_creds(struct linux_binprm *bprm) int ret; kuid_t root_uid; + new->cap_ambient = old->cap_ambient; if (WARN_ON(!cap_ambient_invariant_ok(old))) return -EPERM; From aa8b168731990a86bc8cc1f08dba29cb4101c26c Mon Sep 17 00:00:00 2001 From: Jerry Lee Date: Mon, 18 May 2020 16:03:09 +0800 Subject: [PATCH 190/387] libceph: ignore pool overlay and cache logic on redirects [ Upstream commit 890bd0f8997ae6ac0a367dd5146154a3963306dd ] OSD client should ignore cache/overlay flag if got redirect reply. Otherwise, the client hangs when the cache tier is in forward mode. [ idryomov: Redirects are effectively deprecated and no longer used or tested. The original tiering modes based on redirects are inherently flawed because redirects can race and reorder, potentially resulting in data corruption. The new proxy and readproxy tiering modes should be used instead of forward and readforward. Still marking for stable as obviously correct, though. ] Cc: stable@vger.kernel.org URL: https://tracker.ceph.com/issues/23296 URL: https://tracker.ceph.com/issues/36406 Signed-off-by: Jerry Lee Reviewed-by: Ilya Dryomov Signed-off-by: Ilya Dryomov Signed-off-by: Sasha Levin --- net/ceph/osd_client.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 70ccb0716fc5..4fd679b30b19 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -2879,7 +2879,9 @@ static void handle_reply(struct ceph_osd *osd, struct ceph_msg *msg) * supported. */ req->r_t.target_oloc.pool = m.redirect.oloc.pool; - req->r_flags |= CEPH_OSD_FLAG_REDIRECTED; + req->r_flags |= CEPH_OSD_FLAG_REDIRECTED | + CEPH_OSD_FLAG_IGNORE_OVERLAY | + CEPH_OSD_FLAG_IGNORE_CACHE; req->r_tid = 0; __submit_request(req, false); goto out_unlock_osdc; From 584da13a929bc2e83520fb63e3ba66584964572d Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Wed, 27 May 2020 22:20:47 -0700 Subject: [PATCH 191/387] mm: remove VM_BUG_ON(PageSlab()) from page_mapcount() [ Upstream commit 6988f31d558aa8c744464a7f6d91d34ada48ad12 ] Replace superfluous VM_BUG_ON() with comment about correct usage. Technically reverts commit 1d148e218a0d ("mm: add VM_BUG_ON_PAGE() to page_mapcount()"), but context lines have changed. Function isolate_migratepages_block() runs some checks out of lru_lock when choose pages for migration. After checking PageLRU() it checks extra page references by comparing page_count() and page_mapcount(). Between these two checks page could be removed from lru, freed and taken by slab. As a result this race triggers VM_BUG_ON(PageSlab()) in page_mapcount(). Race window is tiny. For certain workload this happens around once a year. page:ffffea0105ca9380 count:1 mapcount:0 mapping:ffff88ff7712c180 index:0x0 compound_mapcount: 0 flags: 0x500000000008100(slab|head) raw: 0500000000008100 dead000000000100 dead000000000200 ffff88ff7712c180 raw: 0000000000000000 0000000080200020 00000001ffffffff 0000000000000000 page dumped because: VM_BUG_ON_PAGE(PageSlab(page)) ------------[ cut here ]------------ kernel BUG at ./include/linux/mm.h:628! invalid opcode: 0000 [#1] SMP NOPTI CPU: 77 PID: 504 Comm: kcompactd1 Tainted: G W 4.19.109-27 #1 Hardware name: Yandex T175-N41-Y3N/MY81-EX0-Y3N, BIOS R05 06/20/2019 RIP: 0010:isolate_migratepages_block+0x986/0x9b0 The code in isolate_migratepages_block() was added in commit 119d6d59dcc0 ("mm, compaction: avoid isolating pinned pages") before adding VM_BUG_ON into page_mapcount(). This race has been predicted in 2015 by Vlastimil Babka (see link below). [akpm@linux-foundation.org: comment tweaks, per Hugh] Fixes: 1d148e218a0d ("mm: add VM_BUG_ON_PAGE() to page_mapcount()") Signed-off-by: Konstantin Khlebnikov Signed-off-by: Andrew Morton Acked-by: Hugh Dickins Acked-by: Kirill A. Shutemov Acked-by: Vlastimil Babka Cc: David Rientjes Cc: Link: http://lkml.kernel.org/r/159032779896.957378.7852761411265662220.stgit@buzz Link: https://lore.kernel.org/lkml/557710E1.6060103@suse.cz/ Link: https://lore.kernel.org/linux-mm/158937872515.474360.5066096871639561424.stgit@buzz/T/ (v1) Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin --- include/linux/mm.h | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index ca6f213fa4f0..7a4c035b187f 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -504,6 +504,11 @@ static inline int is_vmalloc_or_module_addr(const void *x) extern void kvfree(const void *addr); +/* + * Mapcount of compound page as a whole, does not include mapped sub-pages. + * + * Must be called only for compound pages or any their tail sub-pages. + */ static inline int compound_mapcount(struct page *page) { VM_BUG_ON_PAGE(!PageCompound(page), page); @@ -523,10 +528,16 @@ static inline void page_mapcount_reset(struct page *page) int __page_mapcount(struct page *page); +/* + * Mapcount of 0-order page; when compound sub-page, includes + * compound_mapcount(). + * + * Result is undefined for pages which cannot be mapped into userspace. + * For example SLAB or special types of pages. See function page_has_type(). + * They use this place in struct page differently. + */ static inline int page_mapcount(struct page *page) { - VM_BUG_ON_PAGE(PageSlab(page), page); - if (unlikely(PageCompound(page))) return __page_mapcount(page); return atomic_read(&page->_mapcount) + 1; From d228bc4b19e0b1c35f3eb404acbf1d607c01e64c Mon Sep 17 00:00:00 2001 From: Alexander Potapenko Date: Wed, 27 May 2020 22:20:52 -0700 Subject: [PATCH 192/387] fs/binfmt_elf.c: allocate initialized memory in fill_thread_core_info() [ Upstream commit 1d605416fb7175e1adf094251466caa52093b413 ] KMSAN reported uninitialized data being written to disk when dumping core. As a result, several kilobytes of kmalloc memory may be written to the core file and then read by a non-privileged user. Reported-by: sam Signed-off-by: Alexander Potapenko Signed-off-by: Andrew Morton Acked-by: Kees Cook Cc: Al Viro Cc: Alexey Dobriyan Cc: Link: http://lkml.kernel.org/r/20200419100848.63472-1-glider@google.com Link: https://github.com/google/kmsan/issues/76 Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin --- fs/binfmt_elf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index e78553d51837..73cd7482c1fa 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -1721,7 +1721,7 @@ static int fill_thread_core_info(struct elf_thread_core_info *t, (!regset->active || regset->active(t->task, regset) > 0)) { int ret; size_t size = regset->n * regset->size; - void *data = kmalloc(size, GFP_KERNEL); + void *data = kzalloc(size, GFP_KERNEL); if (unlikely(!data)) return 0; ret = regset->get(t->task, regset, From 4f4a4bc9076866a661a8af7921e7405e9959139d Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 27 May 2020 22:20:55 -0700 Subject: [PATCH 193/387] include/asm-generic/topology.h: guard cpumask_of_node() macro argument [ Upstream commit 4377748c7b5187c3342a60fa2ceb60c8a57a8488 ] drivers/hwmon/amd_energy.c:195:15: error: invalid operands to binary expression ('void' and 'int') (channel - data->nr_cpus)); ~~~~~~~~~^~~~~~~~~~~~~~~~~ include/asm-generic/topology.h:51:42: note: expanded from macro 'cpumask_of_node' #define cpumask_of_node(node) ((void)node, cpu_online_mask) ^~~~ include/linux/cpumask.h:618:72: note: expanded from macro 'cpumask_first_and' #define cpumask_first_and(src1p, src2p) cpumask_next_and(-1, (src1p), (src2p)) ^~~~~ Fixes: f0b848ce6fe9 ("cpumask: Introduce cpumask_of_{node,pcibus} to replace {node,pcibus}_to_cpumask") Fixes: 8abee9566b7e ("hwmon: Add amd_energy driver to report energy counters") Signed-off-by: Arnd Bergmann Signed-off-by: Andrew Morton Acked-by: Guenter Roeck Link: http://lkml.kernel.org/r/20200527134623.930247-1-arnd@arndb.de Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin --- include/asm-generic/topology.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-generic/topology.h b/include/asm-generic/topology.h index 5d2add1a6c96..864fcfa1df41 100644 --- a/include/asm-generic/topology.h +++ b/include/asm-generic/topology.h @@ -51,7 +51,7 @@ #ifdef CONFIG_NEED_MULTIPLE_NODES #define cpumask_of_node(node) ((node) == 0 ? cpu_online_mask : cpu_none_mask) #else - #define cpumask_of_node(node) ((void)node, cpu_online_mask) + #define cpumask_of_node(node) ((void)(node), cpu_online_mask) #endif #endif #ifndef pcibus_to_node From 44ac6becd5c68be7bfe95335f7f8788174c1e02f Mon Sep 17 00:00:00 2001 From: Qiushi Wu Date: Wed, 27 May 2020 16:00:19 -0500 Subject: [PATCH 194/387] iommu: Fix reference count leak in iommu_group_alloc. [ Upstream commit 7cc31613734c4870ae32f5265d576ef296621343 ] kobject_init_and_add() takes reference even when it fails. Thus, when kobject_init_and_add() returns an error, kobject_put() must be called to properly clean up the kobject. Fixes: d72e31c93746 ("iommu: IOMMU Groups") Signed-off-by: Qiushi Wu Link: https://lore.kernel.org/r/20200527210020.6522-1-wu000273@umn.edu Signed-off-by: Joerg Roedel Signed-off-by: Sasha Levin --- drivers/iommu/iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index dbcc13efaf3c..d609e14bb904 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -195,7 +195,7 @@ struct iommu_group *iommu_group_alloc(void) NULL, "%d", group->id); if (ret) { ida_simple_remove(&iommu_group_ida, group->id); - kfree(group); + kobject_put(&group->kobj); return ERR_PTR(ret); } From ce7b3d0533fb28b0cec4a5fc8a8d559c4baf03d3 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Thu, 28 May 2020 22:29:25 +0200 Subject: [PATCH 195/387] parisc: Fix kernel panic in mem_init() commit bf71bc16e02162388808949b179d59d0b571b965 upstream. The Debian kernel v5.6 triggers this kernel panic: Kernel panic - not syncing: Bad Address (null pointer deref?) Bad Address (null pointer deref?): Code=26 (Data memory access rights trap) at addr 0000000000000000 CPU: 0 PID: 0 Comm: swapper Not tainted 5.6.0-2-parisc64 #1 Debian 5.6.14-1 IAOQ[0]: mem_init+0xb0/0x150 IAOQ[1]: mem_init+0xb4/0x150 RP(r2): start_kernel+0x6c8/0x1190 Backtrace: [<0000000040101ab4>] start_kernel+0x6c8/0x1190 [<0000000040108574>] start_parisc+0x158/0x1b8 on a HP-PARISC rp3440 machine with this memory layout: Memory Ranges: 0) Start 0x0000000000000000 End 0x000000003fffffff Size 1024 MB 1) Start 0x0000004040000000 End 0x00000040ffdfffff Size 3070 MB Fix the crash by avoiding virt_to_page() and similar functions in mem_init() until the memory zones have been fully set up. Signed-off-by: Helge Deller Cc: stable@vger.kernel.org # v5.0+ Signed-off-by: Greg Kroah-Hartman --- arch/parisc/mm/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index b9db8e529e4d..dbbe3932f833 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -604,7 +604,7 @@ void __init mem_init(void) > BITS_PER_LONG); high_memory = __va((max_pfn << PAGE_SHIFT)); - set_max_mapnr(page_to_pfn(virt_to_page(high_memory - 1)) + 1); + set_max_mapnr(max_low_pfn); free_all_bootmem(); #ifdef CONFIG_PA11 From a3e733886b59a7484d3f586b5ae77fd80b810b4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20L=C3=BCssing?= Date: Fri, 22 May 2020 19:04:13 +0200 Subject: [PATCH 196/387] mac80211: mesh: fix discovery timer re-arming issue / crash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit e2d4a80f93fcfaf72e2e20daf6a28e39c3b90677 upstream. On a non-forwarding 802.11s link between two fairly busy neighboring nodes (iperf with -P 16 at ~850MBit/s TCP; 1733.3 MBit/s VHT-MCS 9 80MHz short GI VHT-NSS 4), so with frequent PREQ retries, usually after around 30-40 seconds the following crash would occur: [ 1110.822428] Unable to handle kernel read from unreadable memory at virtual address 00000000 [ 1110.830786] Mem abort info: [ 1110.833573] Exception class = IABT (current EL), IL = 32 bits [ 1110.839494] SET = 0, FnV = 0 [ 1110.842546] EA = 0, S1PTW = 0 [ 1110.845678] user pgtable: 4k pages, 48-bit VAs, pgd = ffff800076386000 [ 1110.852204] [0000000000000000] *pgd=00000000f6322003, *pud=00000000f62de003, *pmd=0000000000000000 [ 1110.861167] Internal error: Oops: 86000004 [#1] PREEMPT SMP [ 1110.866730] Modules linked in: pppoe ppp_async batman_adv ath10k_pci ath10k_core ath pppox ppp_generic nf_conntrack_ipv6 mac80211 iptable_nat ipt_REJECT ipt_MASQUERADE cfg80211 xt_time xt_tcpudp xt_state xt_nat xt_multiport xt_mark xt_mac xt_limit xt_conntrack xt_comment xt_TCPMSS xt_REDIRECT xt_LOG xt_FLOWOFFLOAD slhc nf_reject_ipv4 nf_nat_redirect nf_nat_masquerade_ipv4 nf_conntrack_ipv4 nf_nat_ipv4 nf_nat nf_log_ipv4 nf_flow_table_hw nf_flow_table nf_defrag_ipv6 nf_defrag_ipv4 nf_conntrack_rtcache nf_conntrack iptable_mangle iptable_filter ip_tables crc_ccitt compat nf_log_ipv6 nf_log_common ip6table_mangle ip6table_filter ip6_tables ip6t_REJECT x_tables nf_reject_ipv6 usb_storage xhci_plat_hcd xhci_pci xhci_hcd dwc3 usbcore usb_common [ 1110.932190] Process swapper/3 (pid: 0, stack limit = 0xffff0000090c8000) [ 1110.938884] CPU: 3 PID: 0 Comm: swapper/3 Not tainted 4.14.162 #0 [ 1110.944965] Hardware name: LS1043A RGW Board (DT) [ 1110.949658] task: ffff8000787a81c0 task.stack: ffff0000090c8000 [ 1110.955568] PC is at 0x0 [ 1110.958097] LR is at call_timer_fn.isra.27+0x24/0x78 [ 1110.963055] pc : [<0000000000000000>] lr : [] pstate: 00400145 [ 1110.970440] sp : ffff00000801be10 [ 1110.973744] x29: ffff00000801be10 x28: ffff000008bf7018 [ 1110.979047] x27: ffff000008bf87c8 x26: ffff000008c160c0 [ 1110.984352] x25: 0000000000000000 x24: 0000000000000000 [ 1110.989657] x23: dead000000000200 x22: 0000000000000000 [ 1110.994959] x21: 0000000000000000 x20: 0000000000000101 [ 1111.000262] x19: ffff8000787a81c0 x18: 0000000000000000 [ 1111.005565] x17: ffff0000089167b0 x16: 0000000000000058 [ 1111.010868] x15: ffff0000089167b0 x14: 0000000000000000 [ 1111.016172] x13: ffff000008916788 x12: 0000000000000040 [ 1111.021475] x11: ffff80007fda9af0 x10: 0000000000000001 [ 1111.026777] x9 : ffff00000801bea0 x8 : 0000000000000004 [ 1111.032080] x7 : 0000000000000000 x6 : ffff80007fda9aa8 [ 1111.037383] x5 : ffff00000801bea0 x4 : 0000000000000010 [ 1111.042685] x3 : ffff00000801be98 x2 : 0000000000000614 [ 1111.047988] x1 : 0000000000000000 x0 : 0000000000000000 [ 1111.053290] Call trace: [ 1111.055728] Exception stack(0xffff00000801bcd0 to 0xffff00000801be10) [ 1111.062158] bcc0: 0000000000000000 0000000000000000 [ 1111.069978] bce0: 0000000000000614 ffff00000801be98 0000000000000010 ffff00000801bea0 [ 1111.077798] bd00: ffff80007fda9aa8 0000000000000000 0000000000000004 ffff00000801bea0 [ 1111.085618] bd20: 0000000000000001 ffff80007fda9af0 0000000000000040 ffff000008916788 [ 1111.093437] bd40: 0000000000000000 ffff0000089167b0 0000000000000058 ffff0000089167b0 [ 1111.101256] bd60: 0000000000000000 ffff8000787a81c0 0000000000000101 0000000000000000 [ 1111.109075] bd80: 0000000000000000 dead000000000200 0000000000000000 0000000000000000 [ 1111.116895] bda0: ffff000008c160c0 ffff000008bf87c8 ffff000008bf7018 ffff00000801be10 [ 1111.124715] bdc0: ffff0000080ff29c ffff00000801be10 0000000000000000 0000000000400145 [ 1111.132534] bde0: ffff8000787a81c0 ffff00000801bde8 0000ffffffffffff 000001029eb19be8 [ 1111.140353] be00: ffff00000801be10 0000000000000000 [ 1111.145220] [< (null)>] (null) [ 1111.149917] [] run_timer_softirq+0x184/0x398 [ 1111.155741] [] __do_softirq+0x100/0x1fc [ 1111.161130] [] irq_exit+0x80/0xd8 [ 1111.166002] [] __handle_domain_irq+0x88/0xb0 [ 1111.171825] [] gic_handle_irq+0x68/0xb0 [ 1111.177213] Exception stack(0xffff0000090cbe30 to 0xffff0000090cbf70) [ 1111.183642] be20: 0000000000000020 0000000000000000 [ 1111.191461] be40: 0000000000000001 0000000000000000 00008000771af000 0000000000000000 [ 1111.199281] be60: ffff000008c95180 0000000000000000 ffff000008c19360 ffff0000090cbef0 [ 1111.207101] be80: 0000000000000810 0000000000000400 0000000000000098 ffff000000000000 [ 1111.214920] bea0: 0000000000000001 ffff0000089167b0 0000000000000000 ffff0000089167b0 [ 1111.222740] bec0: 0000000000000000 ffff000008c198e8 ffff000008bf7018 ffff000008c19000 [ 1111.230559] bee0: 0000000000000000 0000000000000000 ffff8000787a81c0 ffff000008018000 [ 1111.238380] bf00: ffff00000801c000 ffff00000913ba34 ffff8000787a81c0 ffff0000090cbf70 [ 1111.246199] bf20: ffff0000080857cc ffff0000090cbf70 ffff0000080857d0 0000000000400145 [ 1111.254020] bf40: ffff000008018000 ffff00000801c000 ffffffffffffffff ffff0000080fa574 [ 1111.261838] bf60: ffff0000090cbf70 ffff0000080857d0 [ 1111.266706] [] el1_irq+0xe8/0x18c [ 1111.271576] [] arch_cpu_idle+0x10/0x18 [ 1111.276880] [] do_idle+0xec/0x1b8 [ 1111.281748] [] cpu_startup_entry+0x20/0x28 [ 1111.287399] [] secondary_start_kernel+0x104/0x110 [ 1111.293662] Code: bad PC value [ 1111.296710] ---[ end trace 555b6ca4363c3edd ]--- [ 1111.301318] Kernel panic - not syncing: Fatal exception in interrupt [ 1111.307661] SMP: stopping secondary CPUs [ 1111.311574] Kernel Offset: disabled [ 1111.315053] CPU features: 0x0002000 [ 1111.318530] Memory Limit: none [ 1111.321575] Rebooting in 3 seconds.. With some added debug output / delays we were able to push the crash from the timer callback runner into the callback function and by that shedding some light on which object holding the timer gets corrupted: [ 401.720899] Unable to handle kernel read from unreadable memory at virtual address 00000868 [...] [ 402.335836] [] _raw_spin_lock_bh+0x14/0x48 [ 402.341548] [] mesh_path_timer+0x10c/0x248 [mac80211] [ 402.348154] [] call_timer_fn.isra.27+0x24/0x78 [ 402.354150] [] run_timer_softirq+0x184/0x398 [ 402.359974] [] __do_softirq+0x100/0x1fc [ 402.365362] [] irq_exit+0x80/0xd8 [ 402.370231] [] __handle_domain_irq+0x88/0xb0 [ 402.376053] [] gic_handle_irq+0x68/0xb0 The issue happens due to the following sequence of events: 1) mesh_path_start_discovery(): -> spin_unlock_bh(&mpath->state_lock) before mesh_path_sel_frame_tx() 2) mesh_path_free_rcu() -> del_timer_sync(&mpath->timer) [...] -> kfree_rcu(mpath) 3) mesh_path_start_discovery(): -> mod_timer(&mpath->timer, ...) [...] -> rcu_read_unlock() 4) mesh_path_free_rcu()'s kfree_rcu(): -> kfree(mpath) 5) mesh_path_timer() starts after timeout, using freed mpath object So a use-after-free issue due to a timer re-arming bug caused by an early spin-unlocking. This patch fixes this issue by re-checking if mpath is about to be free'd and if so bails out of re-arming the timer. Cc: stable@vger.kernel.org Fixes: 050ac52cbe1f ("mac80211: code for on-demand Hybrid Wireless Mesh Protocol") Cc: Simon Wunderlich Signed-off-by: Linus Lüssing Link: https://lore.kernel.org/r/20200522170413.14973-1-linus.luessing@c0d3.blue Signed-off-by: Johannes Berg Signed-off-by: Greg Kroah-Hartman --- net/mac80211/mesh_hwmp.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index f7eaa1051b5b..2fbd100b9e73 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -1082,7 +1082,14 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata) mesh_path_sel_frame_tx(MPATH_PREQ, 0, sdata->vif.addr, ifmsh->sn, target_flags, mpath->dst, mpath->sn, da, 0, ttl, lifetime, 0, ifmsh->preq_id++, sdata); + + spin_lock_bh(&mpath->state_lock); + if (mpath->flags & MESH_PATH_DELETED) { + spin_unlock_bh(&mpath->state_lock); + goto enddiscovery; + } mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout); + spin_unlock_bh(&mpath->state_lock); enddiscovery: rcu_read_unlock(); From 724fb3b38b11c919d60a6be8cd5ae0c3d82878c6 Mon Sep 17 00:00:00 2001 From: Alexander Dahl Date: Tue, 26 May 2020 19:57:49 +0200 Subject: [PATCH 197/387] x86/dma: Fix max PFN arithmetic overflow on 32 bit systems MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 88743470668ef5eb6b7ba9e0f99888e5999bf172 upstream. The intermediate result of the old term (4UL * 1024 * 1024 * 1024) is 4 294 967 296 or 0x100000000 which is no problem on 64 bit systems. The patch does not change the later overall result of 0x100000 for MAX_DMA32_PFN (after it has been shifted by PAGE_SHIFT). The new calculation yields the same result, but does not require 64 bit arithmetic. On 32 bit systems the old calculation suffers from an arithmetic overflow in that intermediate term in braces: 4UL aka unsigned long int is 4 byte wide and an arithmetic overflow happens (the 0x100000000 does not fit in 4 bytes), the in braces result is truncated to zero, the following right shift does not alter that, so MAX_DMA32_PFN evaluates to 0 on 32 bit systems. That wrong value is a problem in a comparision against MAX_DMA32_PFN in the init code for swiotlb in pci_swiotlb_detect_4gb() to decide if swiotlb should be active. That comparison yields the opposite result, when compiling on 32 bit systems. This was not possible before 1b7e03ef7570 ("x86, NUMA: Enable emulation on 32bit too") when that MAX_DMA32_PFN was first made visible to x86_32 (and which landed in v3.0). In practice this wasn't a problem, unless CONFIG_SWIOTLB is active on x86-32. However if one has set CONFIG_IOMMU_INTEL, since c5a5dc4cbbf4 ("iommu/vt-d: Don't switch off swiotlb if bounce page is used") there's a dependency on CONFIG_SWIOTLB, which was not necessarily active before. That landed in v5.4, where we noticed it in the fli4l Linux distribution. We have CONFIG_IOMMU_INTEL active on both 32 and 64 bit kernel configs there (I could not find out why, so let's just say historical reasons). The effect is at boot time 64 MiB (default size) were allocated for bounce buffers now, which is a noticeable amount of memory on small systems like pcengines ALIX 2D3 with 256 MiB memory, which are still frequently used as home routers. We noticed this effect when migrating from kernel v4.19 (LTS) to v5.4 (LTS) in fli4l and got that kernel messages for example: Linux version 5.4.22 (buildroot@buildroot) (gcc version 7.3.0 (Buildroot 2018.02.8)) #1 SMP Mon Nov 26 23:40:00 CET 2018 … Memory: 183484K/261756K available (4594K kernel code, 393K rwdata, 1660K rodata, 536K init, 456K bss , 78272K reserved, 0K cma-reserved, 0K highmem) … PCI-DMA: Using software bounce buffering for IO (SWIOTLB) software IO TLB: mapped [mem 0x0bb78000-0x0fb78000] (64MB) The initial analysis and the suggested fix was done by user 'sourcejedi' at stackoverflow and explicitly marked as GPLv2 for inclusion in the Linux kernel: https://unix.stackexchange.com/a/520525/50007 The new calculation, which does not suffer from that overflow, is the same as for arch/mips now as suggested by Robin Murphy. The fix was tested by fli4l users on round about two dozen different systems, including both 32 and 64 bit archs, bare metal and virtualized machines. [ bp: Massage commit message. ] Fixes: 1b7e03ef7570 ("x86, NUMA: Enable emulation on 32bit too") Reported-by: Alan Jenkins Suggested-by: Robin Murphy Signed-off-by: Alexander Dahl Signed-off-by: Borislav Petkov Reviewed-by: Greg Kroah-Hartman Cc: stable@vger.kernel.org Link: https://unix.stackexchange.com/q/520065/50007 Link: https://web.nettworks.org/bugs/browse/FFL-2560 Link: https://lkml.kernel.org/r/20200526175749.20742-1-post@lespocky.de Signed-off-by: Greg Kroah-Hartman --- arch/x86/include/asm/dma.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/include/asm/dma.h b/arch/x86/include/asm/dma.h index fe884e18fa6e..c7854a098b6b 100644 --- a/arch/x86/include/asm/dma.h +++ b/arch/x86/include/asm/dma.h @@ -73,7 +73,7 @@ #define MAX_DMA_PFN ((16UL * 1024 * 1024) >> PAGE_SHIFT) /* 4GB broken PCI/AGP hardware bus master zone */ -#define MAX_DMA32_PFN ((4UL * 1024 * 1024 * 1024) >> PAGE_SHIFT) +#define MAX_DMA32_PFN (1UL << (32 - PAGE_SHIFT)) #ifdef CONFIG_X86_32 /* The maximum address that we can perform a DMA transfer to on this platform */ From 918e01babefc91d50c15b25c83421923d86ea65c Mon Sep 17 00:00:00 2001 From: Xin Long Date: Fri, 10 Apr 2020 17:06:01 +0800 Subject: [PATCH 198/387] xfrm: allow to accept packets with ipv6 NEXTHDR_HOP in xfrm_input commit afcaf61be9d1dbdee5ec186d1dcc67b6b692180f upstream. For beet mode, when it's ipv6 inner address with nexthdrs set, the packet format might be: ---------------------------------------------------- | outer | | dest | | | ESP | ESP | | IP hdr | ESP | opts.| TCP | Data | Trailer | ICV | ---------------------------------------------------- The nexthdr from ESP could be NEXTHDR_HOP(0), so it should continue processing the packet when nexthdr returns 0 in xfrm_input(). Otherwise, when ipv6 nexthdr is set, the packet will be dropped. I don't see any error cases that nexthdr may return 0. So fix it by removing the check for nexthdr == 0. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Xin Long Signed-off-by: Steffen Klassert Signed-off-by: Greg Kroah-Hartman --- net/xfrm/xfrm_input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index 6e3f0254d8a1..1e87639f2c27 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c @@ -302,7 +302,7 @@ resume: dev_put(skb->dev); spin_lock(&x->lock); - if (nexthdr <= 0) { + if (nexthdr < 0) { if (nexthdr == -EBADMSG) { xfrm_audit_state_icvfail(x, skb, x->type->proto); From 6215d490738bec993c7e0a3b9b75256f6cb77a6d Mon Sep 17 00:00:00 2001 From: Xin Long Date: Mon, 25 May 2020 13:53:37 +0800 Subject: [PATCH 199/387] xfrm: fix a warning in xfrm_policy_insert_list commit ed17b8d377eaf6b4a01d46942b4c647378a79bdd upstream. This waring can be triggered simply by: # ip xfrm policy update src 192.168.1.1/24 dst 192.168.1.2/24 dir in \ priority 1 mark 0 mask 0x10 #[1] # ip xfrm policy update src 192.168.1.1/24 dst 192.168.1.2/24 dir in \ priority 2 mark 0 mask 0x1 #[2] # ip xfrm policy update src 192.168.1.1/24 dst 192.168.1.2/24 dir in \ priority 2 mark 0 mask 0x10 #[3] Then dmesg shows: [ ] WARNING: CPU: 1 PID: 7265 at net/xfrm/xfrm_policy.c:1548 [ ] RIP: 0010:xfrm_policy_insert_list+0x2f2/0x1030 [ ] Call Trace: [ ] xfrm_policy_inexact_insert+0x85/0xe50 [ ] xfrm_policy_insert+0x4ba/0x680 [ ] xfrm_add_policy+0x246/0x4d0 [ ] xfrm_user_rcv_msg+0x331/0x5c0 [ ] netlink_rcv_skb+0x121/0x350 [ ] xfrm_netlink_rcv+0x66/0x80 [ ] netlink_unicast+0x439/0x630 [ ] netlink_sendmsg+0x714/0xbf0 [ ] sock_sendmsg+0xe2/0x110 The issue was introduced by Commit 7cb8a93968e3 ("xfrm: Allow inserting policies with matching mark and different priorities"). After that, the policies [1] and [2] would be able to be added with different priorities. However, policy [3] will actually match both [1] and [2]. Policy [1] was matched due to the 1st 'return true' in xfrm_policy_mark_match(), and policy [2] was matched due to the 2nd 'return true' in there. It caused WARN_ON() in xfrm_policy_insert_list(). This patch is to fix it by only (the same value and priority) as the same policy in xfrm_policy_mark_match(). Thanks to Yuehaibing, we could make this fix better. v1->v2: - check policy->mark.v == pol->mark.v only without mask. Fixes: 7cb8a93968e3 ("xfrm: Allow inserting policies with matching mark and different priorities") Reported-by: Xiumei Mu Signed-off-by: Xin Long Signed-off-by: Steffen Klassert Signed-off-by: Greg Kroah-Hartman --- net/xfrm/xfrm_policy.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 69d061d4ed4f..b00ed36b9aac 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -757,12 +757,7 @@ static void xfrm_policy_requeue(struct xfrm_policy *old, static bool xfrm_policy_mark_match(struct xfrm_policy *policy, struct xfrm_policy *pol) { - u32 mark = policy->mark.v & policy->mark.m; - - if (policy->mark.v == pol->mark.v && policy->mark.m == pol->mark.m) - return true; - - if ((mark & pol->mark.m) == pol->mark.v && + if (policy->mark.v == pol->mark.v && policy->priority == pol->priority) return true; From 52914acf0703927dc41cd74751fe74bcac635820 Mon Sep 17 00:00:00 2001 From: Xin Long Date: Tue, 26 May 2020 17:41:46 +0800 Subject: [PATCH 200/387] xfrm: fix a NULL-ptr deref in xfrm_local_error commit f6a23d85d078c2ffde79c66ca81d0a1dde451649 upstream. This patch is to fix a crash: [ ] kasan: GPF could be caused by NULL-ptr deref or user memory access [ ] general protection fault: 0000 [#1] SMP KASAN PTI [ ] RIP: 0010:ipv6_local_error+0xac/0x7a0 [ ] Call Trace: [ ] xfrm6_local_error+0x1eb/0x300 [ ] xfrm_local_error+0x95/0x130 [ ] __xfrm6_output+0x65f/0xb50 [ ] xfrm6_output+0x106/0x46f [ ] udp_tunnel6_xmit_skb+0x618/0xbf0 [ip6_udp_tunnel] [ ] vxlan_xmit_one+0xbc6/0x2c60 [vxlan] [ ] vxlan_xmit+0x6a0/0x4276 [vxlan] [ ] dev_hard_start_xmit+0x165/0x820 [ ] __dev_queue_xmit+0x1ff0/0x2b90 [ ] ip_finish_output2+0xd3e/0x1480 [ ] ip_do_fragment+0x182d/0x2210 [ ] ip_output+0x1d0/0x510 [ ] ip_send_skb+0x37/0xa0 [ ] raw_sendmsg+0x1b4c/0x2b80 [ ] sock_sendmsg+0xc0/0x110 This occurred when sending a v4 skb over vxlan6 over ipsec, in which case skb->protocol == htons(ETH_P_IPV6) while skb->sk->sk_family == AF_INET in xfrm_local_error(). Then it will go to xfrm6_local_error() where it tries to get ipv6 info from a ipv4 sk. This issue was actually fixed by Commit 628e341f319f ("xfrm: make local error reporting more robust"), but brought back by Commit 844d48746e4b ("xfrm: choose protocol family by skb protocol"). So to fix it, we should call xfrm6_local_error() only when skb->protocol is htons(ETH_P_IPV6) and skb->sk->sk_family is AF_INET6. Fixes: 844d48746e4b ("xfrm: choose protocol family by skb protocol") Reported-by: Xiumei Mu Signed-off-by: Xin Long Signed-off-by: Steffen Klassert Signed-off-by: Greg Kroah-Hartman --- net/xfrm/xfrm_output.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c index 637387bbaaea..2c4aa7b5ccd5 100644 --- a/net/xfrm/xfrm_output.c +++ b/net/xfrm/xfrm_output.c @@ -240,7 +240,8 @@ void xfrm_local_error(struct sk_buff *skb, int mtu) if (skb->protocol == htons(ETH_P_IP)) proto = AF_INET; - else if (skb->protocol == htons(ETH_P_IPV6)) + else if (skb->protocol == htons(ETH_P_IPV6) && + skb->sk->sk_family == AF_INET6) proto = AF_INET6; else return; From 60dbd1a36936cc9c238a04d15d07b08e3621c6b1 Mon Sep 17 00:00:00 2001 From: Jeremy Sowden Date: Sat, 23 Mar 2019 14:43:02 +0000 Subject: [PATCH 201/387] vti4: eliminated some duplicate code. commit f981c57ffd2d7cf2dd4b6d6f8fcb3965df42f54c upstream. The ipip tunnel introduced in commit dd9ee3444014 ("vti4: Fix a ipip packet processing bug in 'IPCOMP' virtual tunnel") largely duplicated the existing vti_input and vti_recv functions. Refactored to deduplicate the common code. Signed-off-by: Jeremy Sowden Signed-off-by: Steffen Klassert Signed-off-by: Greg Kroah-Hartman --- net/ipv4/ip_vti.c | 66 ++++++++++++++++++----------------------------- 1 file changed, 25 insertions(+), 41 deletions(-) diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 8afb67a48409..18923d3a5e51 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c @@ -50,7 +50,7 @@ static int vti_net_id __read_mostly; static int vti_tunnel_init(struct net_device *dev); static int vti_input(struct sk_buff *skb, int nexthdr, __be32 spi, - int encap_type) + int encap_type, bool update_skb_dev) { struct ip_tunnel *tunnel; const struct iphdr *iph = ip_hdr(skb); @@ -65,32 +65,8 @@ static int vti_input(struct sk_buff *skb, int nexthdr, __be32 spi, XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = tunnel; - return xfrm_input(skb, nexthdr, spi, encap_type); - } - - return -EINVAL; -drop: - kfree_skb(skb); - return 0; -} - -static int vti_input_ipip(struct sk_buff *skb, int nexthdr, __be32 spi, - int encap_type) -{ - struct ip_tunnel *tunnel; - const struct iphdr *iph = ip_hdr(skb); - struct net *net = dev_net(skb->dev); - struct ip_tunnel_net *itn = net_generic(net, vti_net_id); - - tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY, - iph->saddr, iph->daddr, 0); - if (tunnel) { - if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) - goto drop; - - XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = tunnel; - - skb->dev = tunnel->dev; + if (update_skb_dev) + skb->dev = tunnel->dev; return xfrm_input(skb, nexthdr, spi, encap_type); } @@ -101,20 +77,28 @@ drop: return 0; } -static int vti_rcv(struct sk_buff *skb) +static int vti_input_proto(struct sk_buff *skb, int nexthdr, __be32 spi, + int encap_type) { - XFRM_SPI_SKB_CB(skb)->family = AF_INET; - XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr); - - return vti_input(skb, ip_hdr(skb)->protocol, 0, 0); + return vti_input(skb, nexthdr, spi, encap_type, false); } -static int vti_rcv_ipip(struct sk_buff *skb) +static int vti_rcv(struct sk_buff *skb, __be32 spi, bool update_skb_dev) { XFRM_SPI_SKB_CB(skb)->family = AF_INET; XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr); - return vti_input_ipip(skb, ip_hdr(skb)->protocol, ip_hdr(skb)->saddr, 0); + return vti_input(skb, ip_hdr(skb)->protocol, spi, 0, update_skb_dev); +} + +static int vti_rcv_proto(struct sk_buff *skb) +{ + return vti_rcv(skb, 0, false); +} + +static int vti_rcv_tunnel(struct sk_buff *skb) +{ + return vti_rcv(skb, ip_hdr(skb)->saddr, true); } static int vti_rcv_cb(struct sk_buff *skb, int err) @@ -482,31 +466,31 @@ static void __net_init vti_fb_tunnel_init(struct net_device *dev) } static struct xfrm4_protocol vti_esp4_protocol __read_mostly = { - .handler = vti_rcv, - .input_handler = vti_input, + .handler = vti_rcv_proto, + .input_handler = vti_input_proto, .cb_handler = vti_rcv_cb, .err_handler = vti4_err, .priority = 100, }; static struct xfrm4_protocol vti_ah4_protocol __read_mostly = { - .handler = vti_rcv, - .input_handler = vti_input, + .handler = vti_rcv_proto, + .input_handler = vti_input_proto, .cb_handler = vti_rcv_cb, .err_handler = vti4_err, .priority = 100, }; static struct xfrm4_protocol vti_ipcomp4_protocol __read_mostly = { - .handler = vti_rcv, - .input_handler = vti_input, + .handler = vti_rcv_proto, + .input_handler = vti_input_proto, .cb_handler = vti_rcv_cb, .err_handler = vti4_err, .priority = 100, }; static struct xfrm_tunnel ipip_handler __read_mostly = { - .handler = vti_rcv_ipip, + .handler = vti_rcv_tunnel, .err_handler = vti4_err, .priority = 0, }; From c67ec7f940189af94996c8e5aa704aebe4264d66 Mon Sep 17 00:00:00 2001 From: Xin Long Date: Tue, 21 Apr 2020 20:46:11 +0800 Subject: [PATCH 202/387] ip_vti: receive ipip packet by calling ip_tunnel_rcv commit 976eba8ab596bab94b9714cd46d38d5c6a2c660d upstream. In Commit dd9ee3444014 ("vti4: Fix a ipip packet processing bug in 'IPCOMP' virtual tunnel"), it tries to receive IPIP packets in vti by calling xfrm_input(). This case happens when a small packet or frag sent by peer is too small to get compressed. However, xfrm_input() will still get to the IPCOMP path where skb sec_path is set, but never dropped while it should have been done in vti_ipcomp4_protocol.cb_handler(vti_rcv_cb), as it's not an ipcomp4 packet. This will cause that the packet can never pass xfrm4_policy_check() in the upper protocol rcv functions. So this patch is to call ip_tunnel_rcv() to process IPIP packets instead. Fixes: dd9ee3444014 ("vti4: Fix a ipip packet processing bug in 'IPCOMP' virtual tunnel") Reported-by: Xiumei Mu Signed-off-by: Xin Long Signed-off-by: Steffen Klassert Signed-off-by: Greg Kroah-Hartman --- net/ipv4/ip_vti.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 18923d3a5e51..dc3b36ca9f30 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c @@ -98,7 +98,28 @@ static int vti_rcv_proto(struct sk_buff *skb) static int vti_rcv_tunnel(struct sk_buff *skb) { - return vti_rcv(skb, ip_hdr(skb)->saddr, true); + struct ip_tunnel_net *itn = net_generic(dev_net(skb->dev), vti_net_id); + const struct iphdr *iph = ip_hdr(skb); + struct ip_tunnel *tunnel; + + tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY, + iph->saddr, iph->daddr, 0); + if (tunnel) { + struct tnl_ptk_info tpi = { + .proto = htons(ETH_P_IP), + }; + + if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) + goto drop; + if (iptunnel_pull_header(skb, 0, tpi.proto, false)) + goto drop; + return ip_tunnel_rcv(tunnel, skb, &tpi, NULL, false); + } + + return -EINVAL; +drop: + kfree_skb(skb); + return 0; } static int vti_rcv_cb(struct sk_buff *skb, int err) From b614b8642fb89de42585b80b0a2485002a2d47da Mon Sep 17 00:00:00 2001 From: Michael Braun Date: Wed, 6 May 2020 11:46:25 +0200 Subject: [PATCH 203/387] netfilter: nft_reject_bridge: enable reject with bridge vlan commit e9c284ec4b41c827f4369973d2792992849e4fa5 upstream. Currently, using the bridge reject target with tagged packets results in untagged packets being sent back. Fix this by mirroring the vlan id as well. Fixes: 85f5b3086a04 ("netfilter: bridge: add reject support") Signed-off-by: Michael Braun Signed-off-by: Pablo Neira Ayuso Signed-off-by: Greg Kroah-Hartman --- net/bridge/netfilter/nft_reject_bridge.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/bridge/netfilter/nft_reject_bridge.c b/net/bridge/netfilter/nft_reject_bridge.c index d94aaf7c7685..4b5e1a661317 100644 --- a/net/bridge/netfilter/nft_reject_bridge.c +++ b/net/bridge/netfilter/nft_reject_bridge.c @@ -34,6 +34,12 @@ static void nft_reject_br_push_etherhdr(struct sk_buff *oldskb, ether_addr_copy(eth->h_dest, eth_hdr(oldskb)->h_source); eth->h_proto = eth_hdr(oldskb)->h_proto; skb_pull(nskb, ETH_HLEN); + + if (skb_vlan_tag_present(oldskb)) { + u16 vid = skb_vlan_tag_get(oldskb); + + __vlan_hwaccel_put_tag(nskb, oldskb->vlan_proto, vid); + } } static int nft_bridge_iphdr_validate(struct sk_buff *skb) From 12e427591ed82aa71c18bb544cbae15e71b80f59 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Thu, 14 May 2020 13:31:21 +0200 Subject: [PATCH 204/387] netfilter: ipset: Fix subcounter update skip commit a164b95ad6055c50612795882f35e0efda1f1390 upstream. If IPSET_FLAG_SKIP_SUBCOUNTER_UPDATE is set, user requested to not update counters in sub sets. Therefore IPSET_FLAG_SKIP_COUNTER_UPDATE must be set, not unset. Fixes: 6e01781d1c80e ("netfilter: ipset: set match: add support to match the counters") Signed-off-by: Phil Sutter Signed-off-by: Pablo Neira Ayuso Signed-off-by: Greg Kroah-Hartman --- net/netfilter/ipset/ip_set_list_set.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c index e82157285d34..f13d40402f7e 100644 --- a/net/netfilter/ipset/ip_set_list_set.c +++ b/net/netfilter/ipset/ip_set_list_set.c @@ -61,7 +61,7 @@ list_set_ktest(struct ip_set *set, const struct sk_buff *skb, /* Don't lookup sub-counters at all */ opt->cmdflags &= ~IPSET_FLAG_MATCH_COUNTERS; if (opt->cmdflags & IPSET_FLAG_SKIP_SUBCOUNTER_UPDATE) - opt->cmdflags &= ~IPSET_FLAG_SKIP_COUNTER_UPDATE; + opt->cmdflags |= IPSET_FLAG_SKIP_COUNTER_UPDATE; list_for_each_entry_rcu(e, &map->members, list) { if (SET_WITH_TIMEOUT(set) && ip_set_timeout_expired(ext_timeout(e, set))) From 8ef576491c9ea0166c7a00ff723470e220ff1d4a Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 14 May 2020 14:14:23 +0200 Subject: [PATCH 205/387] netfilter: nf_conntrack_pptp: prevent buffer overflows in debug code commit 4c559f15efcc43b996f4da528cd7f9483aaca36d upstream. Dan Carpenter says: "Smatch complains that the value for "cmd" comes from the network and can't be trusted." Add pptp_msg_name() helper function that checks for the array boundary. Fixes: f09943fefe6b ("[NETFILTER]: nf_conntrack/nf_nat: add PPTP helper port") Reported-by: Dan Carpenter Signed-off-by: Pablo Neira Ayuso Signed-off-by: Greg Kroah-Hartman --- include/linux/netfilter/nf_conntrack_pptp.h | 2 +- net/ipv4/netfilter/nf_nat_pptp.c | 7 +-- net/netfilter/nf_conntrack_pptp.c | 62 ++++++++++++--------- 3 files changed, 38 insertions(+), 33 deletions(-) diff --git a/include/linux/netfilter/nf_conntrack_pptp.h b/include/linux/netfilter/nf_conntrack_pptp.h index 2ab2830316b7..4bba535b663a 100644 --- a/include/linux/netfilter/nf_conntrack_pptp.h +++ b/include/linux/netfilter/nf_conntrack_pptp.h @@ -4,7 +4,7 @@ #include -extern const char *const pptp_msg_name[]; +extern const char *const pptp_msg_name(u_int16_t msg); /* state of the control session */ enum pptp_ctrlsess_state { diff --git a/net/ipv4/netfilter/nf_nat_pptp.c b/net/ipv4/netfilter/nf_nat_pptp.c index b3ca21b2ba9b..ddbf93e70069 100644 --- a/net/ipv4/netfilter/nf_nat_pptp.c +++ b/net/ipv4/netfilter/nf_nat_pptp.c @@ -156,8 +156,7 @@ pptp_outbound_pkt(struct sk_buff *skb, break; default: pr_debug("unknown outbound packet 0x%04x:%s\n", msg, - msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] : - pptp_msg_name[0]); + pptp_msg_name(msg)); /* fall through */ case PPTP_SET_LINK_INFO: /* only need to NAT in case PAC is behind NAT box */ @@ -250,9 +249,7 @@ pptp_inbound_pkt(struct sk_buff *skb, pcid_off = offsetof(union pptp_ctrl_union, setlink.peersCallID); break; default: - pr_debug("unknown inbound packet %s\n", - msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] : - pptp_msg_name[0]); + pr_debug("unknown inbound packet %s\n", pptp_msg_name(msg)); /* fall through */ case PPTP_START_SESSION_REQUEST: case PPTP_START_SESSION_REPLY: diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c index f60a4755d71e..04d93474ab86 100644 --- a/net/netfilter/nf_conntrack_pptp.c +++ b/net/netfilter/nf_conntrack_pptp.c @@ -71,24 +71,32 @@ EXPORT_SYMBOL_GPL(nf_nat_pptp_hook_expectfn); #if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) /* PptpControlMessageType names */ -const char *const pptp_msg_name[] = { - "UNKNOWN_MESSAGE", - "START_SESSION_REQUEST", - "START_SESSION_REPLY", - "STOP_SESSION_REQUEST", - "STOP_SESSION_REPLY", - "ECHO_REQUEST", - "ECHO_REPLY", - "OUT_CALL_REQUEST", - "OUT_CALL_REPLY", - "IN_CALL_REQUEST", - "IN_CALL_REPLY", - "IN_CALL_CONNECT", - "CALL_CLEAR_REQUEST", - "CALL_DISCONNECT_NOTIFY", - "WAN_ERROR_NOTIFY", - "SET_LINK_INFO" +static const char *const pptp_msg_name_array[PPTP_MSG_MAX + 1] = { + [0] = "UNKNOWN_MESSAGE", + [PPTP_START_SESSION_REQUEST] = "START_SESSION_REQUEST", + [PPTP_START_SESSION_REPLY] = "START_SESSION_REPLY", + [PPTP_STOP_SESSION_REQUEST] = "STOP_SESSION_REQUEST", + [PPTP_STOP_SESSION_REPLY] = "STOP_SESSION_REPLY", + [PPTP_ECHO_REQUEST] = "ECHO_REQUEST", + [PPTP_ECHO_REPLY] = "ECHO_REPLY", + [PPTP_OUT_CALL_REQUEST] = "OUT_CALL_REQUEST", + [PPTP_OUT_CALL_REPLY] = "OUT_CALL_REPLY", + [PPTP_IN_CALL_REQUEST] = "IN_CALL_REQUEST", + [PPTP_IN_CALL_REPLY] = "IN_CALL_REPLY", + [PPTP_IN_CALL_CONNECT] = "IN_CALL_CONNECT", + [PPTP_CALL_CLEAR_REQUEST] = "CALL_CLEAR_REQUEST", + [PPTP_CALL_DISCONNECT_NOTIFY] = "CALL_DISCONNECT_NOTIFY", + [PPTP_WAN_ERROR_NOTIFY] = "WAN_ERROR_NOTIFY", + [PPTP_SET_LINK_INFO] = "SET_LINK_INFO" }; + +const char *const pptp_msg_name(u_int16_t msg) +{ + if (msg > PPTP_MSG_MAX) + return pptp_msg_name_array[0]; + + return pptp_msg_name_array[msg]; +} EXPORT_SYMBOL(pptp_msg_name); #endif @@ -277,7 +285,7 @@ pptp_inbound_pkt(struct sk_buff *skb, unsigned int protoff, typeof(nf_nat_pptp_hook_inbound) nf_nat_pptp_inbound; msg = ntohs(ctlh->messageType); - pr_debug("inbound control message %s\n", pptp_msg_name[msg]); + pr_debug("inbound control message %s\n", pptp_msg_name(msg)); switch (msg) { case PPTP_START_SESSION_REPLY: @@ -312,7 +320,7 @@ pptp_inbound_pkt(struct sk_buff *skb, unsigned int protoff, pcid = pptpReq->ocack.peersCallID; if (info->pns_call_id != pcid) goto invalid; - pr_debug("%s, CID=%X, PCID=%X\n", pptp_msg_name[msg], + pr_debug("%s, CID=%X, PCID=%X\n", pptp_msg_name(msg), ntohs(cid), ntohs(pcid)); if (pptpReq->ocack.resultCode == PPTP_OUTCALL_CONNECT) { @@ -329,7 +337,7 @@ pptp_inbound_pkt(struct sk_buff *skb, unsigned int protoff, goto invalid; cid = pptpReq->icreq.callID; - pr_debug("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid)); + pr_debug("%s, CID=%X\n", pptp_msg_name(msg), ntohs(cid)); info->cstate = PPTP_CALL_IN_REQ; info->pac_call_id = cid; break; @@ -348,7 +356,7 @@ pptp_inbound_pkt(struct sk_buff *skb, unsigned int protoff, if (info->pns_call_id != pcid) goto invalid; - pr_debug("%s, PCID=%X\n", pptp_msg_name[msg], ntohs(pcid)); + pr_debug("%s, PCID=%X\n", pptp_msg_name(msg), ntohs(pcid)); info->cstate = PPTP_CALL_IN_CONF; /* we expect a GRE connection from PAC to PNS */ @@ -358,7 +366,7 @@ pptp_inbound_pkt(struct sk_buff *skb, unsigned int protoff, case PPTP_CALL_DISCONNECT_NOTIFY: /* server confirms disconnect */ cid = pptpReq->disc.callID; - pr_debug("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid)); + pr_debug("%s, CID=%X\n", pptp_msg_name(msg), ntohs(cid)); info->cstate = PPTP_CALL_NONE; /* untrack this call id, unexpect GRE packets */ @@ -385,7 +393,7 @@ pptp_inbound_pkt(struct sk_buff *skb, unsigned int protoff, invalid: pr_debug("invalid %s: type=%d cid=%u pcid=%u " "cstate=%d sstate=%d pns_cid=%u pac_cid=%u\n", - msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] : pptp_msg_name[0], + pptp_msg_name(msg), msg, ntohs(cid), ntohs(pcid), info->cstate, info->sstate, ntohs(info->pns_call_id), ntohs(info->pac_call_id)); return NF_ACCEPT; @@ -405,7 +413,7 @@ pptp_outbound_pkt(struct sk_buff *skb, unsigned int protoff, typeof(nf_nat_pptp_hook_outbound) nf_nat_pptp_outbound; msg = ntohs(ctlh->messageType); - pr_debug("outbound control message %s\n", pptp_msg_name[msg]); + pr_debug("outbound control message %s\n", pptp_msg_name(msg)); switch (msg) { case PPTP_START_SESSION_REQUEST: @@ -427,7 +435,7 @@ pptp_outbound_pkt(struct sk_buff *skb, unsigned int protoff, info->cstate = PPTP_CALL_OUT_REQ; /* track PNS call id */ cid = pptpReq->ocreq.callID; - pr_debug("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid)); + pr_debug("%s, CID=%X\n", pptp_msg_name(msg), ntohs(cid)); info->pns_call_id = cid; break; @@ -441,7 +449,7 @@ pptp_outbound_pkt(struct sk_buff *skb, unsigned int protoff, pcid = pptpReq->icack.peersCallID; if (info->pac_call_id != pcid) goto invalid; - pr_debug("%s, CID=%X PCID=%X\n", pptp_msg_name[msg], + pr_debug("%s, CID=%X PCID=%X\n", pptp_msg_name(msg), ntohs(cid), ntohs(pcid)); if (pptpReq->icack.resultCode == PPTP_INCALL_ACCEPT) { @@ -481,7 +489,7 @@ pptp_outbound_pkt(struct sk_buff *skb, unsigned int protoff, invalid: pr_debug("invalid %s: type=%d cid=%u pcid=%u " "cstate=%d sstate=%d pns_cid=%u pac_cid=%u\n", - msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] : pptp_msg_name[0], + pptp_msg_name(msg), msg, ntohs(cid), ntohs(pcid), info->cstate, info->sstate, ntohs(info->pns_call_id), ntohs(info->pac_call_id)); return NF_ACCEPT; From 0dee5beb6c802c16bb2cfc94976c1e215a681427 Mon Sep 17 00:00:00 2001 From: Qiushi Wu Date: Mon, 25 May 2020 03:24:39 -0500 Subject: [PATCH 206/387] qlcnic: fix missing release in qlcnic_83xx_interrupt_test. commit 15c973858903009e995b2037683de29dfe968621 upstream. In function qlcnic_83xx_interrupt_test(), function qlcnic_83xx_diag_alloc_res() is not handled by function qlcnic_83xx_diag_free_res() after a call of the function qlcnic_alloc_mbx_args() failed. Fix this issue by adding a jump target "fail_mbx_args", and jump to this new target when qlcnic_alloc_mbx_args() failed. Fixes: b6b4316c8b2f ("qlcnic: Handle qlcnic_alloc_mbx_args() failure") Signed-off-by: Qiushi Wu Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index 35c5ac41c0a1..5d2de48b77a0 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c @@ -3610,7 +3610,7 @@ int qlcnic_83xx_interrupt_test(struct net_device *netdev) ahw->diag_cnt = 0; ret = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INTRPT_TEST); if (ret) - goto fail_diag_irq; + goto fail_mbx_args; if (adapter->flags & QLCNIC_MSIX_ENABLED) intrpt_id = ahw->intr_tbl[0].id; @@ -3640,6 +3640,8 @@ int qlcnic_83xx_interrupt_test(struct net_device *netdev) done: qlcnic_free_mbx_args(&cmd); + +fail_mbx_args: qlcnic_83xx_diag_free_res(netdev, drv_sds_rings); fail_diag_irq: From cd678077be57378ef2764453478c4694e9c07c6e Mon Sep 17 00:00:00 2001 From: Qiushi Wu Date: Wed, 27 May 2020 22:10:29 -0500 Subject: [PATCH 207/387] bonding: Fix reference count leak in bond_sysfs_slave_add. commit a068aab42258e25094bc2c159948d263ed7d7a77 upstream. kobject_init_and_add() takes reference even when it fails. If this function returns an error, kobject_put() must be called to properly clean up the memory associated with the object. Previous commit "b8eb718348b8" fixed a similar problem. Fixes: 07699f9a7c8d ("bonding: add sysfs /slave dir for bond slave devices.") Signed-off-by: Qiushi Wu Acked-by: Jay Vosburgh Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/bonding/bond_sysfs_slave.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/bonding/bond_sysfs_slave.c b/drivers/net/bonding/bond_sysfs_slave.c index 641a532b67cb..3f756fa2f603 100644 --- a/drivers/net/bonding/bond_sysfs_slave.c +++ b/drivers/net/bonding/bond_sysfs_slave.c @@ -153,8 +153,10 @@ int bond_sysfs_slave_add(struct slave *slave) err = kobject_init_and_add(&slave->kobj, &slave_ktype, &(slave->dev->dev.kobj), "bonding_slave"); - if (err) + if (err) { + kobject_put(&slave->kobj); return err; + } for (a = slave_attrs; *a; ++a) { err = sysfs_create_file(&slave->kobj, &((*a)->attr)); From 2395335b453d54089bea0b7d3020857482c9508c Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 27 May 2020 12:24:10 +0200 Subject: [PATCH 208/387] netfilter: nf_conntrack_pptp: fix compilation warning with W=1 build commit 4946ea5c1237036155c3b3a24f049fd5f849f8f6 upstream. >> include/linux/netfilter/nf_conntrack_pptp.h:13:20: warning: 'const' type qualifier on return type has no effect [-Wignored-qualifiers] extern const char *const pptp_msg_name(u_int16_t msg); ^~~~~~ Reported-by: kbuild test robot Fixes: 4c559f15efcc ("netfilter: nf_conntrack_pptp: prevent buffer overflows in debug code") Signed-off-by: Pablo Neira Ayuso Signed-off-by: Greg Kroah-Hartman --- include/linux/netfilter/nf_conntrack_pptp.h | 2 +- net/netfilter/nf_conntrack_pptp.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/netfilter/nf_conntrack_pptp.h b/include/linux/netfilter/nf_conntrack_pptp.h index 4bba535b663a..aca42a2e79cf 100644 --- a/include/linux/netfilter/nf_conntrack_pptp.h +++ b/include/linux/netfilter/nf_conntrack_pptp.h @@ -4,7 +4,7 @@ #include -extern const char *const pptp_msg_name(u_int16_t msg); +const char *pptp_msg_name(u_int16_t msg); /* state of the control session */ enum pptp_ctrlsess_state { diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c index 04d93474ab86..1b2fa9d8575f 100644 --- a/net/netfilter/nf_conntrack_pptp.c +++ b/net/netfilter/nf_conntrack_pptp.c @@ -90,7 +90,7 @@ static const char *const pptp_msg_name_array[PPTP_MSG_MAX + 1] = { [PPTP_SET_LINK_INFO] = "SET_LINK_INFO" }; -const char *const pptp_msg_name(u_int16_t msg) +const char *pptp_msg_name(u_int16_t msg) { if (msg > PPTP_MSG_MAX) return pptp_msg_name_array[0]; From 6e3885a341f22234ef12074f875d57c6fbd5c181 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 4 Jun 2018 17:33:54 +0200 Subject: [PATCH 209/387] genirq/generic_pending: Do not lose pending affinity update commit a33a5d2d16cb84bea8d5f5510f3a41aa48b5c467 upstream. The generic pending interrupt mechanism moves interrupts from the interrupt handler on the original target CPU to the new destination CPU. This is required for x86 and ia64 due to the way the interrupt delivery and acknowledge works if the interrupts are not remapped. However that update can fail for various reasons. Some of them are valid reasons to discard the pending update, but the case, when the previous move has not been fully cleaned up is not a legit reason to fail. Check the return value of irq_do_set_affinity() for -EBUSY, which indicates a pending cleanup, and rearm the pending move in the irq dexcriptor so it's tried again when the next interrupt arrives. Fixes: 996c591227d9 ("x86/irq: Plug vector cleanup race") Signed-off-by: Thomas Gleixner Tested-by: Song Liu Cc: Joerg Roedel Cc: Peter Zijlstra Cc: Song Liu Cc: Dmitry Safonov <0x7f454c46@gmail.com> Cc: stable@vger.kernel.org Cc: Mike Travis Cc: Borislav Petkov Cc: Tariq Toukan Cc: Guenter Roeck Link: https://lkml.kernel.org/r/20180604162224.386544292@linutronix.de Signed-off-by: Greg Kroah-Hartman --- kernel/irq/migration.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c index 37ddb7bda651..ec7c7eda0774 100644 --- a/kernel/irq/migration.c +++ b/kernel/irq/migration.c @@ -7,17 +7,18 @@ void irq_move_masked_irq(struct irq_data *idata) { struct irq_desc *desc = irq_data_to_desc(idata); - struct irq_chip *chip = desc->irq_data.chip; + struct irq_data *data = &desc->irq_data; + struct irq_chip *chip = data->chip; - if (likely(!irqd_is_setaffinity_pending(&desc->irq_data))) + if (likely(!irqd_is_setaffinity_pending(data))) return; - irqd_clr_move_pending(&desc->irq_data); + irqd_clr_move_pending(data); /* * Paranoia: cpu-local interrupts shouldn't be calling in here anyway. */ - if (irqd_is_per_cpu(&desc->irq_data)) { + if (irqd_is_per_cpu(data)) { WARN_ON(1); return; } @@ -42,9 +43,20 @@ void irq_move_masked_irq(struct irq_data *idata) * For correct operation this depends on the caller * masking the irqs. */ - if (cpumask_any_and(desc->pending_mask, cpu_online_mask) < nr_cpu_ids) - irq_do_set_affinity(&desc->irq_data, desc->pending_mask, false); + if (cpumask_any_and(desc->pending_mask, cpu_online_mask) < nr_cpu_ids) { + int ret; + ret = irq_do_set_affinity(data, desc->pending_mask, false); + /* + * If the there is a cleanup pending in the underlying + * vector management, reschedule the move for the next + * interrupt. Leave desc->pending_mask intact. + */ + if (ret == -EBUSY) { + irqd_set_move_pending(data); + return; + } + } cpumask_clear(desc->pending_mask); } From fba023f8dd69bbd728cea29a2b8277f5bd805d1b Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Wed, 12 Sep 2018 13:21:48 -0700 Subject: [PATCH 210/387] net: rtnl_configure_link: fix dev flags changes arg to __dev_notify_flags commit 56a49d7048703f5ffdb84d3a0ee034108fba6850 upstream. 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 Cc: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- net/core/rtnetlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index ead1a32c68f7..e652e376fb30 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -2361,7 +2361,7 @@ int rtnl_configure_link(struct net_device *dev, const struct ifinfomsg *ifm) } 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); From d20b134f685b4d6558a614396ac88df2fd13eb98 Mon Sep 17 00:00:00 2001 From: Liviu Dudau Date: Tue, 5 Mar 2019 15:42:54 -0800 Subject: [PATCH 211/387] mm/vmalloc.c: don't dereference possible NULL pointer in __vunmap() commit 6ade20327dbb808882888ed8ccded71e93067cf9 upstream. find_vmap_area() can return a NULL pointer and we're going to dereference it without checking it first. Use the existing find_vm_area() function which does exactly what we want and checks for the NULL pointer. Link: http://lkml.kernel.org/r/20181228171009.22269-1-liviu@dudau.co.uk Fixes: f3c01d2f3ade ("mm: vmalloc: avoid racy handling of debugobjects in vunmap") Signed-off-by: Liviu Dudau Reviewed-by: Andrew Morton Cc: Chintan Pandya Cc: Andrey Ryabinin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Cc: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- mm/vmalloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index c74a087fcb7d..5d11aeceb7f8 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -1499,7 +1499,7 @@ static void __vunmap(const void *addr, int deallocate_pages) addr)) return; - area = find_vmap_area((unsigned long)addr)->vm; + area = find_vm_area(addr); if (unlikely(!area)) { WARN(1, KERN_ERR "Trying to vfree() nonexistent vm area (%p)\n", addr); From d5375ed938b7e85b443894f9e7090ec7e803d0cd Mon Sep 17 00:00:00 2001 From: Guoqing Jiang Date: Tue, 9 Apr 2019 16:16:38 +0800 Subject: [PATCH 212/387] sc16is7xx: move label 'err_spi' to correct section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit e00164a0f000de893944981f41a568c981aca658 upstream. err_spi is used when SERIAL_SC16IS7XX_SPI is enabled, so make the label only available under SERIAL_SC16IS7XX_SPI option. Otherwise, the below warning appears. drivers/tty/serial/sc16is7xx.c:1523:1: warning: label ‘err_spi’ defined but not used [-Wunused-label] err_spi: ^~~~~~~ Signed-off-by: Guoqing Jiang Fixes: ac0cdb3d9901 ("sc16is7xx: missing unregister/delete driver on error in sc16is7xx_init()") Signed-off-by: Arnd Bergmann Cc: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sc16is7xx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index f80a88d107d7..d8843657d787 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c @@ -1523,10 +1523,12 @@ static int __init sc16is7xx_init(void) #endif return ret; +#ifdef CONFIG_SERIAL_SC16IS7XX_SPI err_spi: #ifdef CONFIG_SERIAL_SC16IS7XX_I2C i2c_del_driver(&sc16is7xx_i2c_uart_driver); #endif +#endif err_i2c: uart_unregister_driver(&sc16is7xx_uart); return ret; From bd756613f02baa088d2ebb476b40c1334ef97cf6 Mon Sep 17 00:00:00 2001 From: Salil Mehta Date: Mon, 18 Feb 2019 17:40:32 +0000 Subject: [PATCH 213/387] net: hns: Fixes the missing put_device in positive leg for roce reset commit 4d96e13ee9cd1f7f801e8c7f4b12f09d1da4a5d8 upstream. This patch fixes the missing device reference release-after-use in the positive leg of the roce reset API of the HNS DSAF. Fixes: c969c6e7ab8c ("net: hns: Fix object reference leaks in hns_dsaf_roce_reset()") Reported-by: John Garry Signed-off-by: Salil Mehta Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c index 551b2a9ebf0f..4a4e86000192 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c @@ -2867,6 +2867,9 @@ int hns_dsaf_roce_reset(struct fwnode_handle *dsaf_fwnode, bool dereset) dsaf_set_bit(credit, DSAF_SBM_ROCEE_CFG_CRD_EN_B, 1); dsaf_write_dev(dsaf_dev, DSAF_SBM_ROCEE_CFG_REG_REG, credit); } + + put_device(&pdev->dev); + return 0; } EXPORT_SYMBOL(hns_dsaf_roce_reset); From f24116326e77bc26356be828d3cf2e9db402d3b2 Mon Sep 17 00:00:00 2001 From: Benjamin Block Date: Tue, 2 Jul 2019 23:02:01 +0200 Subject: [PATCH 214/387] scsi: zfcp: fix request object use-after-free in send path causing wrong traces [ Upstream commit 106d45f350c7cac876844dc685845cba4ffdb70b ] When tracing instances where we open and close WKA ports, we also pass the request-ID of the respective FSF command. But after successfully sending the FSF command we must not use the request-object anymore, as this might result in an use-after-free (see "zfcp: fix request object use-after-free in send path causing seqno errors" ). To fix this add a new variable that caches the request-ID before sending the request. This won't change during the hand-off to the FCP channel, and so it's safe to trace this cached request-ID later, instead of using the request object. Signed-off-by: Benjamin Block Fixes: d27a7cb91960 ("zfcp: trace on request for open and close of WKA port") Cc: #2.6.38+ Reviewed-by: Steffen Maier Reviewed-by: Jens Remus Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/s390/scsi/zfcp_fsf.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index a3aaef4c53a3..0d2bcb33697f 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -1594,6 +1594,7 @@ int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port) { struct zfcp_qdio *qdio = wka_port->adapter->qdio; struct zfcp_fsf_req *req; + unsigned long req_id = 0; int retval = -EIO; spin_lock_irq(&qdio->req_q_lock); @@ -1616,6 +1617,8 @@ int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port) hton24(req->qtcb->bottom.support.d_id, wka_port->d_id); req->data = wka_port; + req_id = req->req_id; + zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); retval = zfcp_fsf_req_send(req); if (retval) @@ -1623,7 +1626,7 @@ int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port) out: spin_unlock_irq(&qdio->req_q_lock); if (!retval) - zfcp_dbf_rec_run_wka("fsowp_1", wka_port, req->req_id); + zfcp_dbf_rec_run_wka("fsowp_1", wka_port, req_id); return retval; } @@ -1649,6 +1652,7 @@ int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port) { struct zfcp_qdio *qdio = wka_port->adapter->qdio; struct zfcp_fsf_req *req; + unsigned long req_id = 0; int retval = -EIO; spin_lock_irq(&qdio->req_q_lock); @@ -1671,6 +1675,8 @@ int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port) req->data = wka_port; req->qtcb->header.port_handle = wka_port->handle; + req_id = req->req_id; + zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); retval = zfcp_fsf_req_send(req); if (retval) @@ -1678,7 +1684,7 @@ int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port) out: spin_unlock_irq(&qdio->req_q_lock); if (!retval) - zfcp_dbf_rec_run_wka("fscwp_1", wka_port, req->req_id); + zfcp_dbf_rec_run_wka("fscwp_1", wka_port, req_id); return retval; } From af5595c4ae50545abbcc14515e5b15f823fb9b01 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 3 Jun 2020 08:16:48 +0200 Subject: [PATCH 215/387] Linux 4.9.226 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d17a2ad3cc4d..b0e1162fddfa 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 4 PATCHLEVEL = 9 -SUBLEVEL = 225 +SUBLEVEL = 226 EXTRAVERSION = NAME = Roaring Lionus From d74a350d7035b4711d3d76447e986446bb9e96f5 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 2 Oct 2017 16:26:37 +0200 Subject: [PATCH 216/387] scsi: scsi_devinfo: fixup string compare commit b8018b973c7cefa5eb386540130fa47315b8e337 upstream. When checking the model and vendor string we need to use the minimum value of either string, otherwise we'll miss out on wildcard matches. And we should take care when matching with zero size strings; results might be unpredictable. With this patch the rules for matching devinfo strings are as follows: - Vendor strings must match exactly - Empty Model strings will only match if the devinfo model is also empty - Model strings shorter than the devinfo model string will not match Fixes: 5e7ff2c ("SCSI: fix new bug in scsi_dev_info_list string matching") Signed-off-by: Hannes Reinecke Reviewed-by: Alan Stern Reviewed-by: Bart Van Assche Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen Cc: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/scsi_devinfo.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index 9d555b63d2e2..d596b76eea64 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -394,8 +394,8 @@ EXPORT_SYMBOL(scsi_dev_info_list_add_keyed); /** * scsi_dev_info_list_find - find a matching dev_info list entry. - * @vendor: vendor string - * @model: model (product) string + * @vendor: full vendor string + * @model: full model (product) string * @key: specify list to use * * Description: @@ -410,7 +410,7 @@ static struct scsi_dev_info_list *scsi_dev_info_list_find(const char *vendor, struct scsi_dev_info_list *devinfo; struct scsi_dev_info_list_table *devinfo_table = scsi_devinfo_lookup_by_key(key); - size_t vmax, mmax; + size_t vmax, mmax, mlen; const char *vskip, *mskip; if (IS_ERR(devinfo_table)) @@ -449,15 +449,18 @@ static struct scsi_dev_info_list *scsi_dev_info_list_find(const char *vendor, dev_info_list) { if (devinfo->compatible) { /* - * Behave like the older version of get_device_flags. + * vendor strings must be an exact match */ - if (memcmp(devinfo->vendor, vskip, vmax) || - (vmax < sizeof(devinfo->vendor) && - devinfo->vendor[vmax])) + if (vmax != strlen(devinfo->vendor) || + memcmp(devinfo->vendor, vskip, vmax)) continue; - if (memcmp(devinfo->model, mskip, mmax) || - (mmax < sizeof(devinfo->model) && - devinfo->model[mmax])) + + /* + * @model specifies the full string, and + * must be larger or equal to devinfo->model + */ + mlen = strlen(devinfo->model); + if (mmax < mlen || memcmp(devinfo->model, mskip, mlen)) continue; return devinfo; } else { From a7add20ecdbb2e1ccbe51c98610b8078062e6f79 Mon Sep 17 00:00:00 2001 From: Eugeniu Rosca Date: Thu, 21 Jun 2018 17:22:46 +0200 Subject: [PATCH 217/387] usb: gadget: f_uac2: fix error handling in afunc_bind (again) commit e87581fe0509020f77ebf0b7c4c1c338c6a4bcf6 upstream. If usb_ep_autoconfig() fails (i.e. returns a null endpoint descriptor), we expect afunc_bind() to fail (i.e. return a negative error code). However, due to v4.10-rc1 commit f1d3861d63a5 ("usb: gadget: f_uac2: fix error handling at afunc_bind"), afunc_bind() returns zero, telling the caller that it succeeded. This then generates NULL pointer dereference in below scenario on Rcar H3-ES20-Salvator-X target: rcar-gen3:/home/root# modprobe g_audio [ 626.521155] g_audio gadget: afunc_bind:565 Error! [ 626.526319] g_audio gadget: Linux USB Audio Gadget, version: Feb 2, 2012 [ 626.533405] g_audio gadget: g_audio ready rcar-gen3:/home/root# rcar-gen3:/home/root# modprobe -r g_audio [ 728.256707] ================================================================== [ 728.264293] BUG: KASAN: null-ptr-deref in u_audio_stop_capture+0x70/0x268 [u_audio] [ 728.272244] Read of size 8 at addr 00000000000000a0 by task modprobe/2545 [ 728.279309] [ 728.280849] CPU: 0 PID: 2545 Comm: modprobe Tainted: G WC 4.14.47+ #152 [ 728.288778] Hardware name: Renesas Salvator-X board based on r8a7795 ES2.0+ (DT) [ 728.296454] Call trace: [ 728.299151] [] dump_backtrace+0x0/0x364 [ 728.304808] [] show_stack+0x14/0x1c [ 728.310081] [] dump_stack+0x108/0x174 [ 728.315522] [] kasan_report+0x1fc/0x354 [ 728.321134] [] __asan_load8+0x24/0x94 [ 728.326600] [] u_audio_stop_capture+0x70/0x268 [u_audio] [ 728.333735] [] afunc_disable+0x44/0x60 [usb_f_uac2] [ 728.340503] [] usb_remove_function+0x9c/0x210 [libcomposite] [ 728.348060] [] remove_config.isra.2+0x1d8/0x218 [libcomposite] [ 728.355788] [] __composite_unbind+0x104/0x1f8 [libcomposite] [ 728.363339] [] composite_unbind+0x10/0x18 [libcomposite] [ 728.370536] [] usb_gadget_remove_driver+0xc0/0x170 [udc_core] [ 728.378172] [] usb_gadget_unregister_driver+0x1cc/0x258 [udc_core] [ 728.386274] [] usb_composite_unregister+0x10/0x18 [libcomposite] [ 728.394116] [] audio_driver_exit+0x14/0x28 [g_audio] [ 728.400878] [] SyS_delete_module+0x288/0x32c [ 728.406935] Exception stack(0xffff8006cf6c7ec0 to 0xffff8006cf6c8000) [ 728.413624] 7ec0: 0000000006136428 0000000000000800 0000000000000000 0000ffffd706efe8 [ 728.421718] 7ee0: 0000ffffd706efe9 000000000000000a 1999999999999999 0000000000000000 [ 728.429792] 7f00: 000000000000006a 000000000042c078 0000000000000000 0000000000000005 [ 728.437870] 7f20: 0000000000000000 0000000000000000 0000000000000004 0000000000000000 [ 728.445952] 7f40: 000000000042bfc8 0000ffffbc7c8f40 0000000000000000 00000000061363c0 [ 728.454035] 7f60: 0000000006136428 0000000000000000 0000000000000000 0000000006136428 [ 728.462114] 7f80: 000000000042c000 0000ffffd7071448 000000000042c000 0000000000000000 [ 728.470190] 7fa0: 00000000061350c0 0000ffffd7070010 000000000041129c 0000ffffd7070010 [ 728.478281] 7fc0: 0000ffffbc7c8f48 0000000060000000 0000000006136428 000000000000006a [ 728.486351] 7fe0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 [ 728.494434] [] el0_svc_naked+0x34/0x38 [ 728.499957] ================================================================== [ 728.507801] Unable to handle kernel NULL pointer dereference at virtual address 000000a0 [ 728.517742] Mem abort info: [ 728.520993] Exception class = DABT (current EL), IL = 32 bits [ 728.527375] SET = 0, FnV = 0 [ 728.530731] EA = 0, S1PTW = 0 [ 728.534361] Data abort info: [ 728.537650] ISV = 0, ISS = 0x00000006 [ 728.541863] CM = 0, WnR = 0 [ 728.545167] user pgtable: 4k pages, 48-bit VAs, pgd = ffff8006c6100000 [ 728.552156] [00000000000000a0] *pgd=0000000716a8d003 [ 728.557519] , *pud=00000007116fc003 [ 728.561259] , *pmd=0000000000000000 [ 728.564985] Internal error: Oops: 96000006 [#1] PREEMPT SMP [ 728.570815] Modules linked in: [ 728.574023] usb_f_uac2 [ 728.576560] u_audio [ 728.578827] g_audio(-) [ 728.581361] libcomposite [ 728.584071] configfs [ 728.586428] aes_ce_blk [ 728.588960] sata_rcar [ 728.591421] crypto_simd [ 728.594039] cryptd [ 728.596217] libata [ 728.598396] aes_ce_cipher [ 728.601188] crc32_ce [ 728.603542] ghash_ce [ 728.605896] gf128mul [ 728.608250] aes_arm64 [ 728.610692] scsi_mod [ 728.613046] sha2_ce [ 728.615313] xhci_plat_hcd [ 728.618106] sha256_arm64 [ 728.620811] sha1_ce [ 728.623077] renesas_usbhs [ 728.625869] xhci_hcd [ 728.628243] renesas_usb3 [ 728.630948] sha1_generic [ 728.633670] ravb_streaming(C) [ 728.636814] udc_core [ 728.639168] cpufreq_dt [ 728.641697] rcar_gen3_thermal [ 728.644840] usb_dmac [ 728.647194] pwm_rcar [ 728.649548] thermal_sys [ 728.652165] virt_dma [ 728.654519] mch_core(C) [ 728.657137] pwm_bl [ 728.659315] snd_soc_rcar [ 728.662020] snd_aloop [ 728.664462] snd_soc_generic_card [ 728.667869] snd_soc_ak4613 [ 728.670749] ipv6 [ 728.672768] autofs4 [ 728.675052] CPU: 0 PID: 2545 Comm: modprobe Tainted: G B WC 4.14.47+ #152 [ 728.682973] Hardware name: Renesas Salvator-X board based on r8a7795 ES2.0+ (DT) [ 728.690637] task: ffff8006ced38000 task.stack: ffff8006cf6c0000 [ 728.696814] PC is at u_audio_stop_capture+0x70/0x268 [u_audio] [ 728.702896] LR is at u_audio_stop_capture+0x70/0x268 [u_audio] [ 728.708964] pc : [] lr : [] pstate: 60000145 [ 728.716620] sp : ffff8006cf6c7a50 [ 728.720154] x29: ffff8006cf6c7a50 [ 728.723760] x28: ffff8006ced38000 [ 728.727272] x27: ffff200008fd7000 [ 728.730857] x26: ffff2000021d2340 [ 728.734361] x25: 0000000000000000 [ 728.737948] x24: ffff200009e94b08 [ 728.741452] x23: 00000000000000a0 [ 728.745052] x22: 00000000000000a8 [ 728.748558] x21: 1ffff000d9ed8f7c [ 728.752142] x20: ffff8006d671a800 [ 728.755646] x19: 0000000000000000 [ 728.759231] x18: 0000000000000000 [ 728.762736] x17: 0000ffffbc7c8f40 [ 728.766320] x16: ffff200008213c4c [ 728.769823] x15: 0000000000000000 [ 728.773408] x14: 0720072007200720 [ 728.776912] x13: 0720072007200720 [ 728.780497] x12: ffffffffffffffff [ 728.784001] x11: 0000000000000040 [ 728.787598] x10: 0000000000001600 [ 728.791103] x9 : ffff8006cf6c77a0 [ 728.794689] x8 : ffff8006ced39660 [ 728.798193] x7 : ffff20000811c738 [ 728.801794] x6 : 0000000000000000 [ 728.805299] x5 : dfff200000000000 [ 728.808885] x4 : ffff8006ced38000 [ 728.812390] x3 : ffff200008fb46e8 [ 728.815976] x2 : 0000000000000007 [ 728.819480] x1 : 3ba68643e7431500 [ 728.823066] x0 : 0000000000000000 [ 728.826574] Process modprobe (pid: 2545, stack limit = 0xffff8006cf6c0000) [ 728.833704] Call trace: [ 728.836292] Exception stack(0xffff8006cf6c7910 to 0xffff8006cf6c7a50) [ 728.842987] 7900: 0000000000000000 3ba68643e7431500 [ 728.851084] 7920: 0000000000000007 ffff200008fb46e8 ffff8006ced38000 dfff200000000000 [ 728.859173] 7940: 0000000000000000 ffff20000811c738 ffff8006ced39660 ffff8006cf6c77a0 [ 728.867248] 7960: 0000000000001600 0000000000000040 ffffffffffffffff 0720072007200720 [ 728.875323] 7980: 0720072007200720 0000000000000000 ffff200008213c4c 0000ffffbc7c8f40 [ 728.883412] 79a0: 0000000000000000 0000000000000000 ffff8006d671a800 1ffff000d9ed8f7c [ 728.891485] 79c0: 00000000000000a8 00000000000000a0 ffff200009e94b08 0000000000000000 [ 728.899561] 79e0: ffff2000021d2340 ffff200008fd7000 ffff8006ced38000 ffff8006cf6c7a50 [ 728.907636] 7a00: ffff2000021e1618 ffff8006cf6c7a50 ffff2000021e1618 0000000060000145 [ 728.915710] 7a20: 0000000000000008 0000000000000000 0000ffffffffffff 3ba68643e7431500 [ 728.923780] 7a40: ffff8006cf6c7a50 ffff2000021e1618 [ 728.928880] [] u_audio_stop_capture+0x70/0x268 [u_audio] [ 728.936032] [] afunc_disable+0x44/0x60 [usb_f_uac2] [ 728.942822] [] usb_remove_function+0x9c/0x210 [libcomposite] [ 728.950385] [] remove_config.isra.2+0x1d8/0x218 [libcomposite] [ 728.958134] [] __composite_unbind+0x104/0x1f8 [libcomposite] [ 728.965689] [] composite_unbind+0x10/0x18 [libcomposite] [ 728.972882] [] usb_gadget_remove_driver+0xc0/0x170 [udc_core] [ 728.980522] [] usb_gadget_unregister_driver+0x1cc/0x258 [udc_core] [ 728.988638] [] usb_composite_unregister+0x10/0x18 [libcomposite] [ 728.996472] [] audio_driver_exit+0x14/0x28 [g_audio] [ 729.003231] [] SyS_delete_module+0x288/0x32c [ 729.009278] Exception stack(0xffff8006cf6c7ec0 to 0xffff8006cf6c8000) [ 729.015946] 7ec0: 0000000006136428 0000000000000800 0000000000000000 0000ffffd706efe8 [ 729.024022] 7ee0: 0000ffffd706efe9 000000000000000a 1999999999999999 0000000000000000 [ 729.032099] 7f00: 000000000000006a 000000000042c078 0000000000000000 0000000000000005 [ 729.040172] 7f20: 0000000000000000 0000000000000000 0000000000000004 0000000000000000 [ 729.048263] 7f40: 000000000042bfc8 0000ffffbc7c8f40 0000000000000000 00000000061363c0 [ 729.056337] 7f60: 0000000006136428 0000000000000000 0000000000000000 0000000006136428 [ 729.064411] 7f80: 000000000042c000 0000ffffd7071448 000000000042c000 0000000000000000 [ 729.072484] 7fa0: 00000000061350c0 0000ffffd7070010 000000000041129c 0000ffffd7070010 [ 729.080563] 7fc0: 0000ffffbc7c8f48 0000000060000000 0000000006136428 000000000000006a [ 729.088636] 7fe0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 [ 729.096733] [] el0_svc_naked+0x34/0x38 [ 729.102259] Code: 9597d1b3 aa1703e0 9102a276 958792b9 (f9405275) [ 729.108617] ---[ end trace 7560c5fa3d100243 ]--- After this patch is applied, the issue is fixed: rcar-gen3:/home/root# modprobe g_audio [ 59.217127] g_audio gadget: afunc_bind:565 Error! [ 59.222329] g_audio ee020000.usb: failed to start g_audio: -19 modprobe: ERROR: could not insert 'g_audio': No such device rcar-gen3:/home/root# modprobe -r g_audio rcar-gen3:/home/root# Fixes: f1d3861d63a5 ("usb: gadget: f_uac2: fix error handling at afunc_bind") Signed-off-by: Eugeniu Rosca Signed-off-by: Felipe Balbi Cc: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/f_uac2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index f4bd08cfac11..a631975e050d 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -1069,13 +1069,13 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc); if (!agdev->out_ep) { dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); - return ret; + return -ENODEV; } agdev->in_ep = usb_ep_autoconfig(gadget, &fs_epin_desc); if (!agdev->in_ep) { dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); - return ret; + return -ENODEV; } uac2->p_prm.uac2 = uac2; From 7aebadb465fe3d7798a42d3de6907da7ac78419d Mon Sep 17 00:00:00 2001 From: Zhen Lei Date: Wed, 27 Jun 2018 11:49:28 +0800 Subject: [PATCH 218/387] esp6: fix memleak on error path in esp6_input commit 7284fdf39a912322ce97de2d30def3c6068a418c upstream. This ought to be an omission in e6194923237 ("esp: Fix memleaks on error paths."). The memleak on error path in esp6_input is similar to esp_input of esp4. Fixes: e6194923237 ("esp: Fix memleaks on error paths.") Fixes: 3f29770723f ("ipsec: check return value of skb_to_sgvec always") Signed-off-by: Zhen Lei Signed-off-by: Steffen Klassert Cc: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- net/ipv6/esp6.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 6a924be66e37..da158a3acac4 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c @@ -426,8 +426,10 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) sg_init_table(sg, nfrags); ret = skb_to_sgvec(skb, sg, 0, skb->len); - if (unlikely(ret < 0)) + if (unlikely(ret < 0)) { + kfree(tmp); goto out; + } aead_request_set_crypt(req, sg, sg, elen + ivlen, iv); aead_request_set_ad(req, assoclen); From 5720901bcfcf35f57defba352111f40ffecbb30e Mon Sep 17 00:00:00 2001 From: Xinwei Kong Date: Fri, 3 Jan 2020 10:52:10 +0800 Subject: [PATCH 219/387] spi: dw: use "smp_mb()" to avoid sending spi data error [ Upstream commit bfda044533b213985bc62bd7ca96f2b984d21b80 ] Because of out-of-order execution about some CPU architecture, In this debug stage we find Completing spi interrupt enable -> prodrucing TXEI interrupt -> running "interrupt_transfer" function will prior to set "dw->rx and dws->rx_end" data, so this patch add memory barrier to enable dw->rx and dw->rx_end to be visible and solve to send SPI data error. eg: it will fix to this following low possibility error in testing environment which using SPI control to connect TPM Modules kernel: tpm tpm0: Operation Timed out kernel: tpm tpm0: tpm_relinquish_locality: : error -1 Signed-off-by: fengsheng Signed-off-by: Xinwei Kong Link: https://lore.kernel.org/r/1578019930-55858-1-git-send-email-kong.kongxinwei@hisilicon.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-dw.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index 16f0def9df82..babf0a337e96 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -305,6 +305,9 @@ static int dw_spi_transfer_one(struct spi_master *master, dws->len = transfer->len; spin_unlock_irqrestore(&dws->buf_lock, flags); + /* Ensure dw->rx and dw->rx_end are visible */ + smp_mb(); + spi_enable_chip(dws, 0); /* Handle per transfer options for bpw and speed */ From 4237e949fc8bb7c8518a3e8352f12883f061a336 Mon Sep 17 00:00:00 2001 From: Vasily Gorbik Date: Tue, 10 Dec 2019 13:50:23 +0100 Subject: [PATCH 220/387] s390/ftrace: save traced function caller [ Upstream commit b4adfe55915d8363e244e42386d69567db1719b9 ] A typical backtrace acquired from ftraced function currently looks like the following (e.g. for "path_openat"): arch_stack_walk+0x15c/0x2d8 stack_trace_save+0x50/0x68 stack_trace_call+0x15a/0x3b8 ftrace_graph_caller+0x0/0x1c 0x3e0007e3c98 <- ftraced function caller (should be do_filp_open+0x7c/0xe8) do_open_execat+0x70/0x1b8 __do_execve_file.isra.0+0x7d8/0x860 __s390x_sys_execve+0x56/0x68 system_call+0xdc/0x2d8 Note random "0x3e0007e3c98" stack value as ftraced function caller. This value causes either imprecise unwinder result or unwinding failure. That "0x3e0007e3c98" comes from r14 of ftraced function stack frame, which it haven't had a chance to initialize since the very first instruction calls ftrace code ("ftrace_caller"). (ftraced function might never save r14 as well). Nevertheless according to s390 ABI any function is called with stack frame allocated for it and r14 contains return address. "ftrace_caller" itself is called with "brasl %r0,ftrace_caller". So, to fix this issue simply always save traced function caller onto ftraced function stack frame. Reported-by: Sven Schnelle Signed-off-by: Vasily Gorbik Signed-off-by: Sasha Levin --- arch/s390/kernel/mcount.S | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/s390/kernel/mcount.S b/arch/s390/kernel/mcount.S index 802a4ded9a62..e9df35249f9f 100644 --- a/arch/s390/kernel/mcount.S +++ b/arch/s390/kernel/mcount.S @@ -39,6 +39,7 @@ EXPORT_SYMBOL(_mcount) ENTRY(ftrace_caller) .globl ftrace_regs_caller .set ftrace_regs_caller,ftrace_caller + stg %r14,(__SF_GPRS+8*8)(%r15) # save traced function caller lgr %r1,%r15 #ifndef CC_USING_HOTPATCH aghi %r0,MCOUNT_RETURN_FIXUP From d710605701d32cf465624c3d907894b0fe616ca6 Mon Sep 17 00:00:00 2001 From: Eugeniy Paltsev Date: Thu, 2 Apr 2020 20:54:28 +0300 Subject: [PATCH 221/387] ARC: Fix ICCM & DCCM runtime size checks [ Upstream commit 43900edf67d7ef3ac8909854d75b8a1fba2d570c ] As of today the ICCM and DCCM size checks are incorrectly using mismatched units (KiB checked against bytes). The CONFIG_ARC_DCCM_SZ and CONFIG_ARC_ICCM_SZ are in KiB, but the size calculated in runtime and stored in cpu->dccm.sz and cpu->iccm.sz is in bytes. Fix that. Reported-by: Paul Greco Signed-off-by: Eugeniy Paltsev Signed-off-by: Vineet Gupta Signed-off-by: Sasha Levin --- arch/arc/kernel/setup.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index 9f96120eee6e..82464fae7772 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -333,12 +334,12 @@ static void arc_chk_core_config(void) if ((unsigned int)__arc_dccm_base != cpu->dccm.base_addr) panic("Linux built with incorrect DCCM Base address\n"); - if (CONFIG_ARC_DCCM_SZ != cpu->dccm.sz) + if (CONFIG_ARC_DCCM_SZ * SZ_1K != cpu->dccm.sz) panic("Linux built with incorrect DCCM Size\n"); #endif #ifdef CONFIG_ARC_HAS_ICCM - if (CONFIG_ARC_ICCM_SZ != cpu->iccm.sz) + if (CONFIG_ARC_ICCM_SZ * SZ_1K != cpu->iccm.sz) panic("Linux built with incorrect ICCM Size\n"); #endif From c4400d9d7fa008bcec403fbca397f00b6fe81aaa Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Wed, 8 Apr 2020 13:53:23 -0700 Subject: [PATCH 222/387] x86/mmiotrace: Use cpumask_available() for cpumask_var_t variables [ Upstream commit d7110a26e5905ec2fe3fc88bc6a538901accb72b ] When building with Clang + -Wtautological-compare and CONFIG_CPUMASK_OFFSTACK unset: arch/x86/mm/mmio-mod.c:375:6: warning: comparison of array 'downed_cpus' equal to a null pointer is always false [-Wtautological-pointer-compare] if (downed_cpus == NULL && ^~~~~~~~~~~ ~~~~ arch/x86/mm/mmio-mod.c:405:6: warning: comparison of array 'downed_cpus' equal to a null pointer is always false [-Wtautological-pointer-compare] if (downed_cpus == NULL || cpumask_weight(downed_cpus) == 0) ^~~~~~~~~~~ ~~~~ 2 warnings generated. Commit f7e30f01a9e2 ("cpumask: Add helper cpumask_available()") added cpumask_available() to fix warnings of this nature. Use that here so that clang does not warn regardless of CONFIG_CPUMASK_OFFSTACK's value. Reported-by: Sedat Dilek Signed-off-by: Nathan Chancellor Signed-off-by: Borislav Petkov Reviewed-by: Nick Desaulniers Acked-by: Steven Rostedt (VMware) Link: https://github.com/ClangBuiltLinux/linux/issues/982 Link: https://lkml.kernel.org/r/20200408205323.44490-1-natechancellor@gmail.com Signed-off-by: Sasha Levin --- arch/x86/mm/mmio-mod.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c index bef36622e408..abd4fa587ca4 100644 --- a/arch/x86/mm/mmio-mod.c +++ b/arch/x86/mm/mmio-mod.c @@ -385,7 +385,7 @@ static void enter_uniprocessor(void) int cpu; int err; - if (downed_cpus == NULL && + if (!cpumask_available(downed_cpus) && !alloc_cpumask_var(&downed_cpus, GFP_KERNEL)) { pr_notice("Failed to allocate mask\n"); goto out; @@ -415,7 +415,7 @@ static void leave_uniprocessor(void) int cpu; int err; - if (downed_cpus == NULL || cpumask_weight(downed_cpus) == 0) + if (!cpumask_available(downed_cpus) || cpumask_weight(downed_cpus) == 0) return; pr_notice("Re-enabling CPUs...\n"); for_each_cpu(cpu, downed_cpus) { From 9849292d6fd76d393970cb9a3911732131e4af2a Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Tue, 19 May 2020 09:05:58 +0800 Subject: [PATCH 223/387] net: bmac: Fix read of MAC address from ROM [ Upstream commit ef01cee2ee1b369c57a936166483d40942bcc3e3 ] In bmac_get_station_address, We're reading two bytes at a time from ROM, but we do that six times, resulting in 12 bytes of read & writes. This means we will write off the end of the six-byte destination buffer. This change fixes the for-loop to only read/write six bytes. Based on a proposed fix from Finn Thain . Signed-off-by: Jeremy Kerr Reported-by: Stan Johnson Tested-by: Stan Johnson Reported-by: Finn Thain Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/apple/bmac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/apple/bmac.c b/drivers/net/ethernet/apple/bmac.c index a65d7a60f116..ffa7e7e6d18d 100644 --- a/drivers/net/ethernet/apple/bmac.c +++ b/drivers/net/ethernet/apple/bmac.c @@ -1187,7 +1187,7 @@ bmac_get_station_address(struct net_device *dev, unsigned char *ea) int i; unsigned short data; - for (i = 0; i < 6; i++) + for (i = 0; i < 3; i++) { reset_and_select_srom(dev); data = read_srom(dev, i + EnetAddressOffset/2, SROMAddressBits); From dee26e8809495f47349d9210bfa37bd9eb40491d Mon Sep 17 00:00:00 2001 From: Valentin Longchamp Date: Wed, 20 May 2020 17:53:50 +0200 Subject: [PATCH 224/387] net/ethernet/freescale: rework quiesce/activate for ucc_geth [ Upstream commit 79dde73cf9bcf1dd317a2667f78b758e9fe139ed ] ugeth_quiesce/activate are used to halt the controller when there is a link change that requires to reconfigure the mac. The previous implementation called netif_device_detach(). This however causes the initial activation of the netdevice to fail precisely because it's detached. For details, see [1]. A possible workaround was the revert of commit net: linkwatch: add check for netdevice being present to linkwatch_do_dev However, the check introduced in the above commit is correct and shall be kept. The netif_device_detach() is thus replaced with netif_tx_stop_all_queues() that prevents any tranmission. This allows to perform mac config change required by the link change, without detaching the corresponding netdevice and thus not preventing its initial activation. [1] https://lists.openwall.net/netdev/2020/01/08/201 Signed-off-by: Valentin Longchamp Acked-by: Matteo Ghidoni Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/freescale/ucc_geth.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c index 714593023bbc..af922bac19ae 100644 --- a/drivers/net/ethernet/freescale/ucc_geth.c +++ b/drivers/net/ethernet/freescale/ucc_geth.c @@ -45,6 +45,7 @@ #include #include #include +#include #include "ucc_geth.h" @@ -1551,11 +1552,8 @@ static int ugeth_disable(struct ucc_geth_private *ugeth, enum comm_dir mode) static void ugeth_quiesce(struct ucc_geth_private *ugeth) { - /* Prevent any further xmits, plus detach the device. */ - netif_device_detach(ugeth->ndev); - - /* Wait for any current xmits to finish. */ - netif_tx_disable(ugeth->ndev); + /* Prevent any further xmits */ + netif_tx_stop_all_queues(ugeth->ndev); /* Disable the interrupt to avoid NAPI rescheduling. */ disable_irq(ugeth->ug_info->uf_info.irq); @@ -1568,7 +1566,10 @@ static void ugeth_activate(struct ucc_geth_private *ugeth) { napi_enable(&ugeth->napi); enable_irq(ugeth->ug_info->uf_info.irq); - netif_device_attach(ugeth->ndev); + + /* allow to xmit again */ + netif_tx_wake_all_queues(ugeth->ndev); + __netdev_watchdog_up(ugeth->ndev); } /* Called every time the controller might need to be made From 7b880cc0206603b35175061da9d2c1830c9d12a8 Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Thu, 21 May 2020 12:49:34 +0100 Subject: [PATCH 225/387] net: ethernet: stmmac: Enable interface clocks on probe for IPQ806x [ Upstream commit a96ac8a0045e3cbe3e5af6d1b3c78c6c2065dec5 ] The ipq806x_gmac_probe() function enables the PTP clock but not the appropriate interface clocks. This means that if the bootloader hasn't done so attempting to bring up the interface will fail with an error like: [ 59.028131] ipq806x-gmac-dwmac 37600000.ethernet: Failed to reset the dma [ 59.028196] ipq806x-gmac-dwmac 37600000.ethernet eth1: stmmac_hw_setup: DMA engine initialization failed [ 59.034056] ipq806x-gmac-dwmac 37600000.ethernet eth1: stmmac_open: Hw setup failed This patch, a slightly cleaned up version of one posted by Sergey Sergeev in: https://forum.openwrt.org/t/support-for-mikrotik-rb3011uias-rm/4064/257 correctly enables the clock; we have already configured the source just before this. Tested on a MikroTik RB3011. Signed-off-by: Jonathan McDowell Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c index 11a4a81b0397..bcc5d1e16ce2 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c @@ -330,6 +330,19 @@ static int ipq806x_gmac_probe(struct platform_device *pdev) /* Enable PTP clock */ regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val); val |= NSS_COMMON_CLK_GATE_PTP_EN(gmac->id); + switch (gmac->phy_mode) { + case PHY_INTERFACE_MODE_RGMII: + val |= NSS_COMMON_CLK_GATE_RGMII_RX_EN(gmac->id) | + NSS_COMMON_CLK_GATE_RGMII_TX_EN(gmac->id); + break; + case PHY_INTERFACE_MODE_SGMII: + val |= NSS_COMMON_CLK_GATE_GMII_RX_EN(gmac->id) | + NSS_COMMON_CLK_GATE_GMII_TX_EN(gmac->id); + break; + default: + /* We don't get here; the switch above will have errored out */ + unreachable(); + } regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val); if (gmac->phy_mode == PHY_INTERFACE_MODE_SGMII) { From 0e7767215f6888575a5bffbd12506935943ec6f6 Mon Sep 17 00:00:00 2001 From: Dinghao Liu Date: Sat, 23 May 2020 16:08:20 +0800 Subject: [PATCH 226/387] net: smsc911x: Fix runtime PM imbalance on error [ Upstream commit 539d39ad0c61b35f69565a037d7586deaf6d6166 ] Remove runtime PM usage counter decrement when the increment function has not been called to keep the counter balanced. Signed-off-by: Dinghao Liu Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/smsc/smsc911x.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index 4143659615e1..264136dba674 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -2506,20 +2506,20 @@ static int smsc911x_drv_probe(struct platform_device *pdev) retval = smsc911x_init(dev); if (retval < 0) - goto out_disable_resources; + goto out_init_fail; netif_carrier_off(dev); retval = smsc911x_mii_init(pdev, dev); if (retval) { SMSC_WARN(pdata, probe, "Error %i initialising mii", retval); - goto out_disable_resources; + goto out_init_fail; } retval = register_netdev(dev); if (retval) { SMSC_WARN(pdata, probe, "Error %i registering device", retval); - goto out_disable_resources; + goto out_init_fail; } else { SMSC_TRACE(pdata, probe, "Network interface: \"%s\"", dev->name); @@ -2560,9 +2560,10 @@ static int smsc911x_drv_probe(struct platform_device *pdev) return 0; -out_disable_resources: +out_init_fail: pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); +out_disable_resources: (void)smsc911x_disable_resources(pdev); out_enable_resources_fail: smsc911x_free_resources(pdev); From b1fa53f2bc3b99760ab94fe1455b41ec8bb06de9 Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Thu, 14 May 2020 12:15:39 +0200 Subject: [PATCH 227/387] pppoe: only process PADT targeted at local interfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't want to disconnect a session because of a stray PADT arriving while the interface is in promiscuous mode. Furthermore, multicast and broadcast packets make no sense here, so only PACKET_HOST is accepted. Reported-by: David Balažic Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Guillaume Nault Signed-off-by: David S. Miller --- drivers/net/ppp/pppoe.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c index fa8f7c40a384..804c52c35f07 100644 --- a/drivers/net/ppp/pppoe.c +++ b/drivers/net/ppp/pppoe.c @@ -494,6 +494,9 @@ static int pppoe_disc_rcv(struct sk_buff *skb, struct net_device *dev, if (!skb) goto out; + if (skb->pkt_type != PACKET_HOST) + goto abort; + if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr))) goto abort; From c915cffda0a4329ee454646138fe2b11c5ba3cd6 Mon Sep 17 00:00:00 2001 From: Fan Yang Date: Thu, 4 Jun 2020 18:22:07 +0800 Subject: [PATCH 228/387] mm: Fix mremap not considering huge pmd devmap commit 5bfea2d9b17f1034a68147a8b03b9789af5700f9 upstream. The original code in mm/mremap.c checks huge pmd by: if (is_swap_pmd(*old_pmd) || pmd_trans_huge(*old_pmd)) { However, a DAX mapped nvdimm is mapped as huge page (by default) but it is not transparent huge page (_PAGE_PSE | PAGE_DEVMAP). This commit changes the condition to include the case. This addresses CVE-2020-10757. Fixes: 5c7fb56e5e3f ("mm, dax: dax-pmd vs thp-pmd vs hugetlbfs-pmd") Cc: Reported-by: Fan Yang Signed-off-by: Fan Yang Tested-by: Fan Yang Tested-by: Dan Williams Reviewed-by: Dan Williams Acked-by: Kirill A. Shutemov Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- arch/x86/include/asm/pgtable.h | 1 + mm/mremap.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 5736306bdaab..e638e3bc3cb8 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -203,6 +203,7 @@ static inline int pmd_large(pmd_t pte) } #ifdef CONFIG_TRANSPARENT_HUGEPAGE +/* NOTE: when predicate huge page, consider also pmd_devmap, or use pmd_large */ static inline int pmd_trans_huge(pmd_t pmd) { return (pmd_val(pmd) & (_PAGE_PSE|_PAGE_DEVMAP)) == _PAGE_PSE; diff --git a/mm/mremap.c b/mm/mremap.c index 9e6035969d7b..b5d8d25173c6 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -212,7 +212,7 @@ unsigned long move_page_tables(struct vm_area_struct *vma, new_pmd = alloc_new_pmd(vma->vm_mm, vma, new_addr); if (!new_pmd) break; - if (pmd_trans_huge(*old_pmd)) { + if (pmd_trans_huge(*old_pmd) || pmd_devmap(*old_pmd)) { if (extent == HPAGE_PMD_SIZE) { bool moved; /* See comment in move_ptes() */ From 80581e21f6af43e3ae44c7f5dd935e5097edd380 Mon Sep 17 00:00:00 2001 From: Julian Sax Date: Tue, 5 May 2020 17:10:42 +0200 Subject: [PATCH 229/387] HID: i2c-hid: add Schneider SCL142ALM to descriptor override commit 6507ef10660efdfee93f0f3b9fac24b5e4d83e56 upstream. This device uses the SIPODEV SP1064 touchpad, which does not supply descriptors, so it has to be added to the override list. Cc: stable@vger.kernel.org Signed-off-by: Julian Sax Signed-off-by: Jiri Kosina Signed-off-by: Greg Kroah-Hartman --- drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c index 95052373a828..681ac9bc68b3 100644 --- a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c +++ b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c @@ -381,6 +381,14 @@ static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = { }, .driver_data = (void *)&sipodev_desc }, + { + .ident = "Schneider SCL142ALM", + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SCHNEIDER"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SCL142ALM"), + }, + .driver_data = (void *)&sipodev_desc + }, { } /* Terminate list */ }; From 5ac8ff17970490105f23f32074306518beab67b0 Mon Sep 17 00:00:00 2001 From: Giuseppe Marco Randazzo Date: Mon, 6 Apr 2020 00:06:59 +0200 Subject: [PATCH 230/387] p54usb: add AirVasT USB stick device-id commit 63e49a9fdac1b4e97ac26cb3fe953f210d83bc53 upstream. This patch adds the AirVasT USB wireless devices 124a:4026 to the list of supported devices. It's using the ISL3886 usb firmware. Without this modification, the wiki adapter is not recognized. Cc: Signed-off-by: Giuseppe Marco Randazzo Signed-off-by: Christian Lamparter [formatted, reworded] Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200405220659.45621-1-chunkeey@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/intersil/p54/p54usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/intersil/p54/p54usb.c b/drivers/net/wireless/intersil/p54/p54usb.c index 4a197a32d78c..979fcef1d848 100644 --- a/drivers/net/wireless/intersil/p54/p54usb.c +++ b/drivers/net/wireless/intersil/p54/p54usb.c @@ -64,6 +64,7 @@ static struct usb_device_id p54u_table[] = { {USB_DEVICE(0x0db0, 0x6826)}, /* MSI UB54G (MS-6826) */ {USB_DEVICE(0x107b, 0x55f2)}, /* Gateway WGU-210 (Gemtek) */ {USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */ + {USB_DEVICE(0x124a, 0x4026)}, /* AirVasT USB wireless device */ {USB_DEVICE(0x1435, 0x0210)}, /* Inventel UR054G */ {USB_DEVICE(0x15a9, 0x0002)}, /* Gemtek WUBI-100GW 802.11g */ {USB_DEVICE(0x1630, 0x0005)}, /* 2Wire 802.11g USB (v1) / Z-Com */ From d1774b0459875e2bf3e93b86294296e5494fd0b7 Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Thu, 4 Jun 2020 16:51:27 -0700 Subject: [PATCH 231/387] kernel/relay.c: handle alloc_percpu returning NULL in relay_open commit 54e200ab40fc14c863bcc80a51e20b7906608fce upstream. alloc_percpu() may return NULL, which means chan->buf may be set to NULL. In that case, when we do *per_cpu_ptr(chan->buf, ...), we dereference an invalid pointer: BUG: Unable to handle kernel data access at 0x7dae0000 Faulting instruction address: 0xc0000000003f3fec ... NIP relay_open+0x29c/0x600 LR relay_open+0x270/0x600 Call Trace: relay_open+0x264/0x600 (unreliable) __blk_trace_setup+0x254/0x600 blk_trace_setup+0x68/0xa0 sg_ioctl+0x7bc/0x2e80 do_vfs_ioctl+0x13c/0x1300 ksys_ioctl+0x94/0x130 sys_ioctl+0x48/0xb0 system_call+0x5c/0x68 Check if alloc_percpu returns NULL. This was found by syzkaller both on x86 and powerpc, and the reproducer it found on powerpc is capable of hitting the issue as an unprivileged user. Fixes: 017c59c042d0 ("relay: Use per CPU constructs for the relay channel buffer pointers") Reported-by: syzbot+1e925b4b836afe85a1c6@syzkaller-ppc64.appspotmail.com Reported-by: syzbot+587b2421926808309d21@syzkaller-ppc64.appspotmail.com Reported-by: syzbot+58320b7171734bf79d26@syzkaller.appspotmail.com Reported-by: syzbot+d6074fb08bdb2e010520@syzkaller.appspotmail.com Signed-off-by: Daniel Axtens Signed-off-by: Andrew Morton Reviewed-by: Michael Ellerman Reviewed-by: Andrew Donnellan Acked-by: David Rientjes Cc: Akash Goel Cc: Andrew Donnellan Cc: Guenter Roeck Cc: Salvatore Bonaccorso Cc: [4.10+] Link: http://lkml.kernel.org/r/20191219121256.26480-1-dja@axtens.net Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- kernel/relay.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/kernel/relay.c b/kernel/relay.c index 91e8fbf8aff3..5034cb3a339f 100644 --- a/kernel/relay.c +++ b/kernel/relay.c @@ -578,6 +578,11 @@ struct rchan *relay_open(const char *base_filename, return NULL; chan->buf = alloc_percpu(struct rchan_buf *); + if (!chan->buf) { + kfree(chan); + return NULL; + } + chan->version = RELAYFS_CHANNEL_VERSION; chan->n_subbufs = n_subbufs; chan->subbuf_size = subbuf_size; From a7481f5f1abeb1e5ed51b2f755eb75f2aa7f4741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Pouiller?= Date: Mon, 11 May 2020 18:19:02 +0200 Subject: [PATCH 232/387] mmc: fix compilation of user API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 83fc5dd57f86c3ec7d6d22565a6ff6c948853b64 upstream. The definitions of MMC_IOC_CMD and of MMC_IOC_MULTI_CMD rely on MMC_BLOCK_MAJOR: #define MMC_IOC_CMD _IOWR(MMC_BLOCK_MAJOR, 0, struct mmc_ioc_cmd) #define MMC_IOC_MULTI_CMD _IOWR(MMC_BLOCK_MAJOR, 1, struct mmc_ioc_multi_cmd) However, MMC_BLOCK_MAJOR is defined in linux/major.h and linux/mmc/ioctl.h did not include it. Signed-off-by: Jérôme Pouiller Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20200511161902.191405-1-Jerome.Pouiller@silabs.com Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman --- include/uapi/linux/mmc/ioctl.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/uapi/linux/mmc/ioctl.h b/include/uapi/linux/mmc/ioctl.h index 7e385b83b9d8..fe4b6b69d79a 100644 --- a/include/uapi/linux/mmc/ioctl.h +++ b/include/uapi/linux/mmc/ioctl.h @@ -2,6 +2,7 @@ #define LINUX_MMC_IOCTL_H #include +#include struct mmc_ioc_cmd { /* Implies direction of data. true = write, false = read */ From f8535892e13ea72d3a1dedc7f171854fc765fcc9 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 2 Jun 2020 18:54:18 +0100 Subject: [PATCH 233/387] slcan: Fix double-free on slcan_open() error path Commit 9ebd796e2400 ("can: slcan: Fix use-after-free Read in slcan_open") was incorrectly backported to 4.4 and 4.9 stable branches. Since they do not have commit cf124db566e6 ("net: Fix inconsistent teardown and release of private netdev state."), the destructor function slc_free_netdev() is already responsible for calling free_netdev() and slcan_open() must not call both of them. yangerkun previously fixed the same bug in slip. Fixes: ce624b2089ea ("can: slcan: Fix use-after-free Read in slcan_open") # 4.4 Fixes: f59604a80fa4 ("slcan: not call free_netdev before rtnl_unlock ...") # 4.4 Fixes: 56635a1e6ffb ("can: slcan: Fix use-after-free Read in slcan_open") # 4.9 Fixes: a1c9b23142ac ("slcan: not call free_netdev before rtnl_unlock ...") # 4.9 Cc: yangerkun Signed-off-by: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- drivers/net/can/slcan.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index d0435c7631ff..9c938f9892b2 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -618,10 +618,9 @@ err_free_chan: sl->tty = NULL; tty->disc_data = NULL; clear_bit(SLF_INUSE, &sl->flags); - slc_free_netdev(sl->dev); /* do not call free_netdev before rtnl_unlock */ rtnl_unlock(); - free_netdev(sl->dev); + slc_free_netdev(sl->dev); return err; err_exit: From 3f491c622996cbd5a0d0768c383843cc7f7538d0 Mon Sep 17 00:00:00 2001 From: yangerkun Date: Wed, 26 Feb 2020 11:54:35 +0800 Subject: [PATCH 234/387] slip: not call free_netdev before rtnl_unlock in slip_open commit f596c87005f7b1baeb7d62d9a9e25d68c3dfae10 upstream. As the description before netdev_run_todo, we cannot call free_netdev before rtnl_unlock, fix it by reorder the code. Signed-off-by: yangerkun Reviewed-by: Oliver Hartkopp Signed-off-by: David S. Miller [bwh: Backported to <4.11: free_netdev() is called through sl_free_netdev()] Signed-off-by: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- drivers/net/slip/slip.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c index cc841126147e..f870396e05e1 100644 --- a/drivers/net/slip/slip.c +++ b/drivers/net/slip/slip.c @@ -867,7 +867,10 @@ err_free_chan: sl->tty = NULL; tty->disc_data = NULL; clear_bit(SLF_INUSE, &sl->flags); + /* do not call free_netdev before rtnl_unlock */ + rtnl_unlock(); sl_free_netdev(sl->dev); + return err; err_exit: rtnl_unlock(); From ffa5baf3150a3e4afcf5630a1715c39b1af2c619 Mon Sep 17 00:00:00 2001 From: Can Guo Date: Thu, 5 Dec 2019 02:14:33 +0000 Subject: [PATCH 235/387] scsi: ufs: Release clock if DMA map fails commit 17c7d35f141ef6158076adf3338f115f64fcf760 upstream. In queuecommand path, if DMA map fails, it bails out with clock held. In this case, release the clock to keep its usage paired. [mkp: applied by hand] Link: https://lore.kernel.org/r/0101016ed3d66395-1b7e7fce-b74d-42ca-a88a-4db78b795d3b-000000@us-west-2.amazonses.com Reviewed-by: Bean Huo Signed-off-by: Can Guo Signed-off-by: Martin K. Petersen [EB: resolved cherry-pick conflict caused by newer kernels not having the clear_bit_unlock() line] Signed-off-by: Eric Biggers Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/ufs/ufshcd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 50d15748084a..af4b0a2021d6 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -1512,6 +1512,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) err = ufshcd_map_sg(hba, lrbp); if (err) { + ufshcd_release(hba); lrbp->cmd = NULL; clear_bit_unlock(tag, &hba->lrb_in_use); goto out; From b925f159f3f08a5040cf65d182da941bb26c56da Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 27 May 2020 21:48:30 +0300 Subject: [PATCH 236/387] airo: Fix read overflows sending packets commit 11e7a91994c29da96d847f676be023da6a2c1359 upstream. The problem is that we always copy a minimum of ETH_ZLEN (60) bytes from skb->data even when skb->len is less than ETH_ZLEN so it leads to a read overflow. The fix is to pad skb->data to at least ETH_ZLEN bytes. Cc: Reported-by: Hu Jiahui Signed-off-by: Dan Carpenter Reviewed-by: Eric Dumazet Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200527184830.GA1164846@mwanda Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/cisco/airo.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/net/wireless/cisco/airo.c b/drivers/net/wireless/cisco/airo.c index a8d470010f5e..ea609dc7f081 100644 --- a/drivers/net/wireless/cisco/airo.c +++ b/drivers/net/wireless/cisco/airo.c @@ -1928,6 +1928,10 @@ static netdev_tx_t mpi_start_xmit(struct sk_buff *skb, airo_print_err(dev->name, "%s: skb == NULL!",__func__); return NETDEV_TX_OK; } + if (skb_padto(skb, ETH_ZLEN)) { + dev->stats.tx_dropped++; + return NETDEV_TX_OK; + } npacks = skb_queue_len (&ai->txq); if (npacks >= MAXTXQ - 1) { @@ -2130,6 +2134,10 @@ static netdev_tx_t airo_start_xmit(struct sk_buff *skb, airo_print_err(dev->name, "%s: skb == NULL!", __func__); return NETDEV_TX_OK; } + if (skb_padto(skb, ETH_ZLEN)) { + dev->stats.tx_dropped++; + return NETDEV_TX_OK; + } /* Find a vacant FID */ for( i = 0; i < MAX_FIDS / 2 && (fids[i] & 0xffff0000); i++ ); @@ -2204,6 +2212,10 @@ static netdev_tx_t airo_start_xmit11(struct sk_buff *skb, airo_print_err(dev->name, "%s: skb == NULL!", __func__); return NETDEV_TX_OK; } + if (skb_padto(skb, ETH_ZLEN)) { + dev->stats.tx_dropped++; + return NETDEV_TX_OK; + } /* Find a vacant FID */ for( i = MAX_FIDS / 2; i < MAX_FIDS && (fids[i] & 0xffff0000); i++ ); From d2d51114811a6d5ba397fd9e543937161cd84bda Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Sat, 30 May 2020 11:34:33 +0800 Subject: [PATCH 237/387] devinet: fix memleak in inetdev_init() [ Upstream commit 1b49cd71b52403822731dc9f283185d1da355f97 ] When devinet_sysctl_register() failed, the memory allocated in neigh_parms_alloc() should be freed. Fixes: 20e61da7ffcf ("ipv4: fail early when creating netdev named all or default") Signed-off-by: Yang Yingliang Acked-by: Cong Wang Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/ipv4/devinet.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index af3363f4543f..6f3c52943186 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -262,6 +262,7 @@ static struct in_device *inetdev_init(struct net_device *dev) err = devinet_sysctl_register(in_dev); if (err) { in_dev->dead = 1; + neigh_parms_release(&arp_tbl, in_dev->arp_parms); in_dev_put(in_dev); in_dev = NULL; goto out; From 78320d3098edc4c8ef3fcbef52a4602aeeca37ed Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 29 May 2020 11:20:53 -0700 Subject: [PATCH 238/387] l2tp: do not use inet_hash()/inet_unhash() [ Upstream commit 02c71b144c811bcdd865e0a1226d0407d11357e8 ] syzbot recently found a way to crash the kernel [1] Issue here is that inet_hash() & inet_unhash() are currently only meant to be used by TCP & DCCP, since only these protocols provide the needed hashinfo pointer. L2TP uses a single list (instead of a hash table) This old bug became an issue after commit 610236587600 ("bpf: Add new cgroup attach type to enable sock modifications") since after this commit, sk_common_release() can be called while the L2TP socket is still considered 'hashed'. general protection fault, probably for non-canonical address 0xdffffc0000000001: 0000 [#1] PREEMPT SMP KASAN KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f] CPU: 0 PID: 7063 Comm: syz-executor654 Not tainted 5.7.0-rc6-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 RIP: 0010:inet_unhash+0x11f/0x770 net/ipv4/inet_hashtables.c:600 Code: 03 0f b6 04 02 84 c0 74 08 3c 03 0f 8e dd 04 00 00 48 8d 7d 08 44 8b 73 08 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 55 05 00 00 48 8d 7d 14 4c 8b 6d 08 48 b8 00 00 RSP: 0018:ffffc90001777d30 EFLAGS: 00010202 RAX: dffffc0000000000 RBX: ffff88809a6df940 RCX: ffffffff8697c242 RDX: 0000000000000001 RSI: ffffffff8697c251 RDI: 0000000000000008 RBP: 0000000000000000 R08: ffff88809f3ae1c0 R09: fffffbfff1514cc1 R10: ffffffff8a8a6607 R11: fffffbfff1514cc0 R12: ffff88809a6df9b0 R13: 0000000000000007 R14: 0000000000000000 R15: ffffffff873a4d00 FS: 0000000001d2b880(0000) GS:ffff8880ae600000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000000006cd090 CR3: 000000009403a000 CR4: 00000000001406f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: sk_common_release+0xba/0x370 net/core/sock.c:3210 inet_create net/ipv4/af_inet.c:390 [inline] inet_create+0x966/0xe00 net/ipv4/af_inet.c:248 __sock_create+0x3cb/0x730 net/socket.c:1428 sock_create net/socket.c:1479 [inline] __sys_socket+0xef/0x200 net/socket.c:1521 __do_sys_socket net/socket.c:1530 [inline] __se_sys_socket net/socket.c:1528 [inline] __x64_sys_socket+0x6f/0xb0 net/socket.c:1528 do_syscall_64+0xf6/0x7d0 arch/x86/entry/common.c:295 entry_SYSCALL_64_after_hwframe+0x49/0xb3 RIP: 0033:0x441e29 Code: e8 fc b3 02 00 48 83 c4 18 c3 0f 1f 80 00 00 00 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 eb 08 fc ff c3 66 2e 0f 1f 84 00 00 00 00 RSP: 002b:00007ffdce184148 EFLAGS: 00000246 ORIG_RAX: 0000000000000029 RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 0000000000441e29 RDX: 0000000000000073 RSI: 0000000000000002 RDI: 0000000000000002 RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 0000000000402c30 R14: 0000000000000000 R15: 0000000000000000 Modules linked in: ---[ end trace 23b6578228ce553e ]--- RIP: 0010:inet_unhash+0x11f/0x770 net/ipv4/inet_hashtables.c:600 Code: 03 0f b6 04 02 84 c0 74 08 3c 03 0f 8e dd 04 00 00 48 8d 7d 08 44 8b 73 08 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 55 05 00 00 48 8d 7d 14 4c 8b 6d 08 48 b8 00 00 RSP: 0018:ffffc90001777d30 EFLAGS: 00010202 RAX: dffffc0000000000 RBX: ffff88809a6df940 RCX: ffffffff8697c242 RDX: 0000000000000001 RSI: ffffffff8697c251 RDI: 0000000000000008 RBP: 0000000000000000 R08: ffff88809f3ae1c0 R09: fffffbfff1514cc1 R10: ffffffff8a8a6607 R11: fffffbfff1514cc0 R12: ffff88809a6df9b0 R13: 0000000000000007 R14: 0000000000000000 R15: ffffffff873a4d00 FS: 0000000001d2b880(0000) GS:ffff8880ae600000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000000006cd090 CR3: 000000009403a000 CR4: 00000000001406f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Fixes: 0d76751fad77 ("l2tp: Add L2TPv3 IP encapsulation (no UDP) support") Signed-off-by: Eric Dumazet Cc: James Chapman Cc: Andrii Nakryiko Reported-by: syzbot+3610d489778b57cc8031@syzkaller.appspotmail.com Signed-off-by: Greg Kroah-Hartman --- net/l2tp/l2tp_ip.c | 29 ++++++++++++++++++++++------- net/l2tp/l2tp_ip6.c | 30 ++++++++++++++++++++++-------- 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 4a88c4eb2301..3817c3554641 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -208,15 +207,31 @@ discard: return 0; } +static int l2tp_ip_hash(struct sock *sk) +{ + if (sk_unhashed(sk)) { + write_lock_bh(&l2tp_ip_lock); + sk_add_node(sk, &l2tp_ip_table); + write_unlock_bh(&l2tp_ip_lock); + } + return 0; +} + +static void l2tp_ip_unhash(struct sock *sk) +{ + if (sk_unhashed(sk)) + return; + write_lock_bh(&l2tp_ip_lock); + sk_del_node_init(sk); + write_unlock_bh(&l2tp_ip_lock); +} + static int l2tp_ip_open(struct sock *sk) { /* Prevent autobind. We don't have ports. */ inet_sk(sk)->inet_num = IPPROTO_L2TP; - write_lock_bh(&l2tp_ip_lock); - sk_add_node(sk, &l2tp_ip_table); - write_unlock_bh(&l2tp_ip_lock); - + l2tp_ip_hash(sk); return 0; } @@ -598,8 +613,8 @@ static struct proto l2tp_ip_prot = { .sendmsg = l2tp_ip_sendmsg, .recvmsg = l2tp_ip_recvmsg, .backlog_rcv = l2tp_ip_backlog_recv, - .hash = inet_hash, - .unhash = inet_unhash, + .hash = l2tp_ip_hash, + .unhash = l2tp_ip_unhash, .obj_size = sizeof(struct l2tp_ip_sock), #ifdef CONFIG_COMPAT .compat_setsockopt = compat_ip_setsockopt, diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c index 28274f397c55..76ef758db112 100644 --- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c @@ -24,8 +24,6 @@ #include #include #include -#include -#include #include #include #include @@ -221,15 +219,31 @@ discard: return 0; } +static int l2tp_ip6_hash(struct sock *sk) +{ + if (sk_unhashed(sk)) { + write_lock_bh(&l2tp_ip6_lock); + sk_add_node(sk, &l2tp_ip6_table); + write_unlock_bh(&l2tp_ip6_lock); + } + return 0; +} + +static void l2tp_ip6_unhash(struct sock *sk) +{ + if (sk_unhashed(sk)) + return; + write_lock_bh(&l2tp_ip6_lock); + sk_del_node_init(sk); + write_unlock_bh(&l2tp_ip6_lock); +} + static int l2tp_ip6_open(struct sock *sk) { /* Prevent autobind. We don't have ports. */ inet_sk(sk)->inet_num = IPPROTO_L2TP; - write_lock_bh(&l2tp_ip6_lock); - sk_add_node(sk, &l2tp_ip6_table); - write_unlock_bh(&l2tp_ip6_lock); - + l2tp_ip6_hash(sk); return 0; } @@ -732,8 +746,8 @@ static struct proto l2tp_ip6_prot = { .sendmsg = l2tp_ip6_sendmsg, .recvmsg = l2tp_ip6_recvmsg, .backlog_rcv = l2tp_ip6_backlog_recv, - .hash = inet6_hash, - .unhash = inet_unhash, + .hash = l2tp_ip6_hash, + .unhash = l2tp_ip6_unhash, .obj_size = sizeof(struct l2tp_ip6_sock), #ifdef CONFIG_COMPAT .compat_setsockopt = compat_ipv6_setsockopt, From 1331f667aa08246f06f43a9fbe0eee4a6763583e Mon Sep 17 00:00:00 2001 From: Daniele Palmas Date: Mon, 25 May 2020 23:25:37 +0200 Subject: [PATCH 239/387] net: usb: qmi_wwan: add Telit LE910C1-EUX composition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 591612aa578cd7148b7b9d74869ef40118978389 ] Add support for Telit LE910C1-EUX composition 0x1031: tty, tty, tty, rmnet Signed-off-by: Daniele Palmas Acked-by: Bjørn Mork Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/qmi_wwan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 5755eec00d7f..9a873616dd27 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -921,6 +921,7 @@ static const struct usb_device_id products[] = { {QMI_FIXED_INTF(0x1bbb, 0x0203, 2)}, /* Alcatel L800MA */ {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ + {QMI_QUIRK_SET_DTR(0x1bc7, 0x1031, 3)}, /* Telit LE910C1-EUX */ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)}, /* Telit LE922A */ {QMI_FIXED_INTF(0x1bc7, 0x1100, 3)}, /* Telit ME910 */ {QMI_FIXED_INTF(0x1bc7, 0x1101, 3)}, /* Telit ME910 dual modem */ From 990c16edd260d4f4ddbf55c2ef9158fdb118d360 Mon Sep 17 00:00:00 2001 From: Chuhong Yuan Date: Thu, 28 May 2020 18:20:37 +0800 Subject: [PATCH 240/387] NFC: st21nfca: add missed kfree_skb() in an error path [ Upstream commit 3decabdc714ca56c944f4669b4cdec5c2c1cea23 ] st21nfca_tm_send_atr_res() misses to call kfree_skb() in an error path. Add the missed function call to fix it. Fixes: 1892bf844ea0 ("NFC: st21nfca: Adding P2P support to st21nfca in Initiator & Target mode") Signed-off-by: Chuhong Yuan Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/nfc/st21nfca/dep.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/nfc/st21nfca/dep.c b/drivers/nfc/st21nfca/dep.c index 798a32bbac5d..e023a679bdea 100644 --- a/drivers/nfc/st21nfca/dep.c +++ b/drivers/nfc/st21nfca/dep.c @@ -184,8 +184,10 @@ static int st21nfca_tm_send_atr_res(struct nfc_hci_dev *hdev, memcpy(atr_res->gbi, atr_req->gbi, gb_len); r = nfc_set_remote_general_bytes(hdev->ndev, atr_res->gbi, gb_len); - if (r < 0) + if (r < 0) { + kfree_skb(skb); return r; + } } info->dep_info.curr_nfc_dep_pni = 0; From efbdae031219fc5df458de2ff422508619b98f85 Mon Sep 17 00:00:00 2001 From: Stefano Garzarella Date: Wed, 27 May 2020 09:56:55 +0200 Subject: [PATCH 241/387] vsock: fix timeout in vsock_accept() [ Upstream commit 7e0afbdfd13d1e708fe96e31c46c4897101a6a43 ] The accept(2) is an "input" socket interface, so we should use SO_RCVTIMEO instead of SO_SNDTIMEO to set the timeout. So this patch replace sock_sndtimeo() with sock_rcvtimeo() to use the right timeout in the vsock_accept(). Fixes: d021c344051a ("VSOCK: Introduce VM Sockets") Signed-off-by: Stefano Garzarella Reviewed-by: Jorgen Hansen Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/vmw_vsock/af_vsock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 18f377306884..d6473b8d9a81 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1296,7 +1296,7 @@ static int vsock_accept(struct socket *sock, struct socket *newsock, int flags) /* Wait for children sockets to appear; these are the new sockets * created upon connection establishment. */ - timeout = sock_sndtimeo(listener, flags & O_NONBLOCK); + timeout = sock_rcvtimeo(listener, flags & O_NONBLOCK); prepare_to_wait(sk_sleep(listener), &wait, TASK_INTERRUPTIBLE); while ((connected = vsock_dequeue_accept(listener)) == NULL && From eeced742e76d3ef8b968e7a6e4655f7fef52053d Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 29 May 2020 11:32:25 -0700 Subject: [PATCH 242/387] l2tp: add sk_family checks to l2tp_validate_socket [ Upstream commit d9a81a225277686eb629938986d97629ea102633 ] syzbot was able to trigger a crash after using an ISDN socket and fool l2tp. Fix this by making sure the UDP socket is of the proper family. BUG: KASAN: slab-out-of-bounds in setup_udp_tunnel_sock+0x465/0x540 net/ipv4/udp_tunnel.c:78 Write of size 1 at addr ffff88808ed0c590 by task syz-executor.5/3018 CPU: 0 PID: 3018 Comm: syz-executor.5 Not tainted 5.7.0-rc6-syzkaller #0 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+0x188/0x20d lib/dump_stack.c:118 print_address_description.constprop.0.cold+0xd3/0x413 mm/kasan/report.c:382 __kasan_report.cold+0x20/0x38 mm/kasan/report.c:511 kasan_report+0x33/0x50 mm/kasan/common.c:625 setup_udp_tunnel_sock+0x465/0x540 net/ipv4/udp_tunnel.c:78 l2tp_tunnel_register+0xb15/0xdd0 net/l2tp/l2tp_core.c:1523 l2tp_nl_cmd_tunnel_create+0x4b2/0xa60 net/l2tp/l2tp_netlink.c:249 genl_family_rcv_msg_doit net/netlink/genetlink.c:673 [inline] genl_family_rcv_msg net/netlink/genetlink.c:718 [inline] genl_rcv_msg+0x627/0xdf0 net/netlink/genetlink.c:735 netlink_rcv_skb+0x15a/0x410 net/netlink/af_netlink.c:2469 genl_rcv+0x24/0x40 net/netlink/genetlink.c:746 netlink_unicast_kernel net/netlink/af_netlink.c:1303 [inline] netlink_unicast+0x537/0x740 net/netlink/af_netlink.c:1329 netlink_sendmsg+0x882/0xe10 net/netlink/af_netlink.c:1918 sock_sendmsg_nosec net/socket.c:652 [inline] sock_sendmsg+0xcf/0x120 net/socket.c:672 ____sys_sendmsg+0x6e6/0x810 net/socket.c:2352 ___sys_sendmsg+0x100/0x170 net/socket.c:2406 __sys_sendmsg+0xe5/0x1b0 net/socket.c:2439 do_syscall_64+0xf6/0x7d0 arch/x86/entry/common.c:295 entry_SYSCALL_64_after_hwframe+0x49/0xb3 RIP: 0033:0x45ca29 Code: 0d b7 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 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 db b6 fb ff c3 66 2e 0f 1f 84 00 00 00 00 RSP: 002b:00007effe76edc78 EFLAGS: 00000246 ORIG_RAX: 000000000000002e RAX: ffffffffffffffda RBX: 00000000004fe1c0 RCX: 000000000045ca29 RDX: 0000000000000000 RSI: 0000000020000240 RDI: 0000000000000005 RBP: 000000000078bf00 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 00000000ffffffff R13: 000000000000094e R14: 00000000004d5d00 R15: 00007effe76ee6d4 Allocated by task 3018: save_stack+0x1b/0x40 mm/kasan/common.c:49 set_track mm/kasan/common.c:57 [inline] __kasan_kmalloc mm/kasan/common.c:495 [inline] __kasan_kmalloc.constprop.0+0xbf/0xd0 mm/kasan/common.c:468 __do_kmalloc mm/slab.c:3656 [inline] __kmalloc+0x161/0x7a0 mm/slab.c:3665 kmalloc include/linux/slab.h:560 [inline] sk_prot_alloc+0x223/0x2f0 net/core/sock.c:1612 sk_alloc+0x36/0x1100 net/core/sock.c:1666 data_sock_create drivers/isdn/mISDN/socket.c:600 [inline] mISDN_sock_create+0x272/0x400 drivers/isdn/mISDN/socket.c:796 __sock_create+0x3cb/0x730 net/socket.c:1428 sock_create net/socket.c:1479 [inline] __sys_socket+0xef/0x200 net/socket.c:1521 __do_sys_socket net/socket.c:1530 [inline] __se_sys_socket net/socket.c:1528 [inline] __x64_sys_socket+0x6f/0xb0 net/socket.c:1528 do_syscall_64+0xf6/0x7d0 arch/x86/entry/common.c:295 entry_SYSCALL_64_after_hwframe+0x49/0xb3 Freed by task 2484: save_stack+0x1b/0x40 mm/kasan/common.c:49 set_track mm/kasan/common.c:57 [inline] kasan_set_free_info mm/kasan/common.c:317 [inline] __kasan_slab_free+0xf7/0x140 mm/kasan/common.c:456 __cache_free mm/slab.c:3426 [inline] kfree+0x109/0x2b0 mm/slab.c:3757 kvfree+0x42/0x50 mm/util.c:603 __free_fdtable+0x2d/0x70 fs/file.c:31 put_files_struct fs/file.c:420 [inline] put_files_struct+0x248/0x2e0 fs/file.c:413 exit_files+0x7e/0xa0 fs/file.c:445 do_exit+0xb04/0x2dd0 kernel/exit.c:791 do_group_exit+0x125/0x340 kernel/exit.c:894 get_signal+0x47b/0x24e0 kernel/signal.c:2739 do_signal+0x81/0x2240 arch/x86/kernel/signal.c:784 exit_to_usermode_loop+0x26c/0x360 arch/x86/entry/common.c:161 prepare_exit_to_usermode arch/x86/entry/common.c:196 [inline] syscall_return_slowpath arch/x86/entry/common.c:279 [inline] do_syscall_64+0x6b1/0x7d0 arch/x86/entry/common.c:305 entry_SYSCALL_64_after_hwframe+0x49/0xb3 The buggy address belongs to the object at ffff88808ed0c000 which belongs to the cache kmalloc-2k of size 2048 The buggy address is located 1424 bytes inside of 2048-byte region [ffff88808ed0c000, ffff88808ed0c800) The buggy address belongs to the page: page:ffffea00023b4300 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 flags: 0xfffe0000000200(slab) raw: 00fffe0000000200 ffffea0002838208 ffffea00015ba288 ffff8880aa000e00 raw: 0000000000000000 ffff88808ed0c000 0000000100000001 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff88808ed0c480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffff88808ed0c500: 00 00 00 fc fc fc fc fc fc fc fc fc fc fc fc fc >ffff88808ed0c580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ^ ffff88808ed0c600: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ffff88808ed0c680: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc Fixes: 6b9f34239b00 ("l2tp: fix races in tunnel creation") Fixes: fd558d186df2 ("l2tp: Split pppol2tp patch into separate l2tp and ppp parts") Signed-off-by: Eric Dumazet Cc: James Chapman Cc: Guillaume Nault Reported-by: syzbot Acked-by: Guillaume Nault Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/l2tp/l2tp_core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 36c7f616294a..fdc1de1cb4fa 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -1568,6 +1568,8 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32 tunnel_id, fd); goto err; } + if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6) + goto err; switch (encap) { case L2TP_ENCAPTYPE_UDP: if (sk->sk_protocol != IPPROTO_UDP) { From 3a0808691d40b27b1d1e6f09a8a0a0c9fc17e4bb Mon Sep 17 00:00:00 2001 From: Matt Jolly Date: Thu, 21 May 2020 10:43:58 +1000 Subject: [PATCH 243/387] USB: serial: qcserial: add DW5816e QDL support commit 3429444abdd9dbd5faebd9bee552ec6162b17ad6 upstream. Add support for Dell Wireless 5816e Download Mode (AKA boot & hold mode / QDL download mode) to drivers/usb/serial/qcserial.c This is required to update device firmware. Signed-off-by: Matt Jolly Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/qcserial.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 06916ddc3159..c59e6d4a8a61 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -177,6 +177,7 @@ static const struct usb_device_id id_table[] = { {DEVICE_SWI(0x413c, 0x81b3)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */ {DEVICE_SWI(0x413c, 0x81b5)}, /* Dell Wireless 5811e QDL */ {DEVICE_SWI(0x413c, 0x81b6)}, /* Dell Wireless 5811e QDL */ + {DEVICE_SWI(0x413c, 0x81cb)}, /* Dell Wireless 5816e QDL */ {DEVICE_SWI(0x413c, 0x81cc)}, /* Dell Wireless 5816e */ {DEVICE_SWI(0x413c, 0x81cf)}, /* Dell Wireless 5819 */ {DEVICE_SWI(0x413c, 0x81d0)}, /* Dell Wireless 5819 */ From 337741cd29da175a3d3f0194eedb183fa30330f0 Mon Sep 17 00:00:00 2001 From: Bin Liu Date: Wed, 13 May 2020 16:36:46 -0500 Subject: [PATCH 244/387] USB: serial: usb_wwan: do not resubmit rx urb on fatal errors commit 986c1748c84d7727defeaeca74a73b37f7d5cce1 upstream. usb_wwan_indat_callback() shouldn't resubmit rx urb if the previous urb status is a fatal error. Or the usb controller would keep processing the new urbs then run into interrupt storm, and has no chance to recover. Fixes: 6c1ee66a0b2b ("USB-Serial: Fix error handling of usb_wwan") Cc: stable@vger.kernel.org Signed-off-by: Bin Liu Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb_wwan.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index 93c696e2131f..0fbb34fcbddf 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c @@ -305,6 +305,10 @@ static void usb_wwan_indat_callback(struct urb *urb) if (status) { dev_dbg(dev, "%s: nonzero status: %d on endpoint %02x.\n", __func__, status, endpoint); + + /* don't resubmit on fatal errors */ + if (status == -ESHUTDOWN || status == -ENOENT) + return; } else { if (urb->actual_length) { tty_insert_flip_string(&port->port, data, From a75aba90967252f2b23515021b4f11d5bd1706e8 Mon Sep 17 00:00:00 2001 From: Daniele Palmas Date: Mon, 25 May 2020 23:11:06 +0200 Subject: [PATCH 245/387] USB: serial: option: add Telit LE910C1-EUX compositions commit 399ad9477c523f721f8e51d4f824bdf7267f120c upstream. Add Telit LE910C1-EUX compositions: 0x1031: tty, tty, tty, rmnet 0x1033: tty, tty, tty, ecm Signed-off-by: Daniele Palmas Link: https://lore.kernel.org/r/20200525211106.27338-1-dnlplm@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 737b6652a0b5..326e7109b8f8 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1146,6 +1146,10 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UE910_V2) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1031, 0xff), /* Telit LE910C1-EUX */ + .driver_info = NCTRL(0) | RSVD(3) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1033, 0xff), /* Telit LE910C1-EUX (ECM) */ + .driver_info = NCTRL(0) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG0), .driver_info = RSVD(0) | RSVD(1) | NCTRL(2) | RSVD(3) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG1), From 74d904c16dfe2583fc578cc3b0ada8ce395a3714 Mon Sep 17 00:00:00 2001 From: Dinghao Liu Date: Sun, 24 May 2020 21:50:49 -0500 Subject: [PATCH 246/387] usb: musb: Fix runtime PM imbalance on error commit e4befc121df03dc8ed2ac1031c98f9538e244bae upstream. When copy_from_user() returns an error code, there is a runtime PM usage counter imbalance. Fix this by moving copy_from_user() to the beginning of this function. Fixes: 7b6c1b4c0e1e ("usb: musb: fix runtime PM in debugfs") Signed-off-by: Dinghao Liu Cc: stable@vger.kernel.org Signed-off-by: Bin Liu Link: https://lore.kernel.org/r/20200525025049.3400-7-b-liu@ti.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_debugfs.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/usb/musb/musb_debugfs.c b/drivers/usb/musb/musb_debugfs.c index 534a3f6fa89c..474bb13b7dbb 100644 --- a/drivers/usb/musb/musb_debugfs.c +++ b/drivers/usb/musb/musb_debugfs.c @@ -200,6 +200,11 @@ static ssize_t musb_test_mode_write(struct file *file, u8 test; char buf[18]; + memset(buf, 0x00, sizeof(buf)); + + if (copy_from_user(buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) + return -EFAULT; + pm_runtime_get_sync(musb->controller); test = musb_readb(musb->mregs, MUSB_TESTMODE); if (test) { @@ -208,11 +213,6 @@ static ssize_t musb_test_mode_write(struct file *file, goto ret; } - memset(buf, 0x00, sizeof(buf)); - - if (copy_from_user(buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) - return -EFAULT; - if (strstarts(buf, "force host")) test = MUSB_TEST_FORCE_HOST; From adf823fa2a53db5d119d90817778f263a3a47608 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 25 May 2020 16:27:40 -0700 Subject: [PATCH 247/387] vt: keyboard: avoid signed integer overflow in k_ascii commit b86dab054059b970111b5516ae548efaae5b3aae upstream. When k_ascii is invoked several times in a row there is a potential for signed integer overflow: UBSAN: Undefined behaviour in drivers/tty/vt/keyboard.c:888:19 signed integer overflow: 10 * 1111111111 cannot be represented in type 'int' CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.6.11 #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0xce/0x128 lib/dump_stack.c:118 ubsan_epilogue+0xe/0x30 lib/ubsan.c:154 handle_overflow+0xdc/0xf0 lib/ubsan.c:184 __ubsan_handle_mul_overflow+0x2a/0x40 lib/ubsan.c:205 k_ascii+0xbf/0xd0 drivers/tty/vt/keyboard.c:888 kbd_keycode drivers/tty/vt/keyboard.c:1477 [inline] kbd_event+0x888/0x3be0 drivers/tty/vt/keyboard.c:1495 While it can be worked around by using check_mul_overflow()/ check_add_overflow(), it is better to introduce a separate flag to signal that number pad is being used to compose a symbol, and change type of the accumulator from signed to unsigned, thus avoiding undefined behavior when it overflows. Reported-by: Kyungtae Kim Signed-off-by: Dmitry Torokhov Cc: stable Link: https://lore.kernel.org/r/20200525232740.GA262061@dtor-ws Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/keyboard.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index b4e7a7317713..d9eba7938917 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c @@ -125,7 +125,11 @@ static DEFINE_SPINLOCK(func_buf_lock); /* guard 'func_buf' and friends */ static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */ static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */ static bool dead_key_next; -static int npadch = -1; /* -1 or number assembled on pad */ + +/* Handles a number being assembled on the number pad */ +static bool npadch_active; +static unsigned int npadch_value; + static unsigned int diacr; static char rep; /* flag telling character repeat */ @@ -815,12 +819,12 @@ static void k_shift(struct vc_data *vc, unsigned char value, char up_flag) shift_state &= ~(1 << value); /* kludge */ - if (up_flag && shift_state != old_state && npadch != -1) { + if (up_flag && shift_state != old_state && npadch_active) { if (kbd->kbdmode == VC_UNICODE) - to_utf8(vc, npadch); + to_utf8(vc, npadch_value); else - put_queue(vc, npadch & 0xff); - npadch = -1; + put_queue(vc, npadch_value & 0xff); + npadch_active = false; } } @@ -838,7 +842,7 @@ static void k_meta(struct vc_data *vc, unsigned char value, char up_flag) static void k_ascii(struct vc_data *vc, unsigned char value, char up_flag) { - int base; + unsigned int base; if (up_flag) return; @@ -852,10 +856,12 @@ static void k_ascii(struct vc_data *vc, unsigned char value, char up_flag) base = 16; } - if (npadch == -1) - npadch = value; - else - npadch = npadch * base + value; + if (!npadch_active) { + npadch_value = 0; + npadch_active = true; + } + + npadch_value = npadch_value * base + value; } static void k_lock(struct vc_data *vc, unsigned char value, char up_flag) From 2b37e4f0ef5c8cd1d3de19d364dfcbefcc5114b2 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 26 May 2020 16:56:32 +0200 Subject: [PATCH 248/387] tty: hvc_console, fix crashes on parallel open/close commit 24eb2377f977fe06d84fca558f891f95bc28a449 upstream. hvc_open sets tty->driver_data to NULL when open fails at some point. Typically, the failure happens in hp->ops->notifier_add(). If there is a racing process which tries to open such mangled tty, which was not closed yet, the process will crash in hvc_open as tty->driver_data is NULL. All this happens because close wants to know whether open failed or not. But ->open should not NULL this and other tty fields for ->close to be happy. ->open should call tty_port_set_initialized(true) and close should check by tty_port_initialized() instead. So do this properly in this driver. So this patch removes these from ->open: * tty_port_tty_set(&hp->port, NULL). This happens on last close. * tty->driver_data = NULL. Dtto. * tty_port_put(&hp->port). This happens in shutdown and until now, this must have been causing a reference underflow, if I am not missing something. Signed-off-by: Jiri Slaby Cc: stable Reported-and-tested-by: Raghavendra Link: https://lore.kernel.org/r/20200526145632.13879-1-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/hvc/hvc_console.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index f8964247c4c3..985f49a65906 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c @@ -358,15 +358,14 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) * tty fields and return the kref reference. */ if (rc) { - tty_port_tty_set(&hp->port, NULL); - tty->driver_data = NULL; - tty_port_put(&hp->port); printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc); - } else + } else { /* We are ready... raise DTR/RTS */ if (C_BAUD(tty)) if (hp->ops->dtr_rts) hp->ops->dtr_rts(hp, 1); + tty_port_set_initialized(&hp->port, true); + } /* Force wakeup of the polling thread */ hvc_kick(); @@ -376,22 +375,12 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) static void hvc_close(struct tty_struct *tty, struct file * filp) { - struct hvc_struct *hp; + struct hvc_struct *hp = tty->driver_data; unsigned long flags; if (tty_hung_up_p(filp)) return; - /* - * No driver_data means that this close was issued after a failed - * hvc_open by the tty layer's release_dev() function and we can just - * exit cleanly because the kref reference wasn't made. - */ - if (!tty->driver_data) - return; - - hp = tty->driver_data; - spin_lock_irqsave(&hp->port.lock, flags); if (--hp->port.count == 0) { @@ -399,6 +388,9 @@ static void hvc_close(struct tty_struct *tty, struct file * filp) /* We are done with the tty pointer now. */ tty_port_tty_set(&hp->port, NULL); + if (!tty_port_initialized(&hp->port)) + return; + if (C_HUPCL(tty)) if (hp->ops->dtr_rts) hp->ops->dtr_rts(hp, 0); @@ -415,6 +407,7 @@ static void hvc_close(struct tty_struct *tty, struct file * filp) * waking periodically to check chars_in_buffer(). */ tty_wait_until_sent(tty, HVC_CLOSE_WAIT); + tty_port_set_initialized(&hp->port, false); } else { if (hp->port.count < 0) printk(KERN_ERR "hvc_close %X: oops, count is %d\n", From ed9a878378533250b0290e32ff4361ce420690c1 Mon Sep 17 00:00:00 2001 From: Pascal Terjan Date: Sat, 23 May 2020 22:12:47 +0100 Subject: [PATCH 249/387] staging: rtl8712: Fix IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK commit 15ea976a1f12b5fd76b1bd6ff3eb5132fd28047f upstream. The value in shared headers was fixed 9 years ago in commit 8d661f1e462d ("ieee80211: correct IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK macro") and while looking at using shared headers for other duplicated constants I noticed this driver uses the old value. The macros are also defined twice in this file so I am deleting the second definition. Signed-off-by: Pascal Terjan Cc: stable Link: https://lore.kernel.org/r/20200523211247.23262-1-pterjan@google.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/wifi.h | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/staging/rtl8712/wifi.h b/drivers/staging/rtl8712/wifi.h index b8af9656e6da..f97275b90177 100644 --- a/drivers/staging/rtl8712/wifi.h +++ b/drivers/staging/rtl8712/wifi.h @@ -471,7 +471,7 @@ static inline unsigned char *get_hdr_bssid(unsigned char *pframe) /* block-ack parameters */ #define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002 #define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C -#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFA0 +#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFC0 #define IEEE80211_DELBA_PARAM_TID_MASK 0xF000 #define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800 @@ -565,13 +565,6 @@ struct ieee80211_ht_addt_info { #define IEEE80211_HT_IE_NON_GF_STA_PRSNT 0x0004 #define IEEE80211_HT_IE_NON_HT_STA_PRSNT 0x0010 -/* block-ack parameters */ -#define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002 -#define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C -#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFA0 -#define IEEE80211_DELBA_PARAM_TID_MASK 0xF000 -#define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800 - /* * A-PMDU buffer sizes * According to IEEE802.11n spec size varies from 8K to 64K (in powers of 2) From 10873fe64e9d7181c3576134341b6f4d24b32048 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Fri, 22 May 2020 12:33:41 +0100 Subject: [PATCH 250/387] nvmem: qfprom: remove incorrect write support commit 8d9eb0d6d59a5d7028c80a30831143d3e75515a7 upstream. qfprom has different address spaces for read and write. Reads are always done from corrected address space, where as writes are done on raw address space. Writing to corrected address space is invalid and ignored, so it does not make sense to have this support in the driver which only supports corrected address space regions at the moment. Fixes: 4ab11996b489 ("nvmem: qfprom: Add Qualcomm QFPROM support.") Signed-off-by: Srinivas Kandagatla Reviewed-by: Douglas Anderson Cc: stable Link: https://lore.kernel.org/r/20200522113341.7728-1-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/nvmem/qfprom.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/nvmem/qfprom.c b/drivers/nvmem/qfprom.c index b5305f08b184..05b1c4f36b7b 100644 --- a/drivers/nvmem/qfprom.c +++ b/drivers/nvmem/qfprom.c @@ -30,19 +30,6 @@ static int qfprom_reg_read(void *context, return 0; } -static int qfprom_reg_write(void *context, - unsigned int reg, void *_val, size_t bytes) -{ - void __iomem *base = context; - u32 *val = _val; - int i = 0, words = bytes / 4; - - while (words--) - writel(*val++, base + reg + (i++ * 4)); - - return 0; -} - static int qfprom_remove(struct platform_device *pdev) { struct nvmem_device *nvmem = platform_get_drvdata(pdev); @@ -56,7 +43,6 @@ static struct nvmem_config econfig = { .stride = 4, .word_size = 1, .reg_read = qfprom_reg_read, - .reg_write = qfprom_reg_write, }; static int qfprom_probe(struct platform_device *pdev) From 5f8f40583aad4aa3c0fc8a9adaa9f1c988fa8e9e Mon Sep 17 00:00:00 2001 From: Mark Gross Date: Mon, 27 Apr 2020 21:17:15 +0200 Subject: [PATCH 251/387] x86/cpu: Add a steppings field to struct x86_cpu_id commit e9d7144597b10ff13ff2264c059f7d4a7fbc89ac upstream Intel uses the same family/model for several CPUs. Sometimes the stepping must be checked to tell them apart. On x86 there can be at most 16 steppings. Add a steppings bitmask to x86_cpu_id and a X86_MATCH_VENDOR_FAMILY_MODEL_STEPPING_FEATURE macro and support for matching against family/model/stepping. [ bp: Massage. tglx: Lightweight variant for backporting ] Signed-off-by: Mark Gross Signed-off-by: Borislav Petkov Signed-off-by: Thomas Gleixner Reviewed-by: Tony Luck Reviewed-by: Josh Poimboeuf Signed-off-by: Greg Kroah-Hartman --- arch/x86/include/asm/cpu_device_id.h | 27 +++++++++++++++++++++++++++ arch/x86/kernel/cpu/match.c | 7 ++++++- include/linux/mod_devicetable.h | 6 ++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/cpu_device_id.h b/arch/x86/include/asm/cpu_device_id.h index ff501e511d91..b9473858c6b6 100644 --- a/arch/x86/include/asm/cpu_device_id.h +++ b/arch/x86/include/asm/cpu_device_id.h @@ -8,6 +8,33 @@ #include +#define X86_STEPPINGS(mins, maxs) GENMASK(maxs, mins) + +/** + * X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE - Base macro for CPU matching + * @_vendor: The vendor name, e.g. INTEL, AMD, HYGON, ..., ANY + * The name is expanded to X86_VENDOR_@_vendor + * @_family: The family number or X86_FAMILY_ANY + * @_model: The model number, model constant or X86_MODEL_ANY + * @_steppings: Bitmask for steppings, stepping constant or X86_STEPPING_ANY + * @_feature: A X86_FEATURE bit or X86_FEATURE_ANY + * @_data: Driver specific data or NULL. The internal storage + * format is unsigned long. The supplied value, pointer + * etc. is casted to unsigned long internally. + * + * Backport version to keep the SRBDS pile consistant. No shorter variants + * required for this. + */ +#define X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE(_vendor, _family, _model, \ + _steppings, _feature, _data) { \ + .vendor = X86_VENDOR_##_vendor, \ + .family = _family, \ + .model = _model, \ + .steppings = _steppings, \ + .feature = _feature, \ + .driver_data = (unsigned long) _data \ +} + extern const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match); #endif diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c index e42117d5f4d7..f46ffb3b295f 100644 --- a/arch/x86/kernel/cpu/match.c +++ b/arch/x86/kernel/cpu/match.c @@ -33,13 +33,18 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match) const struct x86_cpu_id *m; struct cpuinfo_x86 *c = &boot_cpu_data; - for (m = match; m->vendor | m->family | m->model | m->feature; m++) { + for (m = match; + m->vendor | m->family | m->model | m->steppings | m->feature; + m++) { if (m->vendor != X86_VENDOR_ANY && c->x86_vendor != m->vendor) continue; if (m->family != X86_FAMILY_ANY && c->x86 != m->family) continue; if (m->model != X86_MODEL_ANY && c->x86_model != m->model) continue; + if (m->steppings != X86_STEPPING_ANY && + !(BIT(c->x86_stepping) & m->steppings)) + continue; if (m->feature != X86_FEATURE_ANY && !cpu_has(c, m->feature)) continue; return m; diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 1abfe37314a0..df841a72b804 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -572,6 +572,10 @@ struct mips_cdmm_device_id { /* * MODULE_DEVICE_TABLE expects this struct to be called x86cpu_device_id. * Although gcc seems to ignore this error, clang fails without this define. + * + * Note: The ordering of the struct is different from upstream because the + * static initializers in kernels < 5.7 still use C89 style while upstream + * has been converted to proper C99 initializers. */ #define x86cpu_device_id x86_cpu_id struct x86_cpu_id { @@ -580,6 +584,7 @@ struct x86_cpu_id { __u16 model; __u16 feature; /* bit index */ kernel_ulong_t driver_data; + __u16 steppings; }; #define X86_FEATURE_MATCH(x) \ @@ -588,6 +593,7 @@ struct x86_cpu_id { #define X86_VENDOR_ANY 0xffff #define X86_FAMILY_ANY 0 #define X86_MODEL_ANY 0 +#define X86_STEPPING_ANY 0 #define X86_FEATURE_ANY 0 /* Same as FPU, you can't test for that */ /* From 15cf7ca9f59ff911cd5582969377bbf8c2ecab8a Mon Sep 17 00:00:00 2001 From: Mark Gross Date: Mon, 27 Apr 2020 21:17:15 +0200 Subject: [PATCH 252/387] x86/cpu: Add 'table' argument to cpu_matches() commit 93920f61c2ad7edb01e63323832585796af75fc9 upstream To make cpu_matches() reusable for other matching tables, have it take a pointer to a x86_cpu_id table as an argument. [ bp: Flip arguments order. ] Signed-off-by: Mark Gross Signed-off-by: Borislav Petkov Signed-off-by: Thomas Gleixner Reviewed-by: Josh Poimboeuf Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/cpu/common.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index f490a4fab2f7..078ad5da2e1f 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -956,9 +956,9 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = { {} }; -static bool __init cpu_matches(unsigned long which) +static bool __init cpu_matches(const struct x86_cpu_id *table, unsigned long which) { - const struct x86_cpu_id *m = x86_match_cpu(cpu_vuln_whitelist); + const struct x86_cpu_id *m = x86_match_cpu(table); return m && !!(m->driver_data & which); } @@ -978,29 +978,32 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) u64 ia32_cap = x86_read_arch_cap_msr(); /* Set ITLB_MULTIHIT bug if cpu is not in the whitelist and not mitigated */ - if (!cpu_matches(NO_ITLB_MULTIHIT) && !(ia32_cap & ARCH_CAP_PSCHANGE_MC_NO)) + if (!cpu_matches(cpu_vuln_whitelist, NO_ITLB_MULTIHIT) && + !(ia32_cap & ARCH_CAP_PSCHANGE_MC_NO)) setup_force_cpu_bug(X86_BUG_ITLB_MULTIHIT); - if (cpu_matches(NO_SPECULATION)) + if (cpu_matches(cpu_vuln_whitelist, NO_SPECULATION)) return; setup_force_cpu_bug(X86_BUG_SPECTRE_V1); setup_force_cpu_bug(X86_BUG_SPECTRE_V2); - if (!cpu_matches(NO_SSB) && !(ia32_cap & ARCH_CAP_SSB_NO) && + if (!cpu_matches(cpu_vuln_whitelist, NO_SSB) && + !(ia32_cap & ARCH_CAP_SSB_NO) && !cpu_has(c, X86_FEATURE_AMD_SSB_NO)) setup_force_cpu_bug(X86_BUG_SPEC_STORE_BYPASS); if (ia32_cap & ARCH_CAP_IBRS_ALL) setup_force_cpu_cap(X86_FEATURE_IBRS_ENHANCED); - if (!cpu_matches(NO_MDS) && !(ia32_cap & ARCH_CAP_MDS_NO)) { + if (!cpu_matches(cpu_vuln_whitelist, NO_MDS) && + !(ia32_cap & ARCH_CAP_MDS_NO)) { setup_force_cpu_bug(X86_BUG_MDS); - if (cpu_matches(MSBDS_ONLY)) + if (cpu_matches(cpu_vuln_whitelist, MSBDS_ONLY)) setup_force_cpu_bug(X86_BUG_MSBDS_ONLY); } - if (!cpu_matches(NO_SWAPGS)) + if (!cpu_matches(cpu_vuln_whitelist, NO_SWAPGS)) setup_force_cpu_bug(X86_BUG_SWAPGS); /* @@ -1018,7 +1021,7 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) (ia32_cap & ARCH_CAP_TSX_CTRL_MSR))) setup_force_cpu_bug(X86_BUG_TAA); - if (cpu_matches(NO_MELTDOWN)) + if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN)) return; /* Rogue Data Cache Load? No! */ @@ -1027,7 +1030,7 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) setup_force_cpu_bug(X86_BUG_CPU_MELTDOWN); - if (cpu_matches(NO_L1TF)) + if (cpu_matches(cpu_vuln_whitelist, NO_L1TF)) return; setup_force_cpu_bug(X86_BUG_L1TF); From 2f93f8d6891c2bd3963e1c68ad3eabf4dd6a55af Mon Sep 17 00:00:00 2001 From: Mark Gross Date: Mon, 27 Apr 2020 21:17:15 +0200 Subject: [PATCH 253/387] x86/speculation: Add Special Register Buffer Data Sampling (SRBDS) mitigation commit 7e5b3c267d256822407a22fdce6afdf9cd13f9fb upstream SRBDS is an MDS-like speculative side channel that can leak bits from the random number generator (RNG) across cores and threads. New microcode serializes the processor access during the execution of RDRAND and RDSEED. This ensures that the shared buffer is overwritten before it is released for reuse. While it is present on all affected CPU models, the microcode mitigation is not needed on models that enumerate ARCH_CAPABILITIES[MDS_NO] in the cases where TSX is not supported or has been disabled with TSX_CTRL. The mitigation is activated by default on affected processors and it increases latency for RDRAND and RDSEED instructions. Among other effects this will reduce throughput from /dev/urandom. * Enable administrator to configure the mitigation off when desired using either mitigations=off or srbds=off. * Export vulnerability status via sysfs * Rename file-scoped macros to apply for non-whitelist table initializations. [ bp: Massage, - s/VULNBL_INTEL_STEPPING/VULNBL_INTEL_STEPPINGS/g, - do not read arch cap MSR a second time in tsx_fused_off() - just pass it in, - flip check in cpu_set_bug_bits() to save an indentation level, - reflow comments. jpoimboe: s/Mitigated/Mitigation/ in user-visible strings tglx: Dropped the fused off magic for now ] Signed-off-by: Mark Gross Signed-off-by: Borislav Petkov Signed-off-by: Thomas Gleixner Reviewed-by: Tony Luck Reviewed-by: Pawan Gupta Reviewed-by: Josh Poimboeuf Tested-by: Neelima Krishnan Signed-off-by: Greg Kroah-Hartman --- .../ABI/testing/sysfs-devices-system-cpu | 1 + Documentation/kernel-parameters.txt | 20 ++++ arch/x86/include/asm/cpufeatures.h | 30 ++--- arch/x86/include/asm/msr-index.h | 4 + arch/x86/kernel/cpu/bugs.c | 106 ++++++++++++++++++ arch/x86/kernel/cpu/common.c | 31 +++++ arch/x86/kernel/cpu/cpu.h | 1 + drivers/base/cpu.c | 8 ++ 8 files changed, 187 insertions(+), 14 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu index b41046b5713b..a5225df4a070 100644 --- a/Documentation/ABI/testing/sysfs-devices-system-cpu +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu @@ -358,6 +358,7 @@ What: /sys/devices/system/cpu/vulnerabilities /sys/devices/system/cpu/vulnerabilities/spec_store_bypass /sys/devices/system/cpu/vulnerabilities/l1tf /sys/devices/system/cpu/vulnerabilities/mds + /sys/devices/system/cpu/vulnerabilities/srbds /sys/devices/system/cpu/vulnerabilities/tsx_async_abort /sys/devices/system/cpu/vulnerabilities/itlb_multihit Date: January 2018 diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index e05d65d6fcb6..40602517ca52 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -4262,6 +4262,26 @@ bytes respectively. Such letter suffixes can also be entirely omitted. spia_pedr= spia_peddr= + srbds= [X86,INTEL] + Control the Special Register Buffer Data Sampling + (SRBDS) mitigation. + + Certain CPUs are vulnerable to an MDS-like + exploit which can leak bits from the random + number generator. + + By default, this issue is mitigated by + microcode. However, the microcode fix can cause + the RDRAND and RDSEED instructions to become + much slower. Among other effects, this will + result in reduced throughput from /dev/urandom. + + The microcode mitigation can be disabled with + the following option: + + off: Disable mitigation and remove + performance impact to RDRAND and RDSEED + ssbd= [ARM64,HW] Speculative Store Bypass Disable control diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h index fb457ba8ccc6..2cd5d12a842c 100644 --- a/arch/x86/include/asm/cpufeatures.h +++ b/arch/x86/include/asm/cpufeatures.h @@ -316,6 +316,7 @@ /* Intel-defined CPU features, CPUID level 0x00000007:0 (EDX), word 18 */ #define X86_FEATURE_AVX512_4VNNIW (18*32+ 2) /* AVX-512 Neural Network Instructions */ #define X86_FEATURE_AVX512_4FMAPS (18*32+ 3) /* AVX-512 Multiply Accumulation Single precision */ +#define X86_FEATURE_SRBDS_CTRL (18*32+ 9) /* "" SRBDS mitigation MSR available */ #define X86_FEATURE_TSX_FORCE_ABORT (18*32+13) /* "" TSX_FORCE_ABORT */ #define X86_FEATURE_MD_CLEAR (18*32+10) /* VERW clears CPU buffers */ #define X86_FEATURE_PCONFIG (18*32+18) /* Intel PCONFIG */ @@ -346,19 +347,20 @@ */ #define X86_BUG_ESPFIX X86_BUG(9) /* "" IRET to 16-bit SS corrupts ESP/RSP high bits */ #endif -#define X86_BUG_NULL_SEG X86_BUG(10) /* Nulling a selector preserves the base */ -#define X86_BUG_SWAPGS_FENCE X86_BUG(11) /* SWAPGS without input dep on GS */ -#define X86_BUG_MONITOR X86_BUG(12) /* IPI required to wake up remote CPU */ -#define X86_BUG_AMD_E400 X86_BUG(13) /* CPU is among the affected by Erratum 400 */ -#define X86_BUG_CPU_MELTDOWN X86_BUG(14) /* CPU is affected by meltdown attack and needs kernel page table isolation */ -#define X86_BUG_SPECTRE_V1 X86_BUG(15) /* CPU is affected by Spectre variant 1 attack with conditional branches */ -#define X86_BUG_SPECTRE_V2 X86_BUG(16) /* CPU is affected by Spectre variant 2 attack with indirect branches */ -#define X86_BUG_SPEC_STORE_BYPASS X86_BUG(17) /* CPU is affected by speculative store bypass attack */ -#define X86_BUG_L1TF X86_BUG(18) /* CPU is affected by L1 Terminal Fault */ -#define X86_BUG_MDS X86_BUG(19) /* CPU is affected by Microarchitectural data sampling */ -#define X86_BUG_MSBDS_ONLY X86_BUG(20) /* CPU is only affected by the MSDBS variant of BUG_MDS */ -#define X86_BUG_SWAPGS X86_BUG(21) /* CPU is affected by speculation through SWAPGS */ -#define X86_BUG_TAA X86_BUG(22) /* CPU is affected by TSX Async Abort(TAA) */ -#define X86_BUG_ITLB_MULTIHIT X86_BUG(23) /* CPU may incur MCE during certain page attribute changes */ +#define X86_BUG_NULL_SEG X86_BUG(10) /* Nulling a selector preserves the base */ +#define X86_BUG_SWAPGS_FENCE X86_BUG(11) /* SWAPGS without input dep on GS */ +#define X86_BUG_MONITOR X86_BUG(12) /* IPI required to wake up remote CPU */ +#define X86_BUG_AMD_E400 X86_BUG(13) /* CPU is among the affected by Erratum 400 */ +#define X86_BUG_CPU_MELTDOWN X86_BUG(14) /* CPU is affected by meltdown attack and needs kernel page table isolation */ +#define X86_BUG_SPECTRE_V1 X86_BUG(15) /* CPU is affected by Spectre variant 1 attack with conditional branches */ +#define X86_BUG_SPECTRE_V2 X86_BUG(16) /* CPU is affected by Spectre variant 2 attack with indirect branches */ +#define X86_BUG_SPEC_STORE_BYPASS X86_BUG(17) /* CPU is affected by speculative store bypass attack */ +#define X86_BUG_L1TF X86_BUG(18) /* CPU is affected by L1 Terminal Fault */ +#define X86_BUG_MDS X86_BUG(19) /* CPU is affected by Microarchitectural data sampling */ +#define X86_BUG_MSBDS_ONLY X86_BUG(20) /* CPU is only affected by the MSDBS variant of BUG_MDS */ +#define X86_BUG_SWAPGS X86_BUG(21) /* CPU is affected by speculation through SWAPGS */ +#define X86_BUG_TAA X86_BUG(22) /* CPU is affected by TSX Async Abort(TAA) */ +#define X86_BUG_ITLB_MULTIHIT X86_BUG(23) /* CPU may incur MCE during certain page attribute changes */ +#define X86_BUG_SRBDS X86_BUG(24) /* CPU may leak RNG bits if not mitigated */ #endif /* _ASM_X86_CPUFEATURES_H */ diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 8d162e0f2881..b12b0a50ad1f 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -103,6 +103,10 @@ #define TSX_CTRL_RTM_DISABLE BIT(0) /* Disable RTM feature */ #define TSX_CTRL_CPUID_CLEAR BIT(1) /* Disable TSX enumeration */ +/* SRBDS support */ +#define MSR_IA32_MCU_OPT_CTRL 0x00000123 +#define RNGDS_MITG_DIS BIT(0) + #define MSR_IA32_SYSENTER_CS 0x00000174 #define MSR_IA32_SYSENTER_ESP 0x00000175 #define MSR_IA32_SYSENTER_EIP 0x00000176 diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 24307d5bb4b8..5ef0a2b34261 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -40,6 +40,7 @@ static void __init l1tf_select_mitigation(void); static void __init mds_select_mitigation(void); static void __init mds_print_mitigation(void); static void __init taa_select_mitigation(void); +static void __init srbds_select_mitigation(void); /* The base value of the SPEC_CTRL MSR that always has to be preserved. */ u64 x86_spec_ctrl_base; @@ -107,6 +108,7 @@ void __init check_bugs(void) l1tf_select_mitigation(); mds_select_mitigation(); taa_select_mitigation(); + srbds_select_mitigation(); /* * As MDS and TAA mitigations are inter-related, print MDS @@ -389,6 +391,97 @@ static int __init tsx_async_abort_parse_cmdline(char *str) } early_param("tsx_async_abort", tsx_async_abort_parse_cmdline); +#undef pr_fmt +#define pr_fmt(fmt) "SRBDS: " fmt + +enum srbds_mitigations { + SRBDS_MITIGATION_OFF, + SRBDS_MITIGATION_UCODE_NEEDED, + SRBDS_MITIGATION_FULL, + SRBDS_MITIGATION_TSX_OFF, + SRBDS_MITIGATION_HYPERVISOR, +}; + +static enum srbds_mitigations srbds_mitigation __ro_after_init = SRBDS_MITIGATION_FULL; + +static const char * const srbds_strings[] = { + [SRBDS_MITIGATION_OFF] = "Vulnerable", + [SRBDS_MITIGATION_UCODE_NEEDED] = "Vulnerable: No microcode", + [SRBDS_MITIGATION_FULL] = "Mitigation: Microcode", + [SRBDS_MITIGATION_TSX_OFF] = "Mitigation: TSX disabled", + [SRBDS_MITIGATION_HYPERVISOR] = "Unknown: Dependent on hypervisor status", +}; + +static bool srbds_off; + +void update_srbds_msr(void) +{ + u64 mcu_ctrl; + + if (!boot_cpu_has_bug(X86_BUG_SRBDS)) + return; + + if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) + return; + + if (srbds_mitigation == SRBDS_MITIGATION_UCODE_NEEDED) + return; + + rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl); + + switch (srbds_mitigation) { + case SRBDS_MITIGATION_OFF: + case SRBDS_MITIGATION_TSX_OFF: + mcu_ctrl |= RNGDS_MITG_DIS; + break; + case SRBDS_MITIGATION_FULL: + mcu_ctrl &= ~RNGDS_MITG_DIS; + break; + default: + break; + } + + wrmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl); +} + +static void __init srbds_select_mitigation(void) +{ + u64 ia32_cap; + + if (!boot_cpu_has_bug(X86_BUG_SRBDS)) + return; + + /* + * Check to see if this is one of the MDS_NO systems supporting + * TSX that are only exposed to SRBDS when TSX is enabled. + */ + ia32_cap = x86_read_arch_cap_msr(); + if ((ia32_cap & ARCH_CAP_MDS_NO) && !boot_cpu_has(X86_FEATURE_RTM)) + srbds_mitigation = SRBDS_MITIGATION_TSX_OFF; + else if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) + srbds_mitigation = SRBDS_MITIGATION_HYPERVISOR; + else if (!boot_cpu_has(X86_FEATURE_SRBDS_CTRL)) + srbds_mitigation = SRBDS_MITIGATION_UCODE_NEEDED; + else if (cpu_mitigations_off() || srbds_off) + srbds_mitigation = SRBDS_MITIGATION_OFF; + + update_srbds_msr(); + pr_info("%s\n", srbds_strings[srbds_mitigation]); +} + +static int __init srbds_parse_cmdline(char *str) +{ + if (!str) + return -EINVAL; + + if (!boot_cpu_has_bug(X86_BUG_SRBDS)) + return 0; + + srbds_off = !strcmp(str, "off"); + return 0; +} +early_param("srbds", srbds_parse_cmdline); + #undef pr_fmt #define pr_fmt(fmt) "Spectre V1 : " fmt @@ -1501,6 +1594,11 @@ static char *ibpb_state(void) return ""; } +static ssize_t srbds_show_state(char *buf) +{ + return sprintf(buf, "%s\n", srbds_strings[srbds_mitigation]); +} + static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr, char *buf, unsigned int bug) { @@ -1542,6 +1640,9 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr case X86_BUG_ITLB_MULTIHIT: return itlb_multihit_show_state(buf); + case X86_BUG_SRBDS: + return srbds_show_state(buf); + default: break; } @@ -1588,4 +1689,9 @@ ssize_t cpu_show_itlb_multihit(struct device *dev, struct device_attribute *attr { return cpu_show_common(dev, attr, buf, X86_BUG_ITLB_MULTIHIT); } + +ssize_t cpu_show_srbds(struct device *dev, struct device_attribute *attr, char *buf) +{ + return cpu_show_common(dev, attr, buf, X86_BUG_SRBDS); +} #endif diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 078ad5da2e1f..b16b6176738b 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -956,6 +956,27 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = { {} }; +#define VULNBL_INTEL_STEPPINGS(model, steppings, issues) \ + X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE(INTEL, 6, \ + INTEL_FAM6_##model, steppings, \ + X86_FEATURE_ANY, issues) + +#define SRBDS BIT(0) + +static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { + VULNBL_INTEL_STEPPINGS(IVYBRIDGE, X86_STEPPING_ANY, SRBDS), + VULNBL_INTEL_STEPPINGS(HASWELL_CORE, X86_STEPPING_ANY, SRBDS), + VULNBL_INTEL_STEPPINGS(HASWELL_ULT, X86_STEPPING_ANY, SRBDS), + VULNBL_INTEL_STEPPINGS(HASWELL_GT3E, X86_STEPPING_ANY, SRBDS), + VULNBL_INTEL_STEPPINGS(BROADWELL_GT3E, X86_STEPPING_ANY, SRBDS), + VULNBL_INTEL_STEPPINGS(BROADWELL_CORE, X86_STEPPING_ANY, SRBDS), + VULNBL_INTEL_STEPPINGS(SKYLAKE_MOBILE, X86_STEPPING_ANY, SRBDS), + VULNBL_INTEL_STEPPINGS(SKYLAKE_DESKTOP, X86_STEPPING_ANY, SRBDS), + VULNBL_INTEL_STEPPINGS(KABYLAKE_MOBILE, X86_STEPPINGS(0x0, 0xC), SRBDS), + VULNBL_INTEL_STEPPINGS(KABYLAKE_DESKTOP,X86_STEPPINGS(0x0, 0xD), SRBDS), + {} +}; + static bool __init cpu_matches(const struct x86_cpu_id *table, unsigned long which) { const struct x86_cpu_id *m = x86_match_cpu(table); @@ -1021,6 +1042,15 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) (ia32_cap & ARCH_CAP_TSX_CTRL_MSR))) setup_force_cpu_bug(X86_BUG_TAA); + /* + * SRBDS affects CPUs which support RDRAND or RDSEED and are listed + * in the vulnerability blacklist. + */ + if ((cpu_has(c, X86_FEATURE_RDRAND) || + cpu_has(c, X86_FEATURE_RDSEED)) && + cpu_matches(cpu_vuln_blacklist, SRBDS)) + setup_force_cpu_bug(X86_BUG_SRBDS); + if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN)) return; @@ -1453,6 +1483,7 @@ void identify_secondary_cpu(struct cpuinfo_x86 *c) mtrr_ap_init(); validate_apic_and_package_id(c); x86_spec_ctrl_setup_ap(); + update_srbds_msr(); } struct msr_range { diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h index 4350f50b5deb..fdeeab6b158c 100644 --- a/arch/x86/kernel/cpu/cpu.h +++ b/arch/x86/kernel/cpu/cpu.h @@ -66,6 +66,7 @@ extern int detect_extended_topology_early(struct cpuinfo_x86 *c); extern int detect_ht_early(struct cpuinfo_x86 *c); extern void x86_spec_ctrl_setup_ap(void); +extern void update_srbds_msr(void); extern u64 x86_read_arch_cap_msr(void); diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 677c5f36674b..100850398dd3 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -550,6 +550,12 @@ ssize_t __weak cpu_show_itlb_multihit(struct device *dev, return sprintf(buf, "Not affected\n"); } +ssize_t __weak cpu_show_srbds(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "Not affected\n"); +} + static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL); static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL); static DEVICE_ATTR(spectre_v2, 0444, cpu_show_spectre_v2, NULL); @@ -558,6 +564,7 @@ static DEVICE_ATTR(l1tf, 0444, cpu_show_l1tf, NULL); static DEVICE_ATTR(mds, 0444, cpu_show_mds, NULL); static DEVICE_ATTR(tsx_async_abort, 0444, cpu_show_tsx_async_abort, NULL); static DEVICE_ATTR(itlb_multihit, 0444, cpu_show_itlb_multihit, NULL); +static DEVICE_ATTR(srbds, 0444, cpu_show_srbds, NULL); static struct attribute *cpu_root_vulnerabilities_attrs[] = { &dev_attr_meltdown.attr, @@ -568,6 +575,7 @@ static struct attribute *cpu_root_vulnerabilities_attrs[] = { &dev_attr_mds.attr, &dev_attr_tsx_async_abort.attr, &dev_attr_itlb_multihit.attr, + &dev_attr_srbds.attr, NULL }; From 2808035ba55eb8aaaf5eb37421dbfff37c1f25a8 Mon Sep 17 00:00:00 2001 From: Mark Gross Date: Mon, 27 Apr 2020 21:17:16 +0200 Subject: [PATCH 254/387] x86/speculation: Add SRBDS vulnerability and mitigation documentation commit 7222a1b5b87417f22265c92deea76a6aecd0fb0f upstream Add documentation for the SRBDS vulnerability and its mitigation. [ bp: Massage. jpoimboe: sysfs table strings. ] Signed-off-by: Mark Gross Signed-off-by: Borislav Petkov Reviewed-by: Tony Luck Reviewed-by: Josh Poimboeuf Signed-off-by: Greg Kroah-Hartman --- Documentation/hw-vuln/index.rst | 3 +- .../special-register-buffer-data-sampling.rst | 148 ++++++++++++++++++ 2 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 Documentation/hw-vuln/special-register-buffer-data-sampling.rst diff --git a/Documentation/hw-vuln/index.rst b/Documentation/hw-vuln/index.rst index 24f53c501366..b5fbc6ae9d5f 100644 --- a/Documentation/hw-vuln/index.rst +++ b/Documentation/hw-vuln/index.rst @@ -12,4 +12,5 @@ are configurable at compile, boot or run time. l1tf mds tsx_async_abort - multihit.rst + multihit + special-register-buffer-data-sampling diff --git a/Documentation/hw-vuln/special-register-buffer-data-sampling.rst b/Documentation/hw-vuln/special-register-buffer-data-sampling.rst new file mode 100644 index 000000000000..6a473da80b62 --- /dev/null +++ b/Documentation/hw-vuln/special-register-buffer-data-sampling.rst @@ -0,0 +1,148 @@ +.. SPDX-License-Identifier: GPL-2.0 + +SRBDS - Special Register Buffer Data Sampling +============================================= + +SRBDS is a hardware vulnerability that allows MDS :doc:`mds` techniques to +infer values returned from special register accesses. Special register +accesses are accesses to off core registers. According to Intel's evaluation, +the special register reads that have a security expectation of privacy are +RDRAND, RDSEED and SGX EGETKEY. + +When RDRAND, RDSEED and EGETKEY instructions are used, the data is moved +to the core through the special register mechanism that is susceptible +to MDS attacks. + +Affected processors +-------------------- +Core models (desktop, mobile, Xeon-E3) that implement RDRAND and/or RDSEED may +be affected. + +A processor is affected by SRBDS if its Family_Model and stepping is +in the following list, with the exception of the listed processors +exporting MDS_NO while Intel TSX is available yet not enabled. The +latter class of processors are only affected when Intel TSX is enabled +by software using TSX_CTRL_MSR otherwise they are not affected. + + ============= ============ ======== + common name Family_Model Stepping + ============= ============ ======== + Haswell 06_3CH All + Haswell_L 06_45H All + Haswell_G 06_46H All + + Broadwell_G 06_47H All + Broadwell 06_3DH All + + Skylake_L 06_4EH All + Skylake 06_5EH All + + Kabylake_L 06_8EH <=0xC + + Kabylake 06_9EH <=0xD + ============= ============ ======== + +Related CVEs +------------ + +The following CVE entry is related to this SRBDS issue: + + ============== ===== ===================================== + CVE-2020-0543 SRBDS Special Register Buffer Data Sampling + ============== ===== ===================================== + +Attack scenarios +---------------- +An unprivileged user can extract values returned from RDRAND and RDSEED +executed on another core or sibling thread using MDS techniques. + + +Mitigation mechanism +------------------- +Intel will release microcode updates that modify the RDRAND, RDSEED, and +EGETKEY instructions to overwrite secret special register data in the shared +staging buffer before the secret data can be accessed by another logical +processor. + +During execution of the RDRAND, RDSEED, or EGETKEY instructions, off-core +accesses from other logical processors will be delayed until the special +register read is complete and the secret data in the shared staging buffer is +overwritten. + +This has three effects on performance: + +#. RDRAND, RDSEED, or EGETKEY instructions have higher latency. + +#. Executing RDRAND at the same time on multiple logical processors will be + serialized, resulting in an overall reduction in the maximum RDRAND + bandwidth. + +#. Executing RDRAND, RDSEED or EGETKEY will delay memory accesses from other + logical processors that miss their core caches, with an impact similar to + legacy locked cache-line-split accesses. + +The microcode updates provide an opt-out mechanism (RNGDS_MITG_DIS) to disable +the mitigation for RDRAND and RDSEED instructions executed outside of Intel +Software Guard Extensions (Intel SGX) enclaves. On logical processors that +disable the mitigation using this opt-out mechanism, RDRAND and RDSEED do not +take longer to execute and do not impact performance of sibling logical +processors memory accesses. The opt-out mechanism does not affect Intel SGX +enclaves (including execution of RDRAND or RDSEED inside an enclave, as well +as EGETKEY execution). + +IA32_MCU_OPT_CTRL MSR Definition +-------------------------------- +Along with the mitigation for this issue, Intel added a new thread-scope +IA32_MCU_OPT_CTRL MSR, (address 0x123). The presence of this MSR and +RNGDS_MITG_DIS (bit 0) is enumerated by CPUID.(EAX=07H,ECX=0).EDX[SRBDS_CTRL = +9]==1. This MSR is introduced through the microcode update. + +Setting IA32_MCU_OPT_CTRL[0] (RNGDS_MITG_DIS) to 1 for a logical processor +disables the mitigation for RDRAND and RDSEED executed outside of an Intel SGX +enclave on that logical processor. Opting out of the mitigation for a +particular logical processor does not affect the RDRAND and RDSEED mitigations +for other logical processors. + +Note that inside of an Intel SGX enclave, the mitigation is applied regardless +of the value of RNGDS_MITG_DS. + +Mitigation control on the kernel command line +--------------------------------------------- +The kernel command line allows control over the SRBDS mitigation at boot time +with the option "srbds=". The option for this is: + + ============= ============================================================= + off This option disables SRBDS mitigation for RDRAND and RDSEED on + affected platforms. + ============= ============================================================= + +SRBDS System Information +----------------------- +The Linux kernel provides vulnerability status information through sysfs. For +SRBDS this can be accessed by the following sysfs file: +/sys/devices/system/cpu/vulnerabilities/srbds + +The possible values contained in this file are: + + ============================== ============================================= + Not affected Processor not vulnerable + Vulnerable Processor vulnerable and mitigation disabled + Vulnerable: No microcode Processor vulnerable and microcode is missing + mitigation + Mitigation: Microcode Processor is vulnerable and mitigation is in + effect. + Mitigation: TSX disabled Processor is only vulnerable when TSX is + enabled while this system was booted with TSX + disabled. + Unknown: Dependent on + hypervisor status Running on virtual guest processor that is + affected but with no way to know if host + processor is mitigated or vulnerable. + ============================== ============================================= + +SRBDS Default mitigation +------------------------ +This new microcode serializes processor access during execution of RDRAND, +RDSEED ensures that the shared buffer is overwritten before it is released for +reuse. Use the "srbds=off" kernel command line to disable the mitigation for +RDRAND and RDSEED. From 4798f72395eb523d251f18226527329debe353e9 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Mon, 27 Apr 2020 20:46:13 +0200 Subject: [PATCH 255/387] x86/speculation: Add Ivy Bridge to affected list commit 3798cc4d106e91382bfe016caa2edada27c2bb3f upstream Make the docs match the code. Signed-off-by: Josh Poimboeuf Signed-off-by: Thomas Gleixner Signed-off-by: Greg Kroah-Hartman --- .../hw-vuln/special-register-buffer-data-sampling.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Documentation/hw-vuln/special-register-buffer-data-sampling.rst b/Documentation/hw-vuln/special-register-buffer-data-sampling.rst index 6a473da80b62..47b1b3afac99 100644 --- a/Documentation/hw-vuln/special-register-buffer-data-sampling.rst +++ b/Documentation/hw-vuln/special-register-buffer-data-sampling.rst @@ -27,6 +27,8 @@ by software using TSX_CTRL_MSR otherwise they are not affected. ============= ============ ======== common name Family_Model Stepping ============= ============ ======== + IvyBridge 06_3AH All + Haswell 06_3CH All Haswell_L 06_45H All Haswell_G 06_46H All @@ -37,9 +39,8 @@ by software using TSX_CTRL_MSR otherwise they are not affected. Skylake_L 06_4EH All Skylake 06_5EH All - Kabylake_L 06_8EH <=0xC - - Kabylake 06_9EH <=0xD + Kabylake_L 06_8EH <= 0xC + Kabylake 06_9EH <= 0xD ============= ============ ======== Related CVEs From 259108a77baa0fd4f0541d68a494070e3f06ec5f Mon Sep 17 00:00:00 2001 From: Mathieu Othacehe Date: Sun, 3 May 2020 11:29:55 +0200 Subject: [PATCH 256/387] iio: vcnl4000: Fix i2c swapped word reading. [ Upstream commit 18dfb5326370991c81a6d1ed6d1aeee055cb8c05 ] The bytes returned by the i2c reading need to be swapped unconditionally. Otherwise, on be16 platforms, an incorrect value will be returned. Taking the slow path via next merge window as its been around a while and we have a patch set dependent on this which would be held up. Fixes: 62a1efb9f868 ("iio: add vcnl4000 combined ALS and proximity sensor") Signed-off-by: Mathieu Othacehe Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin --- drivers/iio/light/vcnl4000.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c index 360b6e98137a..5a3a532937ba 100644 --- a/drivers/iio/light/vcnl4000.c +++ b/drivers/iio/light/vcnl4000.c @@ -61,7 +61,6 @@ static int vcnl4000_measure(struct vcnl4000_data *data, u8 req_mask, u8 rdy_mask, u8 data_reg, int *val) { int tries = 20; - __be16 buf; int ret; mutex_lock(&data->lock); @@ -88,13 +87,12 @@ static int vcnl4000_measure(struct vcnl4000_data *data, u8 req_mask, goto fail; } - ret = i2c_smbus_read_i2c_block_data(data->client, - data_reg, sizeof(buf), (u8 *) &buf); + ret = i2c_smbus_read_word_swapped(data->client, data_reg); if (ret < 0) goto fail; mutex_unlock(&data->lock); - *val = be16_to_cpu(buf); + *val = ret; return 0; From 5ec850f0f15dd128c0d584234cdcade9ddf9bb0f Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Mon, 4 May 2020 18:47:25 +0200 Subject: [PATCH 257/387] uprobes: ensure that uprobe->offset and ->ref_ctr_offset are properly aligned commit 013b2deba9a6b80ca02f4fafd7dedf875e9b4450 upstream. uprobe_write_opcode() must not cross page boundary; prepare_uprobe() relies on arch_uprobe_analyze_insn() which should validate "vaddr" but some architectures (csky, s390, and sparc) don't do this. We can remove the BUG_ON() check in prepare_uprobe() and validate the offset early in __uprobe_register(). The new IS_ALIGNED() check matches the alignment check in arch_prepare_kprobe() on supported architectures, so I think that all insns must be aligned to UPROBE_SWBP_INSN_SIZE. Another problem is __update_ref_ctr() which was wrong from the very beginning, it can read/write outside of kmap'ed page unless "vaddr" is aligned to sizeof(short), __uprobe_register() should check this too. Reported-by: Linus Torvalds Suggested-by: Linus Torvalds Signed-off-by: Oleg Nesterov Reviewed-by: Srikar Dronamraju Acked-by: Christian Borntraeger Tested-by: Sven Schnelle Cc: Steven Rostedt Cc: stable@vger.kernel.org Signed-off-by: Linus Torvalds [ check for ref_ctr_offset removed for backport - gregkh ] Signed-off-by: Greg Kroah-Hartman --- kernel/events/uprobes.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 8ddd29476c0d..1fcaa174ed32 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -604,10 +604,6 @@ static int prepare_uprobe(struct uprobe *uprobe, struct file *file, if (ret) goto out; - /* uprobe_write_opcode() assumes we don't cross page boundary */ - BUG_ON((uprobe->offset & ~PAGE_MASK) + - UPROBE_SWBP_INSN_SIZE > PAGE_SIZE); - smp_wmb(); /* pairs with the smp_rmb() in handle_swbp() */ set_bit(UPROBE_COPY_INSN, &uprobe->flags); @@ -886,6 +882,13 @@ int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer * if (offset > i_size_read(inode)) return -EINVAL; + /* + * This ensures that copy_from_page() and copy_to_page() + * can't cross page boundary. + */ + if (!IS_ALIGNED(offset, UPROBE_SWBP_INSN_SIZE)) + return -EINVAL; + retry: uprobe = alloc_uprobe(inode, offset); if (!uprobe) @@ -1696,6 +1699,9 @@ static int is_trap_at_addr(struct mm_struct *mm, unsigned long vaddr) uprobe_opcode_t opcode; int result; + if (WARN_ON_ONCE(!IS_ALIGNED(vaddr, UPROBE_SWBP_INSN_SIZE))) + return -EINVAL; + pagefault_disable(); result = __get_user(opcode, (uprobe_opcode_t __user *)vaddr); pagefault_enable(); From e0799bae56744764303252ac8d52ddb5774bcb4e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 11 Jun 2020 09:22:24 +0200 Subject: [PATCH 258/387] Linux 4.9.227 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b0e1162fddfa..6c3c6e193621 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 4 PATCHLEVEL = 9 -SUBLEVEL = 226 +SUBLEVEL = 227 EXTRAVERSION = NAME = Roaring Lionus From 47fb86422692fac566708d2719226c1a2f857249 Mon Sep 17 00:00:00 2001 From: Hangbin Liu Date: Mon, 1 Jun 2020 11:55:03 +0800 Subject: [PATCH 259/387] ipv6: fix IPV6_ADDRFORM operation logic [ Upstream commit 79a1f0ccdbb4ad700590f61b00525b390cb53905 ] Socket option IPV6_ADDRFORM supports UDP/UDPLITE and TCP at present. Previously the checking logic looks like: if (sk->sk_protocol == IPPROTO_UDP || sk->sk_protocol == IPPROTO_UDPLITE) do_some_check; else if (sk->sk_protocol != IPPROTO_TCP) break; After commit b6f6118901d1 ("ipv6: restrict IPV6_ADDRFORM operation"), TCP was blocked as the logic changed to: if (sk->sk_protocol == IPPROTO_UDP || sk->sk_protocol == IPPROTO_UDPLITE) do_some_check; else if (sk->sk_protocol == IPPROTO_TCP) do_some_check; break; else break; Then after commit 82c9ae440857 ("ipv6: fix restrict IPV6_ADDRFORM operation") UDP/UDPLITE were blocked as the logic changed to: if (sk->sk_protocol == IPPROTO_UDP || sk->sk_protocol == IPPROTO_UDPLITE) do_some_check; if (sk->sk_protocol == IPPROTO_TCP) do_some_check; if (sk->sk_protocol != IPPROTO_TCP) break; Fix it by using Eric's code and simply remove the break in TCP check, which looks like: if (sk->sk_protocol == IPPROTO_UDP || sk->sk_protocol == IPPROTO_UDPLITE) do_some_check; else if (sk->sk_protocol == IPPROTO_TCP) do_some_check; else break; Fixes: 82c9ae440857 ("ipv6: fix restrict IPV6_ADDRFORM operation") Signed-off-by: Hangbin Liu Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/ipv6/ipv6_sockglue.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 455fa4a30353..2c770bba212c 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -184,14 +184,15 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, retv = -EBUSY; break; } - } - if (sk->sk_protocol == IPPROTO_TCP && - sk->sk_prot != &tcpv6_prot) { - retv = -EBUSY; + } else if (sk->sk_protocol == IPPROTO_TCP) { + if (sk->sk_prot != &tcpv6_prot) { + retv = -EBUSY; + break; + } + } else { break; } - if (sk->sk_protocol != IPPROTO_TCP) - break; + if (sk->sk_state != TCP_ESTABLISHED) { retv = -ENOTCONN; break; From 72787b04621661e9e9a63af4215749a938233e2a Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Mon, 1 Jun 2020 15:58:55 +0300 Subject: [PATCH 260/387] vxlan: Avoid infinite loop when suppressing NS messages with invalid options [ Upstream commit 8066e6b449e050675df48e7c4b16c29f00507ff0 ] When proxy mode is enabled the vxlan device might reply to Neighbor Solicitation (NS) messages on behalf of remote hosts. In case the NS message includes the "Source link-layer address" option [1], the vxlan device will use the specified address as the link-layer destination address in its reply. To avoid an infinite loop, break out of the options parsing loop when encountering an option with length zero and disregard the NS message. This is consistent with the IPv6 ndisc code and RFC 4886 which states that "Nodes MUST silently discard an ND packet that contains an option with length zero" [2]. [1] https://tools.ietf.org/html/rfc4861#section-4.3 [2] https://tools.ietf.org/html/rfc4861#section-4.6 Fixes: 4b29dba9c085 ("vxlan: fix nonfunctional neigh_reduce()") Signed-off-by: Ido Schimmel Acked-by: Nikolay Aleksandrov Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/vxlan.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 58ddb6c90418..b1470d30d079 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -1521,6 +1521,10 @@ static struct sk_buff *vxlan_na_create(struct sk_buff *request, daddr = eth_hdr(request)->h_source; ns_olen = request->len - skb_transport_offset(request) - sizeof(*ns); for (i = 0; i < ns_olen-1; i += (ns->opt[i+1]<<3)) { + if (!ns->opt[i + 1]) { + kfree_skb(reply); + return NULL; + } if (ns->opt[i] == ND_OPT_SOURCE_LL_ADDR) { daddr = ns->opt + i + sizeof(struct nd_opt_hdr); break; From 07e0b16899ebc1f8bf0558561869be1612decd53 Mon Sep 17 00:00:00 2001 From: Johannes Thumshirn Date: Wed, 12 Apr 2017 09:21:19 +0200 Subject: [PATCH 261/387] scsi: return correct blkprep status code in case scsi_init_io() fails. commit e7661a8e5ce10b5321882d0bbaf3f81070903319 upstream. When instrumenting the SCSI layer to run into the !blk_rq_nr_phys_segments(rq) case the following warning emitted from the block layer: blk_peek_request: bad return=-22 This happens because since commit fd3fc0b4d730 ("scsi: don't BUG_ON() empty DMA transfers") we return the wrong error value from scsi_prep_fn() back to the block layer. [mkp: silenced checkpatch] Signed-off-by: Johannes Thumshirn Fixes: fd3fc0b4d730 scsi: don't BUG_ON() empty DMA transfers Cc: Reviewed-by: Christoph Hellwig Reviewed-by: Hannes Reinecke Reviewed-by: Bart Van Assche Signed-off-by: Martin K. Petersen [iwamatsu: - backport for 4.4.y and 4.9.y - Use rq->nr_phys_segments instead of blk_rq_nr_phys_segments] Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/scsi_lib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index c7b770075caa..80341863caa5 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1029,10 +1029,10 @@ int scsi_init_io(struct scsi_cmnd *cmd) struct scsi_device *sdev = cmd->device; struct request *rq = cmd->request; bool is_mq = (rq->mq_ctx != NULL); - int error; + int error = BLKPREP_KILL; if (WARN_ON_ONCE(!rq->nr_phys_segments)) - return -EINVAL; + goto err_exit; error = scsi_init_sgtable(rq, &cmd->sdb); if (error) From adbbd088ab97077fa0529740ec43185c7fb7cdd5 Mon Sep 17 00:00:00 2001 From: Su Kang Yin Date: Thu, 11 Jun 2020 19:50:47 +0800 Subject: [PATCH 262/387] crypto: talitos - fix ECB and CBC algs ivsize commit e1de42fdfc6a ("crypto: talitos - fix ECB algs ivsize") wrongly modified CBC algs ivsize instead of ECB aggs ivsize. This restore the CBC algs original ivsize of removes ECB's ones. Fixes: e1de42fdfc6a ("crypto: talitos - fix ECB algs ivsize") Signed-off-by: Su Kang Yin Reviewed-by: Christophe Leroy Signed-off-by: Greg Kroah-Hartman --- drivers/crypto/talitos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 8b383d3d21c2..059c2d4ad18f 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -2636,7 +2636,6 @@ static struct talitos_alg_template driver_algs[] = { .cra_ablkcipher = { .min_keysize = AES_MIN_KEY_SIZE, .max_keysize = AES_MAX_KEY_SIZE, - .ivsize = AES_BLOCK_SIZE, } }, .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | @@ -2670,6 +2669,7 @@ static struct talitos_alg_template driver_algs[] = { .cra_ablkcipher = { .min_keysize = AES_MIN_KEY_SIZE, .max_keysize = AES_MAX_KEY_SIZE, + .ivsize = AES_BLOCK_SIZE, .setkey = ablkcipher_aes_setkey, } }, From d95c626d0b89ddbd223d210cafa07b38e53d9898 Mon Sep 17 00:00:00 2001 From: Fredrik Strupe Date: Mon, 18 May 2020 19:41:11 +0100 Subject: [PATCH 263/387] ARM: 8977/1: ptrace: Fix mask for thumb breakpoint hook [ Upstream commit 3866f217aaa81bf7165c7f27362eee5d7919c496 ] call_undef_hook() in traps.c applies the same instr_mask for both 16-bit and 32-bit thumb instructions. If instr_mask then is only 16 bits wide (0xffff as opposed to 0xffffffff), the first half-word of 32-bit thumb instructions will be masked out. This makes the function match 32-bit thumb instructions where the second half-word is equal to instr_val, regardless of the first half-word. The result in this case is that all undefined 32-bit thumb instructions with the second half-word equal to 0xde01 (udf #1) work as breakpoints and will raise a SIGTRAP instead of a SIGILL, instead of just the one intended 16-bit instruction. An example of such an instruction is 0xeaa0de01, which is unallocated according to Arm ARM and should raise a SIGILL, but instead raises a SIGTRAP. This patch fixes the issue by setting all the bits in instr_mask, which will still match the intended 16-bit thumb instruction (where the upper half is always 0), but not any 32-bit thumb instructions. Cc: Oleg Nesterov Signed-off-by: Fredrik Strupe Signed-off-by: Russell King Signed-off-by: Sasha Levin --- arch/arm/kernel/ptrace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index ae738a6319f6..364985c96a92 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -227,8 +227,8 @@ static struct undef_hook arm_break_hook = { }; static struct undef_hook thumb_break_hook = { - .instr_mask = 0xffff, - .instr_val = 0xde01, + .instr_mask = 0xffffffff, + .instr_val = 0x0000de01, .cpsr_mask = PSR_T_BIT, .cpsr_val = PSR_T_BIT, .fn = break_trap, From 4205ab13e3e6cfcc290da48f1af33add7cb75252 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 26 May 2020 09:38:31 -0600 Subject: [PATCH 264/387] sched/fair: Don't NUMA balance for kthreads [ Upstream commit 18f855e574d9799a0e7489f8ae6fd8447d0dd74a ] Stefano reported a crash with using SQPOLL with io_uring: BUG: kernel NULL pointer dereference, address: 00000000000003b0 CPU: 2 PID: 1307 Comm: io_uring-sq Not tainted 5.7.0-rc7 #11 RIP: 0010:task_numa_work+0x4f/0x2c0 Call Trace: task_work_run+0x68/0xa0 io_sq_thread+0x252/0x3d0 kthread+0xf9/0x130 ret_from_fork+0x35/0x40 which is task_numa_work() oopsing on current->mm being NULL. The task work is queued by task_tick_numa(), which checks if current->mm is NULL at the time of the call. But this state isn't necessarily persistent, if the kthread is using use_mm() to temporarily adopt the mm of a task. Change the task_tick_numa() check to exclude kernel threads in general, as it doesn't make sense to attempt ot balance for kthreads anyway. Reported-by: Stefano Garzarella Signed-off-by: Jens Axboe Signed-off-by: Ingo Molnar Acked-by: Peter Zijlstra Link: https://lore.kernel.org/r/865de121-8190-5d30-ece5-3b097dc74431@kernel.dk Signed-off-by: Sasha Levin --- kernel/sched/fair.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 5e65c7eea872..8233032a2f01 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -2542,7 +2542,7 @@ void task_tick_numa(struct rq *rq, struct task_struct *curr) /* * We don't care about NUMA placement if we don't have memory. */ - if (!curr->mm || (curr->flags & PF_EXITING) || work->next != work) + if ((curr->flags & (PF_EXITING | PF_KTHREAD)) || work->next != work) return; /* From c465ee6aeb130687a9cd8605b363273800d0cff6 Mon Sep 17 00:00:00 2001 From: Thomas Falcon Date: Thu, 28 May 2020 11:19:17 -0500 Subject: [PATCH 265/387] drivers/net/ibmvnic: Update VNIC protocol version reporting [ Upstream commit 784688993ebac34dffe44a9f2fabbe126ebfd4db ] VNIC protocol version is reported in big-endian format, but it is not byteswapped before logging. Fix that, and remove version comparison as only one protocol version exists at this time. Signed-off-by: Thomas Falcon Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/ibm/ibmvnic.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 897a87ae8655..20f7ab4aa2f1 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -3362,12 +3362,10 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq, dev_err(dev, "Error %ld in VERSION_EXCHG_RSP\n", rc); break; } - dev_info(dev, "Partner protocol version is %d\n", - crq->version_exchange_rsp.version); - if (be16_to_cpu(crq->version_exchange_rsp.version) < - ibmvnic_version) - ibmvnic_version = + ibmvnic_version = be16_to_cpu(crq->version_exchange_rsp.version); + dev_info(dev, "Partner protocol version is %d\n", + ibmvnic_version); send_cap_queries(adapter); break; case QUERY_CAPABILITY_RSP: From 42133b6931b976fc987417a8e572628ac6c64018 Mon Sep 17 00:00:00 2001 From: Masashi Honma Date: Tue, 5 May 2020 06:44:43 +0900 Subject: [PATCH 266/387] ath9k_htc: Silence undersized packet warnings [ Upstream commit 450edd2805982d14ed79733a82927d2857b27cac ] Some devices like TP-Link TL-WN722N produces this kind of messages frequently. kernel: ath: phy0: Short RX data len, dropping (dlen: 4) This warning is useful for developers to recognize that the device (Wi-Fi dongle or USB hub etc) is noisy but not for general users. So this patch make this warning to debug message. Reported-By: Denis Ref: https://bugzilla.kernel.org/show_bug.cgi?id=207539 Fixes: cd486e627e67 ("ath9k_htc: Discard undersized packets") Signed-off-by: Masashi Honma Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200504214443.4485-1-masashi.honma@gmail.com Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 52b42ecee621..2eb169b204f8 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -998,9 +998,9 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, * which are not PHY_ERROR (short radar pulses have a length of 3) */ if (unlikely(!rs_datalen || (rs_datalen < 10 && !is_phyerr))) { - ath_warn(common, - "Short RX data len, dropping (dlen: %d)\n", - rs_datalen); + ath_dbg(common, ANY, + "Short RX data len, dropping (dlen: %d)\n", + rs_datalen); goto rx_next; } From 79138a2f6e322f3dac4b12a67cb5a2e263eecd9c Mon Sep 17 00:00:00 2001 From: Bob Haarman Date: Tue, 2 Jun 2020 12:30:59 -0700 Subject: [PATCH 267/387] x86_64: Fix jiffies ODR violation commit d8ad6d39c35d2b44b3d48b787df7f3359381dcbf upstream. 'jiffies' and 'jiffies_64' are meant to alias (two different symbols that share the same address). Most architectures make the symbols alias to the same address via a linker script assignment in their arch//kernel/vmlinux.lds.S: jiffies = jiffies_64; which is effectively a definition of jiffies. jiffies and jiffies_64 are both forward declared for all architectures in include/linux/jiffies.h. jiffies_64 is defined in kernel/time/timer.c. x86_64 was peculiar in that it wasn't doing the above linker script assignment, but rather was: 1. defining jiffies in arch/x86/kernel/time.c instead via the linker script. 2. overriding the symbol jiffies_64 from kernel/time/timer.c in arch/x86/kernel/vmlinux.lds.s via 'jiffies_64 = jiffies;'. As Fangrui notes: In LLD, symbol assignments in linker scripts override definitions in object files. GNU ld appears to have the same behavior. It would probably make sense for LLD to error "duplicate symbol" but GNU ld is unlikely to adopt for compatibility reasons. This results in an ODR violation (UB), which seems to have survived thus far. Where it becomes harmful is when; 1. -fno-semantic-interposition is used: As Fangrui notes: Clang after LLVM commit 5b22bcc2b70d ("[X86][ELF] Prefer to lower MC_GlobalAddress operands to .Lfoo$local") defaults to -fno-semantic-interposition similar semantics which help -fpic/-fPIC code avoid GOT/PLT when the referenced symbol is defined within the same translation unit. Unlike GCC -fno-semantic-interposition, Clang emits such relocations referencing local symbols for non-pic code as well. This causes references to jiffies to refer to '.Ljiffies$local' when jiffies is defined in the same translation unit. Likewise, references to jiffies_64 become references to '.Ljiffies_64$local' in translation units that define jiffies_64. Because these differ from the names used in the linker script, they will not be rewritten to alias one another. 2. Full LTO Full LTO effectively treats all source files as one translation unit, causing these local references to be produced everywhere. When the linker processes the linker script, there are no longer any references to jiffies_64' anywhere to replace with 'jiffies'. And thus '.Ljiffies$local' and '.Ljiffies_64$local' no longer alias at all. In the process of porting patches enabling Full LTO from arm64 to x86_64, spooky bugs have been observed where the kernel appeared to boot, but init doesn't get scheduled. Avoid the ODR violation by matching other architectures and define jiffies only by linker script. For -fno-semantic-interposition + Full LTO, there is no longer a global definition of jiffies for the compiler to produce a local symbol which the linker script won't ensure aliases to jiffies_64. Fixes: 40747ffa5aa8 ("asmlinkage: Make jiffies visible") Reported-by: Nathan Chancellor Reported-by: Alistair Delva Debugged-by: Nick Desaulniers Debugged-by: Sami Tolvanen Suggested-by: Fangrui Song Signed-off-by: Bob Haarman Signed-off-by: Thomas Gleixner Tested-by: Sedat Dilek # build+boot on Reviewed-by: Andi Kleen Reviewed-by: Josh Poimboeuf Cc: stable@vger.kernel.org Link: https://github.com/ClangBuiltLinux/linux/issues/852 Link: https://lkml.kernel.org/r/20200602193100.229287-1-inglorion@google.com Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/time.c | 4 ---- arch/x86/kernel/vmlinux.lds.S | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/arch/x86/kernel/time.c b/arch/x86/kernel/time.c index 89d1190b9d94..5e5de7a7f38d 100644 --- a/arch/x86/kernel/time.c +++ b/arch/x86/kernel/time.c @@ -23,10 +23,6 @@ #include #include -#ifdef CONFIG_X86_64 -__visible volatile unsigned long jiffies __cacheline_aligned_in_smp = INITIAL_JIFFIES; -#endif - unsigned long profile_pc(struct pt_regs *regs) { unsigned long pc = instruction_pointer(regs); diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 55f04875293f..097268f85e4e 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -34,13 +34,13 @@ OUTPUT_FORMAT(CONFIG_OUTPUT_FORMAT, CONFIG_OUTPUT_FORMAT, CONFIG_OUTPUT_FORMAT) #ifdef CONFIG_X86_32 OUTPUT_ARCH(i386) ENTRY(phys_startup_32) -jiffies = jiffies_64; #else OUTPUT_ARCH(i386:x86-64) ENTRY(phys_startup_64) -jiffies_64 = jiffies; #endif +jiffies = jiffies_64; + #if defined(CONFIG_X86_64) /* * On 64-bit, align RODATA to 2MB so we retain large page mappings for From 4046a2e4f6f5f07c1bd5ecb2dcdcca185cc0e53e Mon Sep 17 00:00:00 2001 From: Xiaochun Lee Date: Thu, 14 May 2020 23:31:07 -0400 Subject: [PATCH 268/387] x86/PCI: Mark Intel C620 MROMs as having non-compliant BARs commit 1574051e52cb4b5b7f7509cfd729b76ca1117808 upstream. The Intel C620 Platform Controller Hub has MROM functions that have non-PCI registers (undocumented in the public spec) where BAR 0 is supposed to be, which results in messages like this: pci 0000:00:11.0: [Firmware Bug]: reg 0x30: invalid BAR (can't size) Mark these MROM functions as having non-compliant BARs so we don't try to probe any of them. There are no other BARs on these devices. See the Intel C620 Series Chipset Platform Controller Hub Datasheet, May 2019, Document Number 336067-007US, sec 2.1, 35.5, 35.6. [bhelgaas: commit log, add 0xa26d] Link: https://lore.kernel.org/r/1589513467-17070-1-git-send-email-lixiaochun.2888@163.com Signed-off-by: Xiaochun Lee Signed-off-by: Bjorn Helgaas Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- arch/x86/pci/fixup.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index 62950ef7f84e..68e86d7cc94d 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c @@ -571,6 +571,10 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2fc0, pci_invalid_bar); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6f60, pci_invalid_bar); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fa0, pci_invalid_bar); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fc0, pci_invalid_bar); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0xa1ec, pci_invalid_bar); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0xa1ed, pci_invalid_bar); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0xa26c, pci_invalid_bar); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0xa26d, pci_invalid_bar); /* * Device [1022:7914] From fc0abf5a64ea5d028af0cf5d37d5898afe6748c5 Mon Sep 17 00:00:00 2001 From: Anthony Steinhauser Date: Sun, 5 Jan 2020 12:19:43 -0800 Subject: [PATCH 269/387] x86/speculation: Prevent rogue cross-process SSBD shutdown commit dbbe2ad02e9df26e372f38cc3e70dab9222c832e upstream. On context switch the change of TIF_SSBD and TIF_SPEC_IB are evaluated to adjust the mitigations accordingly. This is optimized to avoid the expensive MSR write if not needed. This optimization is buggy and allows an attacker to shutdown the SSBD protection of a victim process. The update logic reads the cached base value for the speculation control MSR which has neither the SSBD nor the STIBP bit set. It then OR's the SSBD bit only when TIF_SSBD is different and requests the MSR update. That means if TIF_SSBD of the previous and next task are the same, then the base value is not updated, even if TIF_SSBD is set. The MSR write is not requested. Subsequently if the TIF_STIBP bit differs then the STIBP bit is updated in the base value and the MSR is written with a wrong SSBD value. This was introduced when the per task/process conditional STIPB switching was added on top of the existing SSBD switching. It is exploitable if the attacker creates a process which enforces SSBD and has the contrary value of STIBP than the victim process (i.e. if the victim process enforces STIBP, the attacker process must not enforce it; if the victim process does not enforce STIBP, the attacker process must enforce it) and schedule it on the same core as the victim process. If the victim runs after the attacker the victim becomes vulnerable to Spectre V4. To fix this, update the MSR value independent of the TIF_SSBD difference and dependent on the SSBD mitigation method available. This ensures that a subsequent STIPB initiated MSR write has the correct state of SSBD. [ tglx: Handle X86_FEATURE_VIRT_SSBD & X86_FEATURE_VIRT_SSBD correctly and massaged changelog ] Fixes: 5bfbe3ad5840 ("x86/speculation: Prepare for per task indirect branch speculation control") Signed-off-by: Anthony Steinhauser Signed-off-by: Thomas Gleixner Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/process.c | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 2e4eab22ca37..f58e4cc20c1c 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -337,28 +337,20 @@ static __always_inline void __speculation_ctrl_update(unsigned long tifp, u64 msr = x86_spec_ctrl_base; bool updmsr = false; - /* - * If TIF_SSBD is different, select the proper mitigation - * method. Note that if SSBD mitigation is disabled or permanentely - * enabled this branch can't be taken because nothing can set - * TIF_SSBD. - */ - if (tif_diff & _TIF_SSBD) { - if (static_cpu_has(X86_FEATURE_VIRT_SSBD)) { + /* Handle change of TIF_SSBD depending on the mitigation method. */ + if (static_cpu_has(X86_FEATURE_VIRT_SSBD)) { + if (tif_diff & _TIF_SSBD) amd_set_ssb_virt_state(tifn); - } else if (static_cpu_has(X86_FEATURE_LS_CFG_SSBD)) { + } else if (static_cpu_has(X86_FEATURE_LS_CFG_SSBD)) { + if (tif_diff & _TIF_SSBD) amd_set_core_ssb_state(tifn); - } else if (static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD) || - static_cpu_has(X86_FEATURE_AMD_SSBD)) { - msr |= ssbd_tif_to_spec_ctrl(tifn); - updmsr = true; - } + } else if (static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD) || + static_cpu_has(X86_FEATURE_AMD_SSBD)) { + updmsr |= !!(tif_diff & _TIF_SSBD); + msr |= ssbd_tif_to_spec_ctrl(tifn); } - /* - * Only evaluate TIF_SPEC_IB if conditional STIBP is enabled, - * otherwise avoid the MSR write. - */ + /* Only evaluate TIF_SPEC_IB if conditional STIBP is enabled. */ if (IS_ENABLED(CONFIG_SMP) && static_branch_unlikely(&switch_to_cond_stibp)) { updmsr |= !!(tif_diff & _TIF_SPEC_IB); From cc66d80027fc21111b2241a3bb0fc7ec21f99125 Mon Sep 17 00:00:00 2001 From: Hill Ma Date: Sat, 25 Apr 2020 13:06:41 -0700 Subject: [PATCH 270/387] x86/reboot/quirks: Add MacBook6,1 reboot quirk commit 140fd4ac78d385e6c8e6a5757585f6c707085f87 upstream. On MacBook6,1 reboot would hang unless parameter reboot=pci is added. Make it automatic. Signed-off-by: Hill Ma Signed-off-by: Borislav Petkov Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/20200425200641.GA1554@cslab.localdomain Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/reboot.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index c55b11fe8e9f..b427dc73ba27 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -198,6 +198,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5"), }, }, + { /* Handle problems with rebooting on Apple MacBook6,1 */ + .callback = set_pci_reboot, + .ident = "Apple MacBook6,1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBook6,1"), + }, + }, { /* Handle problems with rebooting on Apple MacBookPro5 */ .callback = set_pci_reboot, .ident = "Apple MacBookPro5", From 1e8fd13caaa1403c4b776acc2f9e2e21d4dfe00f Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Fri, 22 May 2020 18:15:49 +0200 Subject: [PATCH 271/387] efi/efivars: Add missing kobject_put() in sysfs entry creation error path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit d8bd8c6e2cfab8b78b537715255be8d7557791c0 upstream. The documentation provided by kobject_init_and_add() clearly spells out the need to call kobject_put() on the kobject if an error is returned. Add this missing call to the error path. Cc: Reported-by: 亿一 Signed-off-by: Ard Biesheuvel Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/efi/efivars.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c index 1c65f5ac4368..6529addd1e82 100644 --- a/drivers/firmware/efi/efivars.c +++ b/drivers/firmware/efi/efivars.c @@ -586,8 +586,10 @@ efivar_create_sysfs_entry(struct efivar_entry *new_var) ret = kobject_init_and_add(&new_var->kobj, &efivar_ktype, NULL, "%s", short_name); kfree(short_name); - if (ret) + if (ret) { + kobject_put(&new_var->kobj); return ret; + } kobject_uevent(&new_var->kobj, KOBJ_ADD); if (efivar_entry_add(new_var, &efivar_sysfs_list)) { From 008eaa9e6b84b0325c7725ce8918c47692e99641 Mon Sep 17 00:00:00 2001 From: Chuhong Yuan Date: Wed, 3 Jun 2020 17:24:59 +0800 Subject: [PATCH 272/387] ALSA: es1688: Add the missed snd_card_free() commit d9b8fbf15d05350b36081eddafcf7b15aa1add50 upstream. snd_es968_pnp_detect() misses a snd_card_free() in a failed path. Add the missed function call to fix it. Fixes: a20971b201ac ("ALSA: Merge es1688 and es968 drivers") Signed-off-by: Chuhong Yuan Cc: Link: https://lore.kernel.org/r/20200603092459.1424093-1-hslester96@gmail.com Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/isa/es1688/es1688.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c index 1901c2bb6c3b..a36e2121ef09 100644 --- a/sound/isa/es1688/es1688.c +++ b/sound/isa/es1688/es1688.c @@ -284,8 +284,10 @@ static int snd_es968_pnp_detect(struct pnp_card_link *pcard, return error; } error = snd_es1688_probe(card, dev); - if (error < 0) + if (error < 0) { + snd_card_free(card); return error; + } pnp_set_card_drvdata(pcard, card); snd_es968_pnp_is_probed = 1; return 0; From f4df2c5f97951b1767005e79bd7d5897694539c0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 3 Jun 2020 17:37:08 +0200 Subject: [PATCH 273/387] ALSA: usb-audio: Fix inconsistent card PM state after resume commit 862b2509d157c629dd26d7ac6c6cdbf043d332eb upstream. When a USB-audio interface gets runtime-suspended via auto-pm feature, the driver suspends all functionality and increment chip->num_suspended_intf. Later on, when the system gets suspended to S3, the driver increments chip->num_suspended_intf again, skips the device changes, and sets the card power state to SNDRV_CTL_POWER_D3hot. In return, when the system gets resumed from S3, the resume callback decrements chip->num_suspended_intf. Since this refcount is still not zero (it's been runtime-suspended), the whole resume is skipped. But there is a small pitfall here. The problem is that the driver doesn't restore the card power state after this resume call, leaving it as SNDRV_CTL_POWER_D3hot. So, even after the system resume finishes, the card instance still appears as if it were system-suspended, and this confuses many ioctl accesses that are blocked unexpectedly. In details, we have two issues behind the scene: one is that the card power state is changed only when the refcount becomes zero, and another is that the prior auto-suspend check is kept in a boolean flag. Although the latter problem is almost negligible since the auto-pm feature is imposed only on the primary interface, but this can be a potential problem on the devices with multiple interfaces. This patch addresses those issues by the following: - Replace chip->autosuspended boolean flag with chip->system_suspend counter - At the first system-suspend, chip->num_suspended_intf is recorded to chip->system_suspend - At system-resume, the card power state is restored when the chip->num_suspended_intf refcount reaches to chip->system_suspend, i.e. the state returns to the auto-suspended Also, the patch fixes yet another hidden problem by the code refactoring along with the fixes above: namely, when some resume procedure failed, the driver left chip->num_suspended_intf that was already decreased, and it might lead to the refcount unbalance. In the new code, the refcount decrement is done after the whole resume procedure, and the problem is avoided as well. Fixes: 0662292aec05 ("ALSA: usb-audio: Handle normal and auto-suspend equally") Reported-and-tested-by: Macpaul Lin Cc: Link: https://lore.kernel.org/r/20200603153709.6293-1-tiwai@suse.de Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/usb/card.c | 20 +++++++++++++------- sound/usb/usbaudio.h | 2 +- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/sound/usb/card.c b/sound/usb/card.c index 549b9b061694..023a36a4922b 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -768,9 +768,6 @@ static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message) if (chip == (void *)-1L) return 0; - chip->autosuspended = !!PMSG_IS_AUTO(message); - if (!chip->autosuspended) - snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot); if (!chip->num_suspended_intf++) { list_for_each_entry(as, &chip->pcm_list, list) { snd_pcm_suspend_all(as->pcm); @@ -783,6 +780,11 @@ static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message) snd_usb_mixer_suspend(mixer); } + if (!PMSG_IS_AUTO(message) && !chip->system_suspend) { + snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot); + chip->system_suspend = chip->num_suspended_intf; + } + return 0; } @@ -795,10 +797,11 @@ static int __usb_audio_resume(struct usb_interface *intf, bool reset_resume) if (chip == (void *)-1L) return 0; - if (--chip->num_suspended_intf) - return 0; atomic_inc(&chip->active); /* avoid autopm */ + if (chip->num_suspended_intf > 1) + goto out; + /* * ALSA leaves material resumption to user space * we just notify and restart the mixers @@ -813,9 +816,12 @@ static int __usb_audio_resume(struct usb_interface *intf, bool reset_resume) snd_usbmidi_resume(p); } - if (!chip->autosuspended) + out: + if (chip->num_suspended_intf == chip->system_suspend) { snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0); - chip->autosuspended = 0; + chip->system_suspend = 0; + } + chip->num_suspended_intf--; err_out: atomic_dec(&chip->active); /* allow autopm after this point */ diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 4d5c89a7ba2b..f4ee83c8e0b2 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h @@ -37,7 +37,7 @@ struct snd_usb_audio { struct usb_interface *pm_intf; u32 usb_id; struct mutex mutex; - unsigned int autosuspended:1; + unsigned int system_suspend; atomic_t active; atomic_t shutdown; atomic_t usage_count; From bdce493344432a5ce4afa45e6ec8d14edd8dd468 Mon Sep 17 00:00:00 2001 From: Qiushi Wu Date: Wed, 27 May 2020 16:17:17 -0500 Subject: [PATCH 274/387] ACPI: sysfs: Fix reference count leak in acpi_sysfs_add_hotplug_profile() commit 6e6c25283dff866308c87b49434c7dbad4774cc0 upstream. kobject_init_and_add() takes reference even when it fails. Thus, when kobject_init_and_add() returns an error, kobject_put() must be called to properly clean up the kobject. Fixes: 3f8055c35836 ("ACPI / hotplug: Introduce user space interface for hotplug profiles") Signed-off-by: Qiushi Wu Cc: 3.10+ # 3.10+ Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/sysfs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index a36d0739dbfe..7502441b1400 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -898,8 +898,10 @@ void acpi_sysfs_add_hotplug_profile(struct acpi_hotplug_profile *hotplug, error = kobject_init_and_add(&hotplug->kobj, &acpi_hotplug_profile_ktype, hotplug_kobj, "%s", name); - if (error) + if (error) { + kobject_put(&hotplug->kobj); goto err_out; + } kobject_uevent(&hotplug->kobj, KOBJ_ADD); return; From 17cac70bdf319d85e6f4ba78f686c06ee55f86cf Mon Sep 17 00:00:00 2001 From: Qiushi Wu Date: Wed, 27 May 2020 17:35:51 -0500 Subject: [PATCH 275/387] ACPI: CPPC: Fix reference count leak in acpi_cppc_processor_probe() commit 4d8be4bc94f74bb7d096e1c2e44457b530d5a170 upstream. kobject_init_and_add() takes reference even when it fails. If this function returns an error, kobject_put() must be called to properly clean up the memory associated with the object. Previous commit "b8eb718348b8" fixed a similar problem. Fixes: 158c998ea44b ("ACPI / CPPC: add sysfs support to compute delivered performance") Signed-off-by: Qiushi Wu Cc: 4.10+ # 4.10+ Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/cppc_acpi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 9ec4618df533..318bdfb8703c 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -793,8 +793,10 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) ret = kobject_init_and_add(&cpc_ptr->kobj, &cppc_ktype, &cpu_dev->kobj, "acpi_cppc"); - if (ret) + if (ret) { + kobject_put(&cpc_ptr->kobj); goto out_free; + } kfree(output.pointer); return 0; From ac0a27243228c1f867873c90160881292241e483 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Fri, 15 May 2020 11:36:13 +0200 Subject: [PATCH 276/387] ACPI: GED: add support for _Exx / _Lxx handler methods commit ea6f3af4c5e63f6981c0b0ab8ebec438e2d5ef40 upstream. Per the ACPI spec, interrupts in the range [0, 255] may be handled in AML using individual methods whose naming is based on the format _Exx or _Lxx, where xx is the hex representation of the interrupt index. Add support for this missing feature to our ACPI GED driver. Cc: v4.9+ # v4.9+ Signed-off-by: Ard Biesheuvel Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/evged.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/evged.c b/drivers/acpi/evged.c index 46f060356a22..385e98bf7bd0 100644 --- a/drivers/acpi/evged.c +++ b/drivers/acpi/evged.c @@ -82,6 +82,8 @@ static acpi_status acpi_ged_request_interrupt(struct acpi_resource *ares, struct resource r; struct acpi_resource_irq *p = &ares->data.irq; struct acpi_resource_extended_irq *pext = &ares->data.extended_irq; + char ev_name[5]; + u8 trigger; if (ares->type == ACPI_RESOURCE_TYPE_END_TAG) return AE_OK; @@ -90,14 +92,28 @@ static acpi_status acpi_ged_request_interrupt(struct acpi_resource *ares, dev_err(dev, "unable to parse IRQ resource\n"); return AE_ERROR; } - if (ares->type == ACPI_RESOURCE_TYPE_IRQ) + if (ares->type == ACPI_RESOURCE_TYPE_IRQ) { gsi = p->interrupts[0]; - else + trigger = p->triggering; + } else { gsi = pext->interrupts[0]; + trigger = p->triggering; + } irq = r.start; - if (ACPI_FAILURE(acpi_get_handle(handle, "_EVT", &evt_handle))) { + switch (gsi) { + case 0 ... 255: + sprintf(ev_name, "_%c%02hhX", + trigger == ACPI_EDGE_SENSITIVE ? 'E' : 'L', gsi); + + if (ACPI_SUCCESS(acpi_get_handle(handle, ev_name, &evt_handle))) + break; + /* fall through */ + default: + if (ACPI_SUCCESS(acpi_get_handle(handle, "_EVT", &evt_handle))) + break; + dev_err(dev, "cannot locate _EVT method\n"); return AE_ERROR; } From 744aa65957cf5aa8b040246d7036c56f0a50a46f Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 4 Jun 2020 19:22:26 +0200 Subject: [PATCH 277/387] ACPI: PM: Avoid using power resources if there are none for D0 commit 956ad9d98b73f59e442cc119c98ba1e04e94fe6d upstream. As recently reported, some platforms provide a list of power resources for device power state D3hot, through the _PR3 object, but they do not provide a list of power resources for device power state D0. Among other things, this causes acpi_device_get_power() to return D3hot as the current state of the device in question if all of the D3hot power resources are "on", because it sees the power_resources flag set and calls acpi_power_get_inferred_state() which finds that D3hot is the shallowest power state with all of the associated power resources turned "on", so that's what it returns. Moreover, that value takes precedence over the acpi_dev_pm_explicit_get() return value, because it means a deeper power state. The device may very well be in D0 physically at that point, however. Moreover, the presence of _PR3 without _PR0 for a given device means that only one D3-level power state can be supported by it. Namely, because there are no power resources to turn "off" when transitioning the device from D0 into D3cold (which should be supported since _PR3 is present), the evaluation of _PS3 should be sufficient to put it straight into D3cold, but this means that the effect of turning "on" the _PR3 power resources is unclear, so it is better to avoid doing that altogether. Consequently, there is no practical way do distinguish D3cold from D3hot for the device in question and the power states of it can be labeled so that D3hot is the deepest supported one (and Linux assumes that putting a device into D3hot via ACPI may cause power to be removed from it anyway, for legacy reasons). To work around the problem described above modify the ACPI enumeration of devices so that power resources are only used for device power management if the list of D0 power resources is not empty and make it mart D3cold as supported only if that is the case and the D3hot list of power resources is not empty too. Fixes: ef85bdbec444 ("ACPI / scan: Consolidate extraction of power resources lists") Link: https://bugzilla.kernel.org/show_bug.cgi?id=205057 Link: https://lore.kernel.org/linux-acpi/20200603194659.185757-1-hdegoede@redhat.com/ Reported-by: Hans de Goede Tested-by: Hans de Goede Tested-by: youling257@gmail.com Cc: 3.10+ # 3.10+ Signed-off-by: Rafael J. Wysocki Reviewed-by: Hans de Goede Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/device_pm.c | 2 +- drivers/acpi/scan.c | 28 +++++++++++++++++++--------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 245bcdb44c64..442aac84ab88 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -171,7 +171,7 @@ int acpi_device_set_power(struct acpi_device *device, int state) * possibly drop references to the power resources in use. */ state = ACPI_STATE_D3_HOT; - /* If _PR3 is not available, use D3hot as the target state. */ + /* If D3cold is not supported, use D3hot as the target state. */ if (!device->power.states[ACPI_STATE_D3_COLD].flags.valid) target_state = state; } else if (!device->power.states[state].flags.valid) { diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 0792ec5a9efc..9a7f017dda47 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -927,12 +927,9 @@ static void acpi_bus_init_power_state(struct acpi_device *device, int state) if (buffer.length && package && package->type == ACPI_TYPE_PACKAGE - && package->package.count) { - int err = acpi_extract_power_resources(package, 0, - &ps->resources); - if (!err) - device->power.flags.power_resources = 1; - } + && package->package.count) + acpi_extract_power_resources(package, 0, &ps->resources); + ACPI_FREE(buffer.pointer); } @@ -979,14 +976,27 @@ static void acpi_bus_get_power_flags(struct acpi_device *device) acpi_bus_init_power_state(device, i); INIT_LIST_HEAD(&device->power.states[ACPI_STATE_D3_COLD].resources); - if (!list_empty(&device->power.states[ACPI_STATE_D3_HOT].resources)) - device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1; - /* Set defaults for D0 and D3hot states (always valid) */ + /* Set the defaults for D0 and D3hot (always supported). */ device->power.states[ACPI_STATE_D0].flags.valid = 1; device->power.states[ACPI_STATE_D0].power = 100; device->power.states[ACPI_STATE_D3_HOT].flags.valid = 1; + /* + * Use power resources only if the D0 list of them is populated, because + * some platforms may provide _PR3 only to indicate D3cold support and + * in those cases the power resources list returned by it may be bogus. + */ + if (!list_empty(&device->power.states[ACPI_STATE_D0].resources)) { + device->power.flags.power_resources = 1; + /* + * D3cold is supported if the D3hot list of power resources is + * not empty. + */ + if (!list_empty(&device->power.states[ACPI_STATE_D3_HOT].resources)) + device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1; + } + if (acpi_bus_init_power(device)) device->flags.power_manageable = 0; } From d4341f4655811a2b6540f990e08209b1e47963d7 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 27 Jun 2019 13:39:48 -0700 Subject: [PATCH 278/387] cgroup, blkcg: Prepare some symbols for module and !CONFIG_CGROUP usages commit 9b0eb69b75bccada2d341d7e7ca342f0cb1c9a6a upstream. btrfs is going to use css_put() and wbc helpers to improve cgroup writeback support. Add dummy css_get() definition and export wbc helpers to prepare for module and !CONFIG_CGROUP builds. [only backport the export of __inode_attach_wb for stable kernels - gregkh] Reported-by: kbuild test robot Reviewed-by: Jan Kara Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- fs/fs-writeback.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 882e9d6830df..5a1a6dbbc55f 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -269,6 +269,7 @@ void __inode_attach_wb(struct inode *inode, struct page *page) if (unlikely(cmpxchg(&inode->i_wb, NULL, wb))) wb_put(wb); } +EXPORT_SYMBOL_GPL(__inode_attach_wb); /** * locked_inode_to_wb_and_lock_list - determine a locked inode's wb and lock it From 0b23abc6de626360b19b4e579ff6b8e3c0c57abe Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Wed, 10 Jun 2020 18:41:35 -0700 Subject: [PATCH 279/387] nilfs2: fix null pointer dereference at nilfs_segctor_do_construct() commit 8301c719a2bd131436438e49130ee381d30933f5 upstream. After commit c3aab9a0bd91 ("mm/filemap.c: don't initiate writeback if mapping has no dirty pages"), the following null pointer dereference has been reported on nilfs2: BUG: kernel NULL pointer dereference, address: 00000000000000a8 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 0 P4D 0 Oops: 0000 [#1] SMP PTI ... RIP: 0010:percpu_counter_add_batch+0xa/0x60 ... Call Trace: __test_set_page_writeback+0x2d3/0x330 nilfs_segctor_do_construct+0x10d3/0x2110 [nilfs2] nilfs_segctor_construct+0x168/0x260 [nilfs2] nilfs_segctor_thread+0x127/0x3b0 [nilfs2] kthread+0xf8/0x130 ... This crash turned out to be caused by set_page_writeback() call for segment summary buffers at nilfs_segctor_prepare_write(). set_page_writeback() can call inc_wb_stat(inode_to_wb(inode), WB_WRITEBACK) where inode_to_wb(inode) is NULL if the inode of underlying block device does not have an associated wb. This fixes the issue by calling inode_attach_wb() in advance to ensure to associate the bdev inode with its wb. Fixes: c3aab9a0bd91 ("mm/filemap.c: don't initiate writeback if mapping has no dirty pages") Reported-by: Walton Hoops Reported-by: Tomas Hlavaty Reported-by: ARAI Shun-ichi Reported-by: Hideki EIRAKU Signed-off-by: Ryusuke Konishi Signed-off-by: Andrew Morton Tested-by: Ryusuke Konishi Cc: [5.4+] Link: http://lkml.kernel.org/r/20200608.011819.1399059588922299158.konishi.ryusuke@gmail.com Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- fs/nilfs2/segment.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index 36362d4bc344..a92af0ed0e28 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c @@ -2793,6 +2793,8 @@ int nilfs_attach_log_writer(struct super_block *sb, struct nilfs_root *root) if (!nilfs->ns_writer) return -ENOMEM; + inode_attach_wb(nilfs->ns_bdev->bd_inode, NULL); + err = nilfs_segctor_start_thread(nilfs->ns_writer); if (err) { kfree(nilfs->ns_writer); From 639cd86bdadeb83ed603fd6556a64d61189622ec Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Fri, 15 May 2020 17:58:03 +0200 Subject: [PATCH 280/387] spi: bcm2835aux: Fix controller unregister order commit b9dd3f6d417258ad0beeb292a1bc74200149f15d upstream. The BCM2835aux SPI driver uses devm_spi_register_master() on bind. As a consequence, on unbind, __device_release_driver() first invokes bcm2835aux_spi_remove() before unregistering the SPI controller via devres_release_all(). This order is incorrect: bcm2835aux_spi_remove() turns off the SPI controller, including its interrupts and clock. The SPI controller is thus no longer usable. When the SPI controller is subsequently unregistered, it unbinds all its slave devices. If their drivers need to access the SPI bus, e.g. to quiesce their interrupts, unbinding will fail. As a rule, devm_spi_register_master() must not be used if the ->remove() hook performs teardown steps which shall be performed after unbinding of slaves. Fix by using the non-devm variant spi_register_master(). Note that the struct spi_master as well as the driver-private data are not freed until after bcm2835aux_spi_remove() has finished, so accessing them is safe. Fixes: 1ea29b39f4c8 ("spi: bcm2835aux: add bcm2835 auxiliary spi device driver") Signed-off-by: Lukas Wunner Cc: stable@vger.kernel.org # v4.4+ Cc: Martin Sperl Link: https://lore.kernel.org/r/32f27f4d8242e4d75f9a53f7e8f1f77483b08669.1589557526.git.lukas@wunner.de Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- drivers/spi/spi-bcm2835aux.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-bcm2835aux.c b/drivers/spi/spi-bcm2835aux.c index e075712c501e..b7f78e6d9bec 100644 --- a/drivers/spi/spi-bcm2835aux.c +++ b/drivers/spi/spi-bcm2835aux.c @@ -485,7 +485,7 @@ static int bcm2835aux_spi_probe(struct platform_device *pdev) goto out_clk_disable; } - err = devm_spi_register_master(&pdev->dev, master); + err = spi_register_master(master); if (err) { dev_err(&pdev->dev, "could not register SPI master: %d\n", err); goto out_clk_disable; @@ -505,6 +505,8 @@ static int bcm2835aux_spi_remove(struct platform_device *pdev) struct spi_master *master = platform_get_drvdata(pdev); struct bcm2835aux_spi *bs = spi_master_get_devdata(master); + spi_unregister_master(master); + bcm2835aux_spi_reset_hw(bs); /* disable the HW block by releasing the clock */ From 855995d68e9a5c9e633ca6eaf58b3eedae966ab6 Mon Sep 17 00:00:00 2001 From: Justin Chen Date: Mon, 20 Apr 2020 15:08:49 -0400 Subject: [PATCH 281/387] spi: bcm-qspi: when tx/rx buffer is NULL set to 0 commit 4df3bea7f9d2ddd9ac2c29ba945c7c4db2def29c upstream. Currently we set the tx/rx buffer to 0xff when NULL. This causes problems with some spi slaves where 0xff is a valid command. Looking at other drivers, the tx/rx buffer is usually set to 0x00 when NULL. Following this convention solves the issue. Fixes: fa236a7ef240 ("spi: bcm-qspi: Add Broadcom MSPI driver") Signed-off-by: Justin Chen Signed-off-by: Kamal Dasu Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20200420190853.45614-6-kdasu.kdev@gmail.com Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- drivers/spi/spi-bcm-qspi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c index 63231760facc..1906b2319e5b 100644 --- a/drivers/spi/spi-bcm-qspi.c +++ b/drivers/spi/spi-bcm-qspi.c @@ -698,7 +698,7 @@ static void read_from_hw(struct bcm_qspi *qspi, int slots) if (buf) buf[tp.byte] = read_rxram_slot_u8(qspi, slot); dev_dbg(&qspi->pdev->dev, "RD %02x\n", - buf ? buf[tp.byte] : 0xff); + buf ? buf[tp.byte] : 0x0); } else { u16 *buf = tp.trans->rx_buf; @@ -706,7 +706,7 @@ static void read_from_hw(struct bcm_qspi *qspi, int slots) buf[tp.byte / 2] = read_rxram_slot_u16(qspi, slot); dev_dbg(&qspi->pdev->dev, "RD %04x\n", - buf ? buf[tp.byte] : 0xffff); + buf ? buf[tp.byte / 2] : 0x0); } update_qspi_trans_byte_count(qspi, &tp, @@ -761,13 +761,13 @@ static int write_to_hw(struct bcm_qspi *qspi, struct spi_device *spi) while (!tstatus && slot < MSPI_NUM_CDRAM) { if (tp.trans->bits_per_word <= 8) { const u8 *buf = tp.trans->tx_buf; - u8 val = buf ? buf[tp.byte] : 0xff; + u8 val = buf ? buf[tp.byte] : 0x00; write_txram_slot_u8(qspi, slot, val); dev_dbg(&qspi->pdev->dev, "WR %02x\n", val); } else { const u16 *buf = tp.trans->tx_buf; - u16 val = buf ? buf[tp.byte / 2] : 0xffff; + u16 val = buf ? buf[tp.byte / 2] : 0x0000; write_txram_slot_u16(qspi, slot, val); dev_dbg(&qspi->pdev->dev, "WR %04x\n", val); From 496d422fcbd696e402aa0cac29851338d35b9f18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Mon, 8 Jun 2020 18:50:39 +0200 Subject: [PATCH 282/387] ALSA: pcm: disallow linking stream to itself MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 951e2736f4b11b58dc44d41964fa17c3527d882a upstream. Prevent SNDRV_PCM_IOCTL_LINK linking stream to itself - the code can't handle it. Fixed commit is not where bug was introduced, but changes the context significantly. Cc: stable@vger.kernel.org Fixes: 0888c321de70 ("pcm_native: switch to fdget()/fdput()") Signed-off-by: Michał Mirosław Link: https://lore.kernel.org/r/89c4a2487609a0ed6af3ecf01cc972bdc59a7a2d.1591634956.git.mirq-linux@rere.qmqm.pl Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/core/pcm_native.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 23e17a58651b..5c07c5be3142 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -1836,6 +1836,11 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd) } pcm_file = f.file->private_data; substream1 = pcm_file->substream; + if (substream == substream1) { + res = -EINVAL; + goto _badf; + } + group = kmalloc(sizeof(*group), GFP_KERNEL); if (!group) { res = -ENOMEM; From 669ce559aec775e9c26ace076d650e7bbb21e80a Mon Sep 17 00:00:00 2001 From: Waiman Long Date: Wed, 5 Dec 2018 14:49:27 -0500 Subject: [PATCH 283/387] x86/speculation: Change misspelled STIPB to STIBP [ Upstream commit aa77bfb354c495fc4361199e63fc5765b9e1e783 ] STIBP stands for Single Thread Indirect Branch Predictors. The acronym, however, can be easily mis-spelled as STIPB. It is perhaps due to the presence of another related term - IBPB (Indirect Branch Predictor Barrier). Fix the mis-spelling in the code. Signed-off-by: Waiman Long Signed-off-by: Borislav Petkov Cc: "H. Peter Anvin" Cc: Andi Kleen Cc: David Woodhouse Cc: Ingo Molnar Cc: Jiri Kosina Cc: Josh Poimboeuf Cc: KarimAllah Ahmed Cc: Konrad Rzeszutek Wilk Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Tim Chen Cc: x86-ml Link: https://lkml.kernel.org/r/1544039368-9009-1-git-send-email-longman@redhat.com Signed-off-by: Sasha Levin --- arch/x86/kernel/cpu/bugs.c | 6 +++--- arch/x86/kernel/process.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 5ef0a2b34261..704ffc01a226 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -60,7 +60,7 @@ static u64 __ro_after_init x86_spec_ctrl_mask = SPEC_CTRL_IBRS; u64 __ro_after_init x86_amd_ls_cfg_base; u64 __ro_after_init x86_amd_ls_cfg_ssbd_mask; -/* Control conditional STIPB in switch_to() */ +/* Control conditional STIBP in switch_to() */ DEFINE_STATIC_KEY_FALSE(switch_to_cond_stibp); /* Control conditional IBPB in switch_mm() */ DEFINE_STATIC_KEY_FALSE(switch_mm_cond_ibpb); @@ -749,12 +749,12 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd) "always-on" : "conditional"); } - /* If enhanced IBRS is enabled no STIPB required */ + /* If enhanced IBRS is enabled no STIBP required */ if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED) return; /* - * If SMT is not possible or STIBP is not available clear the STIPB + * If SMT is not possible or STIBP is not available clear the STIBP * mode. */ if (!smt_possible || !boot_cpu_has(X86_FEATURE_STIBP)) diff --git a/arch/x86/kernel/process.h b/arch/x86/kernel/process.h index 898e97cf6629..320ab978fb1f 100644 --- a/arch/x86/kernel/process.h +++ b/arch/x86/kernel/process.h @@ -19,7 +19,7 @@ static inline void switch_to_extra(struct task_struct *prev, if (IS_ENABLED(CONFIG_SMP)) { /* * Avoid __switch_to_xtra() invocation when conditional - * STIPB is disabled and the only different bit is + * STIBP is disabled and the only different bit is * TIF_SPEC_IB. For CONFIG_SMP=n TIF_SPEC_IB is not * in the TIF_WORK_CTXSW masks. */ From 5eaa7ef6506313ca424292ae9f1b8e50c54e6488 Mon Sep 17 00:00:00 2001 From: Thomas Lendacky Date: Thu, 13 Dec 2018 23:03:54 +0000 Subject: [PATCH 284/387] x86/speculation: Add support for STIBP always-on preferred mode [ Upstream commit 20c3a2c33e9fdc82e9e8e8d2a6445b3256d20191 ] Different AMD processors may have different implementations of STIBP. When STIBP is conditionally enabled, some implementations would benefit from having STIBP always on instead of toggling the STIBP bit through MSR writes. This preference is advertised through a CPUID feature bit. When conditional STIBP support is requested at boot and the CPU advertises STIBP always-on mode as preferred, switch to STIBP "on" support. To show that this transition has occurred, create a new spectre_v2_user_mitigation value and a new spectre_v2_user_strings message. The new mitigation value is used in spectre_v2_user_select_mitigation() to print the new mitigation message as well as to return a new string from stibp_state(). Signed-off-by: Tom Lendacky Signed-off-by: Thomas Gleixner Cc: Andrea Arcangeli Cc: Konrad Rzeszutek Wilk Cc: Jiri Kosina Cc: Borislav Petkov Cc: Tim Chen Cc: David Woodhouse Link: https://lkml.kernel.org/r/20181213230352.6937.74943.stgit@tlendack-t1.amdoffice.net Signed-off-by: Sasha Levin --- arch/x86/include/asm/cpufeatures.h | 2 +- arch/x86/include/asm/nospec-branch.h | 1 + arch/x86/kernel/cpu/bugs.c | 28 ++++++++++++++++++++++------ 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h index 2cd5d12a842c..8ceb7a8a249c 100644 --- a/arch/x86/include/asm/cpufeatures.h +++ b/arch/x86/include/asm/cpufeatures.h @@ -273,6 +273,7 @@ #define X86_FEATURE_AMD_IBPB (13*32+12) /* "" Indirect Branch Prediction Barrier */ #define X86_FEATURE_AMD_IBRS (13*32+14) /* "" Indirect Branch Restricted Speculation */ #define X86_FEATURE_AMD_STIBP (13*32+15) /* "" Single Thread Indirect Branch Predictors */ +#define X86_FEATURE_AMD_STIBP_ALWAYS_ON (13*32+17) /* "" Single Thread Indirect Branch Predictors always-on preferred */ #define X86_FEATURE_AMD_SSBD (13*32+24) /* "" Speculative Store Bypass Disable */ #define X86_FEATURE_VIRT_SSBD (13*32+25) /* Virtualized Speculative Store Bypass Disable */ #define X86_FEATURE_AMD_SSB_NO (13*32+26) /* "" Speculative Store Bypass is fixed in hardware. */ @@ -312,7 +313,6 @@ #define X86_FEATURE_SUCCOR (17*32+1) /* Uncorrectable error containment and recovery */ #define X86_FEATURE_SMCA (17*32+3) /* Scalable MCA */ - /* Intel-defined CPU features, CPUID level 0x00000007:0 (EDX), word 18 */ #define X86_FEATURE_AVX512_4VNNIW (18*32+ 2) /* AVX-512 Neural Network Instructions */ #define X86_FEATURE_AVX512_4FMAPS (18*32+ 3) /* AVX-512 Multiply Accumulation Single precision */ diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h index 8d56d701b5f7..4af16acc001a 100644 --- a/arch/x86/include/asm/nospec-branch.h +++ b/arch/x86/include/asm/nospec-branch.h @@ -223,6 +223,7 @@ enum spectre_v2_mitigation { enum spectre_v2_user_mitigation { SPECTRE_V2_USER_NONE, SPECTRE_V2_USER_STRICT, + SPECTRE_V2_USER_STRICT_PREFERRED, SPECTRE_V2_USER_PRCTL, SPECTRE_V2_USER_SECCOMP, }; diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 704ffc01a226..82549060b824 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -632,10 +632,11 @@ enum spectre_v2_user_cmd { }; static const char * const spectre_v2_user_strings[] = { - [SPECTRE_V2_USER_NONE] = "User space: Vulnerable", - [SPECTRE_V2_USER_STRICT] = "User space: Mitigation: STIBP protection", - [SPECTRE_V2_USER_PRCTL] = "User space: Mitigation: STIBP via prctl", - [SPECTRE_V2_USER_SECCOMP] = "User space: Mitigation: STIBP via seccomp and prctl", + [SPECTRE_V2_USER_NONE] = "User space: Vulnerable", + [SPECTRE_V2_USER_STRICT] = "User space: Mitigation: STIBP protection", + [SPECTRE_V2_USER_STRICT_PREFERRED] = "User space: Mitigation: STIBP always-on protection", + [SPECTRE_V2_USER_PRCTL] = "User space: Mitigation: STIBP via prctl", + [SPECTRE_V2_USER_SECCOMP] = "User space: Mitigation: STIBP via seccomp and prctl", }; static const struct { @@ -725,6 +726,15 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd) break; } + /* + * At this point, an STIBP mode other than "off" has been set. + * If STIBP support is not being forced, check if STIBP always-on + * is preferred. + */ + if (mode != SPECTRE_V2_USER_STRICT && + boot_cpu_has(X86_FEATURE_AMD_STIBP_ALWAYS_ON)) + mode = SPECTRE_V2_USER_STRICT_PREFERRED; + /* Initialize Indirect Branch Prediction Barrier */ if (boot_cpu_has(X86_FEATURE_IBPB)) { setup_force_cpu_cap(X86_FEATURE_USE_IBPB); @@ -1007,6 +1017,7 @@ void arch_smt_update(void) case SPECTRE_V2_USER_NONE: break; case SPECTRE_V2_USER_STRICT: + case SPECTRE_V2_USER_STRICT_PREFERRED: update_stibp_strict(); break; case SPECTRE_V2_USER_PRCTL: @@ -1241,7 +1252,8 @@ static int ib_prctl_set(struct task_struct *task, unsigned long ctrl) * Indirect branch speculation is always disabled in strict * mode. */ - if (spectre_v2_user == SPECTRE_V2_USER_STRICT) + if (spectre_v2_user == SPECTRE_V2_USER_STRICT || + spectre_v2_user == SPECTRE_V2_USER_STRICT_PREFERRED) return -EPERM; task_clear_spec_ib_disable(task); task_update_spec_tif(task); @@ -1254,7 +1266,8 @@ static int ib_prctl_set(struct task_struct *task, unsigned long ctrl) */ if (spectre_v2_user == SPECTRE_V2_USER_NONE) return -EPERM; - if (spectre_v2_user == SPECTRE_V2_USER_STRICT) + if (spectre_v2_user == SPECTRE_V2_USER_STRICT || + spectre_v2_user == SPECTRE_V2_USER_STRICT_PREFERRED) return 0; task_set_spec_ib_disable(task); if (ctrl == PR_SPEC_FORCE_DISABLE) @@ -1325,6 +1338,7 @@ static int ib_prctl_get(struct task_struct *task) return PR_SPEC_PRCTL | PR_SPEC_DISABLE; return PR_SPEC_PRCTL | PR_SPEC_ENABLE; case SPECTRE_V2_USER_STRICT: + case SPECTRE_V2_USER_STRICT_PREFERRED: return PR_SPEC_DISABLE; default: return PR_SPEC_NOT_AFFECTED; @@ -1574,6 +1588,8 @@ static char *stibp_state(void) return ", STIBP: disabled"; case SPECTRE_V2_USER_STRICT: return ", STIBP: forced"; + case SPECTRE_V2_USER_STRICT_PREFERRED: + return ", STIBP: always-on"; case SPECTRE_V2_USER_PRCTL: case SPECTRE_V2_USER_SECCOMP: if (static_key_enabled(&switch_to_cond_stibp)) From 38be87f5e7a7a7378d4ef4528c13bd1d666ab867 Mon Sep 17 00:00:00 2001 From: Anthony Steinhauser Date: Tue, 19 May 2020 06:40:42 -0700 Subject: [PATCH 285/387] x86/speculation: Avoid force-disabling IBPB based on STIBP and enhanced IBRS. [ Upstream commit 21998a351512eba4ed5969006f0c55882d995ada ] When STIBP is unavailable or enhanced IBRS is available, Linux force-disables the IBPB mitigation of Spectre-BTB even when simultaneous multithreading is disabled. While attempts to enable IBPB using prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, ...) fail with EPERM, the seccomp syscall (or its prctl(PR_SET_SECCOMP, ...) equivalent) which are used e.g. by Chromium or OpenSSH succeed with no errors but the application remains silently vulnerable to cross-process Spectre v2 attacks (classical BTB poisoning). At the same time the SYSFS reporting (/sys/devices/system/cpu/vulnerabilities/spectre_v2) displays that IBPB is conditionally enabled when in fact it is unconditionally disabled. STIBP is useful only when SMT is enabled. When SMT is disabled and STIBP is unavailable, it makes no sense to force-disable also IBPB, because IBPB protects against cross-process Spectre-BTB attacks regardless of the SMT state. At the same time since missing STIBP was only observed on AMD CPUs, AMD does not recommend using STIBP, but recommends using IBPB, so disabling IBPB because of missing STIBP goes directly against AMD's advice: https://developer.amd.com/wp-content/resources/Architecture_Guidelines_Update_Indirect_Branch_Control.pdf Similarly, enhanced IBRS is designed to protect cross-core BTB poisoning and BTB-poisoning attacks from user space against kernel (and BTB-poisoning attacks from guest against hypervisor), it is not designed to prevent cross-process (or cross-VM) BTB poisoning between processes (or VMs) running on the same core. Therefore, even with enhanced IBRS it is necessary to flush the BTB during context-switches, so there is no reason to force disable IBPB when enhanced IBRS is available. Enable the prctl control of IBPB even when STIBP is unavailable or enhanced IBRS is available. Fixes: 7cc765a67d8e ("x86/speculation: Enable prctl mode for spectre_v2_user") Signed-off-by: Anthony Steinhauser Signed-off-by: Thomas Gleixner Cc: stable@vger.kernel.org Signed-off-by: Sasha Levin --- arch/x86/kernel/cpu/bugs.c | 87 ++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 37 deletions(-) diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 82549060b824..2ab65f0ec56d 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -580,7 +580,9 @@ early_param("nospectre_v1", nospectre_v1_cmdline); static enum spectre_v2_mitigation spectre_v2_enabled __ro_after_init = SPECTRE_V2_NONE; -static enum spectre_v2_user_mitigation spectre_v2_user __ro_after_init = +static enum spectre_v2_user_mitigation spectre_v2_user_stibp __ro_after_init = + SPECTRE_V2_USER_NONE; +static enum spectre_v2_user_mitigation spectre_v2_user_ibpb __ro_after_init = SPECTRE_V2_USER_NONE; #ifdef RETPOLINE @@ -726,15 +728,6 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd) break; } - /* - * At this point, an STIBP mode other than "off" has been set. - * If STIBP support is not being forced, check if STIBP always-on - * is preferred. - */ - if (mode != SPECTRE_V2_USER_STRICT && - boot_cpu_has(X86_FEATURE_AMD_STIBP_ALWAYS_ON)) - mode = SPECTRE_V2_USER_STRICT_PREFERRED; - /* Initialize Indirect Branch Prediction Barrier */ if (boot_cpu_has(X86_FEATURE_IBPB)) { setup_force_cpu_cap(X86_FEATURE_USE_IBPB); @@ -757,23 +750,36 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd) pr_info("mitigation: Enabling %s Indirect Branch Prediction Barrier\n", static_key_enabled(&switch_mm_always_ibpb) ? "always-on" : "conditional"); + + spectre_v2_user_ibpb = mode; } - /* If enhanced IBRS is enabled no STIBP required */ - if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED) + /* + * If enhanced IBRS is enabled or SMT impossible, STIBP is not + * required. + */ + if (!smt_possible || spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED) return; /* - * If SMT is not possible or STIBP is not available clear the STIBP - * mode. + * At this point, an STIBP mode other than "off" has been set. + * If STIBP support is not being forced, check if STIBP always-on + * is preferred. */ - if (!smt_possible || !boot_cpu_has(X86_FEATURE_STIBP)) + if (mode != SPECTRE_V2_USER_STRICT && + boot_cpu_has(X86_FEATURE_AMD_STIBP_ALWAYS_ON)) + mode = SPECTRE_V2_USER_STRICT_PREFERRED; + + /* + * If STIBP is not available, clear the STIBP mode. + */ + if (!boot_cpu_has(X86_FEATURE_STIBP)) mode = SPECTRE_V2_USER_NONE; + + spectre_v2_user_stibp = mode; + set_mode: - spectre_v2_user = mode; - /* Only print the STIBP mode when SMT possible */ - if (smt_possible) - pr_info("%s\n", spectre_v2_user_strings[mode]); + pr_info("%s\n", spectre_v2_user_strings[mode]); } static const char * const spectre_v2_strings[] = { @@ -1013,7 +1019,7 @@ void arch_smt_update(void) { mutex_lock(&spec_ctrl_mutex); - switch (spectre_v2_user) { + switch (spectre_v2_user_stibp) { case SPECTRE_V2_USER_NONE: break; case SPECTRE_V2_USER_STRICT: @@ -1246,14 +1252,16 @@ static int ib_prctl_set(struct task_struct *task, unsigned long ctrl) { switch (ctrl) { case PR_SPEC_ENABLE: - if (spectre_v2_user == SPECTRE_V2_USER_NONE) + if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE && + spectre_v2_user_stibp == SPECTRE_V2_USER_NONE) return 0; /* * Indirect branch speculation is always disabled in strict * mode. */ - if (spectre_v2_user == SPECTRE_V2_USER_STRICT || - spectre_v2_user == SPECTRE_V2_USER_STRICT_PREFERRED) + if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT || + spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT || + spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED) return -EPERM; task_clear_spec_ib_disable(task); task_update_spec_tif(task); @@ -1264,10 +1272,12 @@ static int ib_prctl_set(struct task_struct *task, unsigned long ctrl) * Indirect branch speculation is always allowed when * mitigation is force disabled. */ - if (spectre_v2_user == SPECTRE_V2_USER_NONE) + if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE && + spectre_v2_user_stibp == SPECTRE_V2_USER_NONE) return -EPERM; - if (spectre_v2_user == SPECTRE_V2_USER_STRICT || - spectre_v2_user == SPECTRE_V2_USER_STRICT_PREFERRED) + if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT || + spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT || + spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED) return 0; task_set_spec_ib_disable(task); if (ctrl == PR_SPEC_FORCE_DISABLE) @@ -1298,7 +1308,8 @@ void arch_seccomp_spec_mitigate(struct task_struct *task) { if (ssb_mode == SPEC_STORE_BYPASS_SECCOMP) ssb_prctl_set(task, PR_SPEC_FORCE_DISABLE); - if (spectre_v2_user == SPECTRE_V2_USER_SECCOMP) + if (spectre_v2_user_ibpb == SPECTRE_V2_USER_SECCOMP || + spectre_v2_user_stibp == SPECTRE_V2_USER_SECCOMP) ib_prctl_set(task, PR_SPEC_FORCE_DISABLE); } #endif @@ -1327,22 +1338,24 @@ static int ib_prctl_get(struct task_struct *task) if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2)) return PR_SPEC_NOT_AFFECTED; - switch (spectre_v2_user) { - case SPECTRE_V2_USER_NONE: + if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE && + spectre_v2_user_stibp == SPECTRE_V2_USER_NONE) return PR_SPEC_ENABLE; - case SPECTRE_V2_USER_PRCTL: - case SPECTRE_V2_USER_SECCOMP: + else if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT || + spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT || + spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED) + return PR_SPEC_DISABLE; + else if (spectre_v2_user_ibpb == SPECTRE_V2_USER_PRCTL || + spectre_v2_user_ibpb == SPECTRE_V2_USER_SECCOMP || + spectre_v2_user_stibp == SPECTRE_V2_USER_PRCTL || + spectre_v2_user_stibp == SPECTRE_V2_USER_SECCOMP) { if (task_spec_ib_force_disable(task)) return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE; if (task_spec_ib_disable(task)) return PR_SPEC_PRCTL | PR_SPEC_DISABLE; return PR_SPEC_PRCTL | PR_SPEC_ENABLE; - case SPECTRE_V2_USER_STRICT: - case SPECTRE_V2_USER_STRICT_PREFERRED: - return PR_SPEC_DISABLE; - default: + } else return PR_SPEC_NOT_AFFECTED; - } } int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which) @@ -1583,7 +1596,7 @@ static char *stibp_state(void) if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED) return ""; - switch (spectre_v2_user) { + switch (spectre_v2_user_stibp) { case SPECTRE_V2_USER_NONE: return ", STIBP: disabled"; case SPECTRE_V2_USER_STRICT: From db39004352a40107213a70dc8e549936a6468fa9 Mon Sep 17 00:00:00 2001 From: Anthony Steinhauser Date: Sun, 7 Jun 2020 05:44:19 -0700 Subject: [PATCH 286/387] x86/speculation: PR_SPEC_FORCE_DISABLE enforcement for indirect branches. [ Upstream commit 4d8df8cbb9156b0a0ab3f802b80cb5db57acc0bf ] Currently, it is possible to enable indirect branch speculation even after it was force-disabled using the PR_SPEC_FORCE_DISABLE option. Moreover, the PR_GET_SPECULATION_CTRL command gives afterwards an incorrect result (force-disabled when it is in fact enabled). This also is inconsistent vs. STIBP and the documention which cleary states that PR_SPEC_FORCE_DISABLE cannot be undone. Fix this by actually enforcing force-disabled indirect branch speculation. PR_SPEC_ENABLE called after PR_SPEC_FORCE_DISABLE now fails with -EPERM as described in the documentation. Fixes: 9137bb27e60e ("x86/speculation: Add prctl() control for indirect branch speculation") Signed-off-by: Anthony Steinhauser Signed-off-by: Thomas Gleixner Cc: stable@vger.kernel.org Signed-off-by: Sasha Levin --- arch/x86/kernel/cpu/bugs.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 2ab65f0ec56d..85c1cc0305f3 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -1257,11 +1257,14 @@ static int ib_prctl_set(struct task_struct *task, unsigned long ctrl) return 0; /* * Indirect branch speculation is always disabled in strict - * mode. + * mode. It can neither be enabled if it was force-disabled + * by a previous prctl call. + */ if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT || spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT || - spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED) + spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED || + task_spec_ib_force_disable(task)) return -EPERM; task_clear_spec_ib_disable(task); task_update_spec_tif(task); From 79645f0e85c4986eb9bbcdc577030502c826e397 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Mon, 15 Jun 2020 17:28:08 -0400 Subject: [PATCH 287/387] spi: dw: fix possible race condition [ Upstream commit 66b19d762378785d1568b5650935205edfeb0503 ] It is possible to get an interrupt as soon as it is requested. dw_spi_irq does spi_controller_get_devdata(master) and expects it to be different than NULL. However, spi_controller_set_devdata() is called after request_irq(), resulting in the following crash: CPU 0 Unable to handle kernel paging request at virtual address 00000030, epc == 8058e09c, ra == 8018ff90 [...] Call Trace: [<8058e09c>] dw_spi_irq+0x8/0x64 [<8018ff90>] __handle_irq_event_percpu+0x70/0x1d4 [<80190128>] handle_irq_event_percpu+0x34/0x8c [<801901c4>] handle_irq_event+0x44/0x80 [<801951a8>] handle_level_irq+0xdc/0x194 [<8018f580>] generic_handle_irq+0x38/0x50 [<804c6924>] ocelot_irq_handler+0x104/0x1c0 Signed-off-by: Alexandre Belloni Reviewed-by: Andy Shevchenko Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-dw.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index babf0a337e96..be3ab4006313 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -500,6 +500,8 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) snprintf(dws->name, sizeof(dws->name), "dw_spi%d", dws->bus_num); spin_lock_init(&dws->buf_lock); + spi_master_set_devdata(master, dws); + ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, dws->name, master); if (ret < 0) { dev_err(dev, "can not get IRQ\n"); @@ -531,7 +533,6 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) } } - spi_master_set_devdata(master, dws); ret = devm_spi_register_master(dev, master); if (ret) { dev_err(&master->dev, "problem registering spi master\n"); From 35654d44a5f15449000a91a47b4769ea6572e028 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Mon, 25 May 2020 14:25:01 +0200 Subject: [PATCH 288/387] spi: dw: Fix controller unregister order [ Upstream commit ca8b19d61e3fce5d2d7790cde27a0b57bcb3f341 ] The Designware SPI driver uses devm_spi_register_controller() on bind. As a consequence, on unbind, __device_release_driver() first invokes dw_spi_remove_host() before unregistering the SPI controller via devres_release_all(). This order is incorrect: dw_spi_remove_host() shuts down the chip, rendering the SPI bus inaccessible even though the SPI controller is still registered. When the SPI controller is subsequently unregistered, it unbinds all its slave devices. Because their drivers cannot access the SPI bus, e.g. to quiesce interrupts, the slave devices may be left in an improper state. As a rule, devm_spi_register_controller() must not be used if the ->remove() hook performs teardown steps which shall be performed after unregistering the controller and specifically after unbinding of slaves. Fix by reverting to the non-devm variant of spi_register_controller(). An alternative approach would be to use device-managed functions for all steps in dw_spi_remove_host(), e.g. by calling devm_add_action_or_reset() on probe. However that approach would add more LoC to the driver and it wouldn't lend itself as well to backporting to stable. Fixes: 04f421e7b0b1 ("spi: dw: use managed resources") Signed-off-by: Lukas Wunner Reviewed-by: Andy Shevchenko Cc: stable@vger.kernel.org # v3.14+ Cc: Baruch Siach Link: https://lore.kernel.org/r/3fff8cb8ae44a9893840d0688be15bb88c090a14.1590408496.git.lukas@wunner.de Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-dw.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index be3ab4006313..c5a2f369941c 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -533,7 +533,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) } } - ret = devm_spi_register_master(dev, master); + ret = spi_register_master(master); if (ret) { dev_err(&master->dev, "problem registering spi master\n"); goto err_dma_exit; @@ -557,6 +557,8 @@ void dw_spi_remove_host(struct dw_spi *dws) { dw_spi_debugfs_remove(dws); + spi_unregister_master(dws->master); + if (dws->dma_ops && dws->dma_ops->dma_exit) dws->dma_ops->dma_exit(dws); From 7bc16ca02b374b687f47044817c8ccdb89773b35 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Sat, 15 Jun 2019 20:41:35 +0300 Subject: [PATCH 289/387] spi: No need to assign dummy value in spi_unregister_controller() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit ebc37af5e0a134355ea2b62ed4141458bdbd5389 ] The device_for_each_child() doesn't require the returned value to be checked. Thus, drop the dummy variable completely and have no warning anymore: drivers/spi/spi.c: In function ‘spi_unregister_controller’: drivers/spi/spi.c:2480:6: warning: variable ‘dummy’ set but not used [-Wunused-but-set-variable] int dummy; ^~~~~ Signed-off-by: Andy Shevchenko Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index d74d341f9890..7fec76dd532f 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -2025,8 +2025,6 @@ static int __unregister(struct device *dev, void *null) */ void spi_unregister_master(struct spi_master *master) { - int dummy; - if (master->queued) { if (spi_destroy_queue(master)) dev_err(&master->dev, "queue remove failed\n"); @@ -2036,7 +2034,7 @@ void spi_unregister_master(struct spi_master *master) list_del(&master->list); mutex_unlock(&board_lock); - dummy = device_for_each_child(&master->dev, NULL, __unregister); + device_for_each_child(&master->dev, NULL, __unregister); device_unregister(&master->dev); } EXPORT_SYMBOL_GPL(spi_unregister_master); From c7e41e1caa713225f5f16f144cc0f8760a7a06c4 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Fri, 15 May 2020 17:58:01 +0200 Subject: [PATCH 290/387] spi: Fix controller unregister order [ Upstream commit 84855678add8aba927faf76bc2f130a40f94b6f7 ] When an SPI controller unregisters, it unbinds all its slave devices. For this, their drivers may need to access the SPI bus, e.g. to quiesce interrupts. However since commit ffbbdd21329f ("spi: create a message queueing infrastructure"), spi_destroy_queue() is executed before unbinding the slaves. It sets ctlr->running = false, thereby preventing SPI bus access and causing unbinding of slave devices to fail. Fix by unbinding slaves before calling spi_destroy_queue(). Fixes: ffbbdd21329f ("spi: create a message queueing infrastructure") Signed-off-by: Lukas Wunner Cc: stable@vger.kernel.org # v3.4+ Cc: Linus Walleij Link: https://lore.kernel.org/r/8aaf9d44c153fe233b17bc2dec4eb679898d7e7b.1589557526.git.lukas@wunner.de Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 7fec76dd532f..3fadc564d781 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -2030,11 +2030,12 @@ void spi_unregister_master(struct spi_master *master) dev_err(&master->dev, "queue remove failed\n"); } + device_for_each_child(&master->dev, NULL, __unregister); + mutex_lock(&board_lock); list_del(&master->list); mutex_unlock(&board_lock); - device_for_each_child(&master->dev, NULL, __unregister); device_unregister(&master->dev); } EXPORT_SYMBOL_GPL(spi_unregister_master); From 97cf608da5be7c2b48aa05410e261b1c0273857b Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Mon, 25 May 2020 14:25:02 +0200 Subject: [PATCH 291/387] spi: pxa2xx: Fix controller unregister order [ Upstream commit 32e5b57232c0411e7dea96625c415510430ac079 ] The PXA2xx SPI driver uses devm_spi_register_controller() on bind. As a consequence, on unbind, __device_release_driver() first invokes pxa2xx_spi_remove() before unregistering the SPI controller via devres_release_all(). This order is incorrect: pxa2xx_spi_remove() disables the chip, rendering the SPI bus inaccessible even though the SPI controller is still registered. When the SPI controller is subsequently unregistered, it unbinds all its slave devices. Because their drivers cannot access the SPI bus, e.g. to quiesce interrupts, the slave devices may be left in an improper state. As a rule, devm_spi_register_controller() must not be used if the ->remove() hook performs teardown steps which shall be performed after unregistering the controller and specifically after unbinding of slaves. Fix by reverting to the non-devm variant of spi_register_controller(). An alternative approach would be to use device-managed functions for all steps in pxa2xx_spi_remove(), e.g. by calling devm_add_action_or_reset() on probe. However that approach would add more LoC to the driver and it wouldn't lend itself as well to backporting to stable. The improper use of devm_spi_register_controller() was introduced in 2013 by commit a807fcd090d6 ("spi: pxa2xx: use devm_spi_register_master()"), but all earlier versions of the driver going back to 2006 were likewise broken because they invoked spi_unregister_master() at the end of pxa2xx_spi_remove(), rather than at the beginning. Fixes: e0c9905e87ac ("[PATCH] SPI: add PXA2xx SSP SPI Driver") Signed-off-by: Lukas Wunner Reviewed-by: Andy Shevchenko Cc: stable@vger.kernel.org # v2.6.17+ Cc: Tsuchiya Yuto Link: https://bugzilla.kernel.org/show_bug.cgi?id=206403#c1 Link: https://lore.kernel.org/r/834c446b1cf3284d2660f1bee1ebe3e737cd02a9.1590408496.git.lukas@wunner.de Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-pxa2xx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 2f84d7653afd..da3834fe5e57 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -1774,7 +1774,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) /* Register with the SPI framework */ platform_set_drvdata(pdev, drv_data); - status = devm_spi_register_master(&pdev->dev, master); + status = spi_register_master(master); if (status != 0) { dev_err(&pdev->dev, "problem registering spi master\n"); goto out_error_clock_enabled; @@ -1804,6 +1804,8 @@ static int pxa2xx_spi_remove(struct platform_device *pdev) pm_runtime_get_sync(&pdev->dev); + spi_unregister_master(drv_data->master); + /* Disable the SSP at the peripheral and SOC level */ pxa2xx_spi_write(drv_data, SSCR0, 0); clk_disable_unprepare(ssp->clk); From 826332330dab13003337a22bbd1685afb1f79d6d Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Fri, 15 May 2020 17:58:02 +0200 Subject: [PATCH 292/387] spi: bcm2835: Fix controller unregister order [ Upstream commit 9dd277ff92d06f6aa95b39936ad83981d781f49b ] The BCM2835 SPI driver uses devm_spi_register_controller() on bind. As a consequence, on unbind, __device_release_driver() first invokes bcm2835_spi_remove() before unregistering the SPI controller via devres_release_all(). This order is incorrect: bcm2835_spi_remove() tears down the DMA channels and turns off the SPI controller, including its interrupts and clock. The SPI controller is thus no longer usable. When the SPI controller is subsequently unregistered, it unbinds all its slave devices. If their drivers need to access the SPI bus, e.g. to quiesce their interrupts, unbinding will fail. As a rule, devm_spi_register_controller() must not be used if the ->remove() hook performs teardown steps which shall be performed after unbinding of slaves. Fix by using the non-devm variant spi_register_controller(). Note that the struct spi_controller as well as the driver-private data are not freed until after bcm2835_spi_remove() has finished, so accessing them is safe. Fixes: 247263dba208 ("spi: bcm2835: use devm_spi_register_master()") Signed-off-by: Lukas Wunner Cc: stable@vger.kernel.org # v3.13+ Link: https://lore.kernel.org/r/2397dd70cdbe95e0bc4da2b9fca0f31cb94e5aed.1589557526.git.lukas@wunner.de Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-bcm2835.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index eab27d41ba83..df6abc75bc16 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -793,7 +793,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev) goto out_clk_disable; } - err = devm_spi_register_master(&pdev->dev, master); + err = spi_register_master(master); if (err) { dev_err(&pdev->dev, "could not register SPI master: %d\n", err); goto out_clk_disable; @@ -813,6 +813,8 @@ static int bcm2835_spi_remove(struct platform_device *pdev) struct spi_master *master = platform_get_drvdata(pdev); struct bcm2835_spi *bs = spi_master_get_devdata(master); + spi_unregister_master(master); + /* Clear FIFOs, and disable the HW block */ bcm2835_wr(bs, BCM2835_SPI_CS, BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX); From fd50ed659b388546cfc99caf5ac1cf7f0e2ec8cb Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Wed, 27 May 2020 04:08:02 +0100 Subject: [PATCH 293/387] ovl: initialize error in ovl_copy_xattr commit 520da69d265a91c6536c63851cbb8a53946974f0 upstream. In ovl_copy_xattr, if all the xattrs to be copied are overlayfs private xattrs, the copy loop will terminate without assigning anything to the error variable, thus returning an uninitialized value. If ovl_copy_xattr is called from ovl_clear_empty, this uninitialized error value is put into a pointer by ERR_PTR(), causing potential invalid memory accesses down the line. This commit initialize error with 0. This is the correct value because when there's no xattr to copy, because all xattrs are private, ovl_copy_xattr should succeed. This bug is discovered with the help of INIT_STACK_ALL and clang. Signed-off-by: Yuxuan Shui Link: https://bugs.chromium.org/p/chromium/issues/detail?id=1050405 Fixes: 0956254a2d5b ("ovl: don't copy up opaqueness") Cc: stable@vger.kernel.org # v4.8 Signed-off-by: Alexander Potapenko Signed-off-by: Miklos Szeredi Signed-off-by: Greg Kroah-Hartman --- fs/overlayfs/copy_up.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index 36795eed40b0..299dbf59f28f 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@ -56,7 +56,7 @@ int ovl_copy_xattr(struct dentry *old, struct dentry *new) { ssize_t list_size, size, value_size = 0; char *buf, *name, *value = NULL; - int uninitialized_var(error); + int error = 0; size_t slen; if (!(old->d_inode->i_opflags & IOP_XATTR) || From 5b85bf5cf3af4584a7198c1a4e780b0e029eb50e Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Fri, 12 Jun 2020 09:42:03 -0500 Subject: [PATCH 294/387] proc: Use new_inode not new_inode_pseudo commit ef1548adada51a2f32ed7faef50aa465e1b4c5da upstream. Recently syzbot reported that unmounting proc when there is an ongoing inotify watch on the root directory of proc could result in a use after free when the watch is removed after the unmount of proc when the watcher exits. Commit 69879c01a0c3 ("proc: Remove the now unnecessary internal mount of proc") made it easier to unmount proc and allowed syzbot to see the problem, but looking at the code it has been around for a long time. Looking at the code the fsnotify watch should have been removed by fsnotify_sb_delete in generic_shutdown_super. Unfortunately the inode was allocated with new_inode_pseudo instead of new_inode so the inode was not on the sb->s_inodes list. Which prevented fsnotify_unmount_inodes from finding the inode and removing the watch as well as made it so the "VFS: Busy inodes after unmount" warning could not find the inodes to warn about them. Make all of the inodes in proc visible to generic_shutdown_super, and fsnotify_sb_delete by using new_inode instead of new_inode_pseudo. The only functional difference is that new_inode places the inodes on the sb->s_inodes list. I wrote a small test program and I can verify that without changes it can trigger this issue, and by replacing new_inode_pseudo with new_inode the issues goes away. Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/000000000000d788c905a7dfa3f4@google.com Reported-by: syzbot+7d2debdcdb3cb93c1e5e@syzkaller.appspotmail.com Fixes: 0097875bd415 ("proc: Implement /proc/thread-self to point at the directory of the current thread") Fixes: 021ada7dff22 ("procfs: switch /proc/self away from proc_dir_entry") Fixes: 51f0885e5415 ("vfs,proc: guarantee unique inodes in /proc") Signed-off-by: "Eric W. Biederman" Signed-off-by: Greg Kroah-Hartman --- fs/proc/inode.c | 2 +- fs/proc/self.c | 2 +- fs/proc/thread_self.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/proc/inode.c b/fs/proc/inode.c index c2afe39f0b9e..a28934912530 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c @@ -417,7 +417,7 @@ const struct inode_operations proc_link_inode_operations = { struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de) { - struct inode *inode = new_inode_pseudo(sb); + struct inode *inode = new_inode(sb); if (inode) { inode->i_ino = de->low_ino; diff --git a/fs/proc/self.c b/fs/proc/self.c index 40245954c450..c8bbc1c84a39 100644 --- a/fs/proc/self.c +++ b/fs/proc/self.c @@ -53,7 +53,7 @@ int proc_setup_self(struct super_block *s) inode_lock(root_inode); self = d_alloc_name(s->s_root, "self"); if (self) { - struct inode *inode = new_inode_pseudo(s); + struct inode *inode = new_inode(s); if (inode) { inode->i_ino = self_inum; inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode); diff --git a/fs/proc/thread_self.c b/fs/proc/thread_self.c index 595b90a9766c..02d1db8e9723 100644 --- a/fs/proc/thread_self.c +++ b/fs/proc/thread_self.c @@ -55,7 +55,7 @@ int proc_setup_thread_self(struct super_block *s) inode_lock(root_inode); thread_self = d_alloc_name(s->s_root, "thread-self"); if (thread_self) { - struct inode *inode = new_inode_pseudo(s); + struct inode *inode = new_inode(s); if (inode) { inode->i_ino = thread_self_inum; inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode); From b8ef2244dfda97fcbaa18f06ed0edc66b7288b03 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Wed, 6 May 2020 20:19:02 +0200 Subject: [PATCH 295/387] video: fbdev: w100fb: Fix a potential double free. commit 18722d48a6bb9c2e8d046214c0a5fd19d0a7c9f6 upstream. Some memory is vmalloc'ed in the 'w100fb_save_vidmem' function and freed in the 'w100fb_restore_vidmem' function. (these functions are called respectively from the 'suspend' and the 'resume' functions) However, it is also freed in the 'remove' function. In order to avoid a potential double free, set the corresponding pointer to NULL once freed in the 'w100fb_restore_vidmem' function. Fixes: aac51f09d96a ("[PATCH] w100fb: Rewrite for platform independence") Cc: Richard Purdie Cc: Antonino Daplas Cc: Bartlomiej Zolnierkiewicz Cc: # v2.6.14+ Signed-off-by: Christophe JAILLET Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20200506181902.193290-1-christophe.jaillet@wanadoo.fr Signed-off-by: Greg Kroah-Hartman --- drivers/video/fbdev/w100fb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/video/fbdev/w100fb.c b/drivers/video/fbdev/w100fb.c index 10951c82f6ed..7bd4c27cfb14 100644 --- a/drivers/video/fbdev/w100fb.c +++ b/drivers/video/fbdev/w100fb.c @@ -583,6 +583,7 @@ static void w100fb_restore_vidmem(struct w100fb_par *par) memsize=par->mach->mem->size; memcpy_toio(remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), par->saved_extmem, memsize); vfree(par->saved_extmem); + par->saved_extmem = NULL; } if (par->saved_intmem) { memsize=MEM_INT_SIZE; @@ -591,6 +592,7 @@ static void w100fb_restore_vidmem(struct w100fb_par *par) else memcpy_toio(remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), par->saved_intmem, memsize); vfree(par->saved_intmem); + par->saved_intmem = NULL; } } From 5e9cc6ea67757d1ddfceddd870ea390cb964b841 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 20 May 2020 08:02:17 -0400 Subject: [PATCH 296/387] KVM: nSVM: leave ASID aside in copy_vmcb_control_area commit 6c0238c4a62b3a0b1201aeb7e33a4636d552a436 upstream. Restoring the ASID from the hsave area on VMEXIT is wrong, because its value depends on the handling of TLB flushes. Just skipping the field in copy_vmcb_control_area will do. Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/svm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 1079228e4fef..29078eaf18c9 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -2734,7 +2734,7 @@ static inline void copy_vmcb_control_area(struct vmcb *dst_vmcb, struct vmcb *fr dst->iopm_base_pa = from->iopm_base_pa; dst->msrpm_base_pa = from->msrpm_base_pa; dst->tsc_offset = from->tsc_offset; - dst->asid = from->asid; + /* asid not copied, it is handled manually for svm->vmcb. */ dst->tlb_ctl = from->tlb_ctl; dst->int_ctl = from->int_ctl; dst->int_vector = from->int_vector; From 99a9857ddbd732be6348af989535fc39bbd2ab20 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Thu, 27 Feb 2020 09:44:30 -0800 Subject: [PATCH 297/387] KVM: nVMX: Consult only the "basic" exit reason when routing nested exit commit 2ebac8bb3c2d35f5135466490fc8eeaf3f3e2d37 upstream. Consult only the basic exit reason, i.e. bits 15:0 of vmcs.EXIT_REASON, when determining whether a nested VM-Exit should be reflected into L1 or handled by KVM in L0. For better or worse, the switch statement in nested_vmx_exit_reflected() currently defaults to "true", i.e. reflects any nested VM-Exit without dedicated logic. Because the case statements only contain the basic exit reason, any VM-Exit with modifier bits set will be reflected to L1, even if KVM intended to handle it in L0. Practically speaking, this only affects EXIT_REASON_MCE_DURING_VMENTRY, i.e. a #MC that occurs on nested VM-Enter would be incorrectly routed to L1, as "failed VM-Entry" is the only modifier that KVM can currently encounter. The SMM modifiers will never be generated as KVM doesn't support/employ a SMI Transfer Monitor. Ditto for "exit from enclave", as KVM doesn't yet support virtualizing SGX, i.e. it's impossible to enter an enclave in a KVM guest (L1 or L2). Fixes: 644d711aa0e1 ("KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit") Cc: Jim Mattson Cc: Xiaoyao Li Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson Message-Id: <20200227174430.26371-1-sean.j.christopherson@intel.com> Signed-off-by: Paolo Bonzini Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/vmx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index b62886f10dc1..e7fe5974c81c 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -8207,7 +8207,7 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu) return true; } - switch (exit_reason) { + switch ((u16)exit_reason) { case EXIT_REASON_EXCEPTION_NMI: if (is_nmi(intr_info)) return false; From 8ab5aec37049529fce062472221a91433984b731 Mon Sep 17 00:00:00 2001 From: Xing Li Date: Sat, 23 May 2020 15:56:28 +0800 Subject: [PATCH 298/387] KVM: MIPS: Define KVM_ENTRYHI_ASID to cpu_asid_mask(&boot_cpu_data) commit fe2b73dba47fb6d6922df1ad44e83b1754d5ed4d upstream. The code in decode_config4() of arch/mips/kernel/cpu-probe.c asid_mask = MIPS_ENTRYHI_ASID; if (config4 & MIPS_CONF4_AE) asid_mask |= MIPS_ENTRYHI_ASIDX; set_cpu_asid_mask(c, asid_mask); set asid_mask to cpuinfo->asid_mask. So in order to support variable ASID_MASK, KVM_ENTRYHI_ASID should also be changed to cpu_asid_mask(&boot_cpu_data). Cc: Stable #4.9+ Reviewed-by: Aleksandar Markovic Signed-off-by: Xing Li [Huacai: Change current_cpu_data to boot_cpu_data for optimization] Signed-off-by: Huacai Chen Message-Id: <1590220602-3547-2-git-send-email-chenhc@lemote.com> Signed-off-by: Paolo Bonzini Signed-off-by: Greg Kroah-Hartman --- arch/mips/include/asm/kvm_host.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h index bebec370324f..a828ec22ddf6 100644 --- a/arch/mips/include/asm/kvm_host.h +++ b/arch/mips/include/asm/kvm_host.h @@ -244,7 +244,7 @@ enum emulation_result { #define MIPS3_PG_FRAME 0x3fffffc0 #define VPN2_MASK 0xffffe000 -#define KVM_ENTRYHI_ASID MIPS_ENTRYHI_ASID +#define KVM_ENTRYHI_ASID cpu_asid_mask(&boot_cpu_data) #define TLB_IS_GLOBAL(x) ((x).tlb_lo[0] & (x).tlb_lo[1] & ENTRYLO_G) #define TLB_VPN2(x) ((x).tlb_hi & VPN2_MASK) #define TLB_ASID(x) ((x).tlb_hi & KVM_ENTRYHI_ASID) From cb671aa02528073d677aaf1d044539ab024c9470 Mon Sep 17 00:00:00 2001 From: Xing Li Date: Sat, 23 May 2020 15:56:29 +0800 Subject: [PATCH 299/387] KVM: MIPS: Fix VPN2_MASK definition for variable cpu_vmbits commit 5816c76dea116a458f1932eefe064e35403248eb upstream. If a CPU support more than 32bit vmbits (which is true for 64bit CPUs), VPN2_MASK set to fixed 0xffffe000 will lead to a wrong EntryHi in some functions such as _kvm_mips_host_tlb_inv(). The cpu_vmbits definition of 32bit CPU in cpu-features.h is 31, so we still use the old definition. Cc: Stable Reviewed-by: Aleksandar Markovic Signed-off-by: Xing Li [Huacai: Improve commit messages] Signed-off-by: Huacai Chen Message-Id: <1590220602-3547-3-git-send-email-chenhc@lemote.com> Signed-off-by: Paolo Bonzini Signed-off-by: Greg Kroah-Hartman --- arch/mips/include/asm/kvm_host.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h index a828ec22ddf6..22573b4f25b6 100644 --- a/arch/mips/include/asm/kvm_host.h +++ b/arch/mips/include/asm/kvm_host.h @@ -243,7 +243,11 @@ enum emulation_result { #define MIPS3_PG_SHIFT 6 #define MIPS3_PG_FRAME 0x3fffffc0 +#if defined(CONFIG_64BIT) +#define VPN2_MASK GENMASK(cpu_vmbits - 1, 13) +#else #define VPN2_MASK 0xffffe000 +#endif #define KVM_ENTRYHI_ASID cpu_asid_mask(&boot_cpu_data) #define TLB_IS_GLOBAL(x) ((x).tlb_lo[0] & (x).tlb_lo[1] & ENTRYLO_G) #define TLB_VPN2(x) ((x).tlb_hi & VPN2_MASK) From 3fce258c1163bd69547327c66e82df7ac3077a0d Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 9 Jun 2020 08:40:35 +0100 Subject: [PATCH 300/387] KVM: arm64: Make vcpu_cp1x() work on Big Endian hosts commit 3204be4109ad681523e3461ce64454c79278450a upstream. AArch32 CP1x registers are overlayed on their AArch64 counterparts in the vcpu struct. This leads to an interesting problem as they are stored in their CPU-local format, and thus a CP1x register doesn't "hit" the lower 32bit portion of the AArch64 register on a BE host. To workaround this unfortunate situation, introduce a bias trick in the vcpu_cp1x() accessors which picks the correct half of the 64bit register. Cc: stable@vger.kernel.org Reported-by: James Morse Tested-by: James Morse Acked-by: James Morse Signed-off-by: Marc Zyngier Signed-off-by: Greg Kroah-Hartman --- arch/arm64/include/asm/kvm_host.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 4cdfbd01b2de..367ebb48170b 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -290,8 +290,10 @@ struct kvm_vcpu_arch { * CP14 and CP15 live in the same array, as they are backed by the * same system registers. */ -#define vcpu_cp14(v,r) ((v)->arch.ctxt.copro[(r)]) -#define vcpu_cp15(v,r) ((v)->arch.ctxt.copro[(r)]) +#define CPx_BIAS IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) + +#define vcpu_cp14(v,r) ((v)->arch.ctxt.copro[(r) ^ CPx_BIAS]) +#define vcpu_cp15(v,r) ((v)->arch.ctxt.copro[(r) ^ CPx_BIAS]) #ifdef CONFIG_CPU_BIG_ENDIAN #define vcpu_cp15_64_high(v,r) vcpu_cp15((v),(r)) From 44736603a7099d2a9b48c669e43a689588e272a5 Mon Sep 17 00:00:00 2001 From: Qiujun Huang Date: Sat, 4 Apr 2020 12:18:35 +0800 Subject: [PATCH 301/387] ath9k: Fix use-after-free Read in ath9k_wmi_ctrl_rx commit abeaa85054ff8cfe8b99aafc5c70ea067e5d0908 upstream. Free wmi later after cmd urb has been killed, as urb cb will access wmi. the case reported by syzbot: https://lore.kernel.org/linux-usb/0000000000000002fc05a1d61a68@google.com BUG: KASAN: use-after-free in ath9k_wmi_ctrl_rx+0x416/0x500 drivers/net/wireless/ath/ath9k/wmi.c:215 Read of size 1 at addr ffff8881cef1417c by task swapper/1/0 Call Trace: ath9k_wmi_ctrl_rx+0x416/0x500 drivers/net/wireless/ath/ath9k/wmi.c:215 ath9k_htc_rx_msg+0x2da/0xaf0 drivers/net/wireless/ath/ath9k/htc_hst.c:459 ath9k_hif_usb_reg_in_cb+0x1ba/0x630 drivers/net/wireless/ath/ath9k/hif_usb.c:718 __usb_hcd_giveback_urb+0x29a/0x550 drivers/usb/core/hcd.c:1650 usb_hcd_giveback_urb+0x368/0x420 drivers/usb/core/hcd.c:1716 dummy_timer+0x1258/0x32ae drivers/usb/gadget/udc/dummy_hcd.c:1966 call_timer_fn+0x195/0x6f0 kernel/time/timer.c:1404 expire_timers kernel/time/timer.c:1449 [inline] __run_timers kernel/time/timer.c:1773 [inline] __run_timers kernel/time/timer.c:1740 [inline] run_timer_softirq+0x5f9/0x1500 kernel/time/timer.c:1786 Reported-and-tested-by: syzbot+5d338854440137ea0fef@syzkaller.appspotmail.com Signed-off-by: Qiujun Huang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200404041838.10426-3-hqjagain@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath9k/hif_usb.c | 5 +++-- drivers/net/wireless/ath/ath9k/hif_usb.h | 1 + drivers/net/wireless/ath/ath9k/htc_drv_init.c | 10 +++++++--- drivers/net/wireless/ath/ath9k/wmi.c | 5 ++++- drivers/net/wireless/ath/ath9k/wmi.h | 3 ++- 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index b5e12be73f2b..278488acfdbc 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -971,7 +971,7 @@ err: return -ENOMEM; } -static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) +void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) { usb_kill_anchored_urbs(&hif_dev->regout_submitted); ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev); @@ -1338,8 +1338,9 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface) if (hif_dev->flags & HIF_USB_READY) { ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged); - ath9k_htc_hw_free(hif_dev->htc_handle); ath9k_hif_usb_dev_deinit(hif_dev); + ath9k_destoy_wmi(hif_dev->htc_handle->drv_priv); + ath9k_htc_hw_free(hif_dev->htc_handle); } usb_set_intfdata(interface, NULL); diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h index 7c2ef7ecd98b..a95cdf562611 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.h +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h @@ -131,5 +131,6 @@ struct hif_device_usb { int ath9k_hif_usb_init(void); void ath9k_hif_usb_exit(void); +void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev); #endif /* HTC_USB_H */ diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index b65c1b661ade..15a0036dcc6e 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -931,8 +931,9 @@ err_init: int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, u16 devid, char *product, u32 drv_info) { - struct ieee80211_hw *hw; + struct hif_device_usb *hif_dev; struct ath9k_htc_priv *priv; + struct ieee80211_hw *hw; int ret; hw = ieee80211_alloc_hw(sizeof(struct ath9k_htc_priv), &ath9k_htc_ops); @@ -967,7 +968,10 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, return 0; err_init: - ath9k_deinit_wmi(priv); + ath9k_stop_wmi(priv); + hif_dev = (struct hif_device_usb *)htc_handle->hif_dev; + ath9k_hif_usb_dealloc_urbs(hif_dev); + ath9k_destoy_wmi(priv); err_free: ieee80211_free_hw(hw); return ret; @@ -982,7 +986,7 @@ void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug) htc_handle->drv_priv->ah->ah_flags |= AH_UNPLUGGED; ath9k_deinit_device(htc_handle->drv_priv); - ath9k_deinit_wmi(htc_handle->drv_priv); + ath9k_stop_wmi(htc_handle->drv_priv); ieee80211_free_hw(htc_handle->drv_priv->hw); } } diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 9c16e2a6d185..8f14897ae5a3 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -112,14 +112,17 @@ struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv) return wmi; } -void ath9k_deinit_wmi(struct ath9k_htc_priv *priv) +void ath9k_stop_wmi(struct ath9k_htc_priv *priv) { struct wmi *wmi = priv->wmi; mutex_lock(&wmi->op_mutex); wmi->stopped = true; mutex_unlock(&wmi->op_mutex); +} +void ath9k_destoy_wmi(struct ath9k_htc_priv *priv) +{ kfree(priv->wmi); } diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 380175d5ecd7..d8b912206232 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h @@ -179,7 +179,6 @@ struct wmi { }; struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv); -void ath9k_deinit_wmi(struct ath9k_htc_priv *priv); int ath9k_wmi_connect(struct htc_target *htc, struct wmi *wmi, enum htc_endpoint_id *wmi_ctrl_epid); int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, @@ -189,6 +188,8 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, void ath9k_wmi_event_tasklet(unsigned long data); void ath9k_fatal_work(struct work_struct *work); void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv); +void ath9k_stop_wmi(struct ath9k_htc_priv *priv); +void ath9k_destoy_wmi(struct ath9k_htc_priv *priv); #define WMI_CMD(_wmi_cmd) \ do { \ From 435f90a6506625722bd7c253b06274477dacd7ce Mon Sep 17 00:00:00 2001 From: Qiujun Huang Date: Sat, 4 Apr 2020 12:18:36 +0800 Subject: [PATCH 302/387] ath9k: Fix use-after-free Write in ath9k_htc_rx_msg commit e4ff08a4d727146bb6717a39a8d399d834654345 upstream. Write out of slab bounds. We should check epid. The case reported by syzbot: https://lore.kernel.org/linux-usb/0000000000006ac55b05a1c05d72@google.com BUG: KASAN: use-after-free in htc_process_conn_rsp drivers/net/wireless/ath/ath9k/htc_hst.c:131 [inline] BUG: KASAN: use-after-free in ath9k_htc_rx_msg+0xa25/0xaf0 drivers/net/wireless/ath/ath9k/htc_hst.c:443 Write of size 2 at addr ffff8881cea291f0 by task swapper/1/0 Call Trace: htc_process_conn_rsp drivers/net/wireless/ath/ath9k/htc_hst.c:131 [inline] ath9k_htc_rx_msg+0xa25/0xaf0 drivers/net/wireless/ath/ath9k/htc_hst.c:443 ath9k_hif_usb_reg_in_cb+0x1ba/0x630 drivers/net/wireless/ath/ath9k/hif_usb.c:718 __usb_hcd_giveback_urb+0x29a/0x550 drivers/usb/core/hcd.c:1650 usb_hcd_giveback_urb+0x368/0x420 drivers/usb/core/hcd.c:1716 dummy_timer+0x1258/0x32ae drivers/usb/gadget/udc/dummy_hcd.c:1966 call_timer_fn+0x195/0x6f0 kernel/time/timer.c:1404 expire_timers kernel/time/timer.c:1449 [inline] __run_timers kernel/time/timer.c:1773 [inline] __run_timers kernel/time/timer.c:1740 [inline] run_timer_softirq+0x5f9/0x1500 kernel/time/timer.c:1786 Reported-and-tested-by: syzbot+b1c61e5f11be5782f192@syzkaller.appspotmail.com Signed-off-by: Qiujun Huang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200404041838.10426-4-hqjagain@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath9k/htc_hst.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index fd85f996c554..257b6ee51e54 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -114,6 +114,9 @@ static void htc_process_conn_rsp(struct htc_target *target, if (svc_rspmsg->status == HTC_SERVICE_SUCCESS) { epid = svc_rspmsg->endpoint_id; + if (epid < 0 || epid >= ENDPOINT_MAX) + return; + service_id = be16_to_cpu(svc_rspmsg->service_id); max_msglen = be16_to_cpu(svc_rspmsg->max_msg_len); endpoint = &target->endpoint[epid]; From 4c87598dbcafb489c6eeee794c7e40eb939c1eca Mon Sep 17 00:00:00 2001 From: Qiujun Huang Date: Sat, 4 Apr 2020 12:18:37 +0800 Subject: [PATCH 303/387] ath9x: Fix stack-out-of-bounds Write in ath9k_hif_usb_rx_cb commit 19d6c375d671ce9949a864fb9a03e19f5487b4d3 upstream. Add barrier to accessing the stack array skb_pool. The case reported by syzbot: https://lore.kernel.org/linux-usb/0000000000003d7c1505a2168418@google.com BUG: KASAN: stack-out-of-bounds in ath9k_hif_usb_rx_stream drivers/net/wireless/ath/ath9k/hif_usb.c:626 [inline] BUG: KASAN: stack-out-of-bounds in ath9k_hif_usb_rx_cb+0xdf6/0xf70 drivers/net/wireless/ath/ath9k/hif_usb.c:666 Write of size 8 at addr ffff8881db309a28 by task swapper/1/0 Call Trace: ath9k_hif_usb_rx_stream drivers/net/wireless/ath/ath9k/hif_usb.c:626 [inline] ath9k_hif_usb_rx_cb+0xdf6/0xf70 drivers/net/wireless/ath/ath9k/hif_usb.c:666 __usb_hcd_giveback_urb+0x1f2/0x470 drivers/usb/core/hcd.c:1648 usb_hcd_giveback_urb+0x368/0x420 drivers/usb/core/hcd.c:1713 dummy_timer+0x1258/0x32ae drivers/usb/gadget/udc/dummy_hcd.c:1966 call_timer_fn+0x195/0x6f0 kernel/time/timer.c:1404 expire_timers kernel/time/timer.c:1449 [inline] __run_timers kernel/time/timer.c:1773 [inline] __run_timers kernel/time/timer.c:1740 [inline] run_timer_softirq+0x5f9/0x1500 kernel/time/timer.c:1786 Reported-and-tested-by: syzbot+d403396d4df67ad0bd5f@syzkaller.appspotmail.com Signed-off-by: Qiujun Huang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200404041838.10426-5-hqjagain@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath9k/hif_usb.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 278488acfdbc..84b5f8a144ff 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -610,6 +610,11 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev, hif_dev->remain_skb = nskb; spin_unlock(&hif_dev->rx_lock); } else { + if (pool_index == MAX_PKT_NUM_IN_TRANSFER) { + dev_err(&hif_dev->udev->dev, + "ath9k_htc: over RX MAX_PKT_NUM\n"); + goto err; + } nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC); if (!nskb) { dev_err(&hif_dev->udev->dev, From 5317abc46279d900c7e63cc122682d819da658bd Mon Sep 17 00:00:00 2001 From: Qiujun Huang Date: Sat, 4 Apr 2020 12:18:38 +0800 Subject: [PATCH 304/387] ath9k: Fix general protection fault in ath9k_hif_usb_rx_cb commit 2bbcaaee1fcbd83272e29f31e2bb7e70d8c49e05 upstream. In ath9k_hif_usb_rx_cb interface number is assumed to be 0. usb_ifnum_to_if(urb->dev, 0) But it isn't always true. The case reported by syzbot: https://lore.kernel.org/linux-usb/000000000000666c9c05a1c05d12@google.com usb 2-1: new high-speed USB device number 2 using dummy_hcd usb 2-1: config 1 has an invalid interface number: 2 but max is 0 usb 2-1: config 1 has no interface number 0 usb 2-1: New USB device found, idVendor=0cf3, idProduct=9271, bcdDevice= 1.08 usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 general protection fault, probably for non-canonical address 0xdffffc0000000015: 0000 [#1] SMP KASAN KASAN: null-ptr-deref in range [0x00000000000000a8-0x00000000000000af] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.6.0-rc5-syzkaller #0 Call Trace __usb_hcd_giveback_urb+0x29a/0x550 drivers/usb/core/hcd.c:1650 usb_hcd_giveback_urb+0x368/0x420 drivers/usb/core/hcd.c:1716 dummy_timer+0x1258/0x32ae drivers/usb/gadget/udc/dummy_hcd.c:1966 call_timer_fn+0x195/0x6f0 kernel/time/timer.c:1404 expire_timers kernel/time/timer.c:1449 [inline] __run_timers kernel/time/timer.c:1773 [inline] __run_timers kernel/time/timer.c:1740 [inline] run_timer_softirq+0x5f9/0x1500 kernel/time/timer.c:1786 __do_softirq+0x21e/0x950 kernel/softirq.c:292 invoke_softirq kernel/softirq.c:373 [inline] irq_exit+0x178/0x1a0 kernel/softirq.c:413 exiting_irq arch/x86/include/asm/apic.h:546 [inline] smp_apic_timer_interrupt+0x141/0x540 arch/x86/kernel/apic/apic.c:1146 apic_timer_interrupt+0xf/0x20 arch/x86/entry/entry_64.S:829 Reported-and-tested-by: syzbot+40d5d2e8a4680952f042@syzkaller.appspotmail.com Signed-off-by: Qiujun Huang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200404041838.10426-6-hqjagain@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath9k/hif_usb.c | 48 ++++++++++++++++++------ drivers/net/wireless/ath/ath9k/hif_usb.h | 5 +++ 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 84b5f8a144ff..e27acccc3678 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -641,9 +641,9 @@ err: static void ath9k_hif_usb_rx_cb(struct urb *urb) { - struct sk_buff *skb = (struct sk_buff *) urb->context; - struct hif_device_usb *hif_dev = - usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); + struct rx_buf *rx_buf = (struct rx_buf *)urb->context; + struct hif_device_usb *hif_dev = rx_buf->hif_dev; + struct sk_buff *skb = rx_buf->skb; int ret; if (!skb) @@ -683,14 +683,15 @@ resubmit: return; free: kfree_skb(skb); + kfree(rx_buf); } static void ath9k_hif_usb_reg_in_cb(struct urb *urb) { - struct sk_buff *skb = (struct sk_buff *) urb->context; + struct rx_buf *rx_buf = (struct rx_buf *)urb->context; + struct hif_device_usb *hif_dev = rx_buf->hif_dev; + struct sk_buff *skb = rx_buf->skb; struct sk_buff *nskb; - struct hif_device_usb *hif_dev = - usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); int ret; if (!skb) @@ -748,6 +749,7 @@ resubmit: return; free: kfree_skb(skb); + kfree(rx_buf); urb->context = NULL; } @@ -793,7 +795,7 @@ static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev) init_usb_anchor(&hif_dev->mgmt_submitted); for (i = 0; i < MAX_TX_URB_NUM; i++) { - tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL); + tx_buf = kzalloc(sizeof(*tx_buf), GFP_KERNEL); if (!tx_buf) goto err; @@ -830,8 +832,9 @@ static void ath9k_hif_usb_dealloc_rx_urbs(struct hif_device_usb *hif_dev) static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev) { - struct urb *urb = NULL; + struct rx_buf *rx_buf = NULL; struct sk_buff *skb = NULL; + struct urb *urb = NULL; int i, ret; init_usb_anchor(&hif_dev->rx_submitted); @@ -839,6 +842,12 @@ static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev) for (i = 0; i < MAX_RX_URB_NUM; i++) { + rx_buf = kzalloc(sizeof(*rx_buf), GFP_KERNEL); + if (!rx_buf) { + ret = -ENOMEM; + goto err_rxb; + } + /* Allocate URB */ urb = usb_alloc_urb(0, GFP_KERNEL); if (urb == NULL) { @@ -853,11 +862,14 @@ static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev) goto err_skb; } + rx_buf->hif_dev = hif_dev; + rx_buf->skb = skb; + usb_fill_bulk_urb(urb, hif_dev->udev, usb_rcvbulkpipe(hif_dev->udev, USB_WLAN_RX_PIPE), skb->data, MAX_RX_BUF_SIZE, - ath9k_hif_usb_rx_cb, skb); + ath9k_hif_usb_rx_cb, rx_buf); /* Anchor URB */ usb_anchor_urb(urb, &hif_dev->rx_submitted); @@ -883,6 +895,8 @@ err_submit: err_skb: usb_free_urb(urb); err_urb: + kfree(rx_buf); +err_rxb: ath9k_hif_usb_dealloc_rx_urbs(hif_dev); return ret; } @@ -894,14 +908,21 @@ static void ath9k_hif_usb_dealloc_reg_in_urbs(struct hif_device_usb *hif_dev) static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev) { - struct urb *urb = NULL; + struct rx_buf *rx_buf = NULL; struct sk_buff *skb = NULL; + struct urb *urb = NULL; int i, ret; init_usb_anchor(&hif_dev->reg_in_submitted); for (i = 0; i < MAX_REG_IN_URB_NUM; i++) { + rx_buf = kzalloc(sizeof(*rx_buf), GFP_KERNEL); + if (!rx_buf) { + ret = -ENOMEM; + goto err_rxb; + } + /* Allocate URB */ urb = usb_alloc_urb(0, GFP_KERNEL); if (urb == NULL) { @@ -916,11 +937,14 @@ static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev) goto err_skb; } + rx_buf->hif_dev = hif_dev; + rx_buf->skb = skb; + usb_fill_int_urb(urb, hif_dev->udev, usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE), skb->data, MAX_REG_IN_BUF_SIZE, - ath9k_hif_usb_reg_in_cb, skb, 1); + ath9k_hif_usb_reg_in_cb, rx_buf, 1); /* Anchor URB */ usb_anchor_urb(urb, &hif_dev->reg_in_submitted); @@ -946,6 +970,8 @@ err_submit: err_skb: usb_free_urb(urb); err_urb: + kfree(rx_buf); +err_rxb: ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev); return ret; } diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h index a95cdf562611..835264c36595 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.h +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h @@ -84,6 +84,11 @@ struct tx_buf { struct list_head list; }; +struct rx_buf { + struct sk_buff *skb; + struct hif_device_usb *hif_dev; +}; + #define HIF_USB_TX_STOP BIT(0) #define HIF_USB_TX_FLUSH BIT(1) From d9010023962a37eeaf1c75bdc5fcb15e235a5d1a Mon Sep 17 00:00:00 2001 From: Casey Schaufler Date: Thu, 9 Apr 2020 16:35:28 -0700 Subject: [PATCH 305/387] Smack: slab-out-of-bounds in vsscanf commit 84e99e58e8d1e26f04c097f4266e431a33987f36 upstream. Add barrier to soob. Return -EOVERFLOW if the buffer is exceeded. Suggested-by: Hillf Danton Reported-by: syzbot+bfdd4a2f07be52351350@syzkaller.appspotmail.com Signed-off-by: Casey Schaufler Signed-off-by: Greg Kroah-Hartman --- security/smack/smackfs.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 6492fe96cae4..3397b216bc6c 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -901,11 +901,21 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf, else rule += strlen(skp->smk_known) + 1; + if (rule > data + count) { + rc = -EOVERFLOW; + goto out; + } + ret = sscanf(rule, "%d", &maplevel); if (ret != 1 || maplevel > SMACK_CIPSO_MAXLEVEL) goto out; rule += SMK_DIGITLEN; + if (rule > data + count) { + rc = -EOVERFLOW; + goto out; + } + ret = sscanf(rule, "%d", &catlen); if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM) goto out; From 248bd0506b58fd62c0fd1c8fd4a0d5a48b12ff43 Mon Sep 17 00:00:00 2001 From: Wang Hai Date: Wed, 3 Jun 2020 15:56:21 -0700 Subject: [PATCH 306/387] mm/slub: fix a memory leak in sysfs_slab_add() commit dde3c6b72a16c2db826f54b2d49bdea26c3534a2 upstream. syzkaller reports for memory leak when kobject_init_and_add() returns an error in the function sysfs_slab_add() [1] When this happened, the function kobject_put() is not called for the corresponding kobject, which potentially leads to memory leak. This patch fixes the issue by calling kobject_put() even if kobject_init_and_add() fails. [1] BUG: memory leak unreferenced object 0xffff8880a6d4be88 (size 8): comm "syz-executor.3", pid 946, jiffies 4295772514 (age 18.396s) hex dump (first 8 bytes): 70 69 64 5f 33 00 ff ff pid_3... backtrace: kstrdup+0x35/0x70 mm/util.c:60 kstrdup_const+0x3d/0x50 mm/util.c:82 kvasprintf_const+0x112/0x170 lib/kasprintf.c:48 kobject_set_name_vargs+0x55/0x130 lib/kobject.c:289 kobject_add_varg lib/kobject.c:384 [inline] kobject_init_and_add+0xd8/0x170 lib/kobject.c:473 sysfs_slab_add+0x1d8/0x290 mm/slub.c:5811 __kmem_cache_create+0x50a/0x570 mm/slub.c:4384 create_cache+0x113/0x1e0 mm/slab_common.c:407 kmem_cache_create_usercopy+0x1a1/0x260 mm/slab_common.c:505 kmem_cache_create+0xd/0x10 mm/slab_common.c:564 create_pid_cachep kernel/pid_namespace.c:54 [inline] create_pid_namespace kernel/pid_namespace.c:96 [inline] copy_pid_ns+0x77c/0x8f0 kernel/pid_namespace.c:148 create_new_namespaces+0x26b/0xa30 kernel/nsproxy.c:95 unshare_nsproxy_namespaces+0xa7/0x1e0 kernel/nsproxy.c:229 ksys_unshare+0x3d2/0x770 kernel/fork.c:2969 __do_sys_unshare kernel/fork.c:3037 [inline] __se_sys_unshare kernel/fork.c:3035 [inline] __x64_sys_unshare+0x2d/0x40 kernel/fork.c:3035 do_syscall_64+0xa1/0x530 arch/x86/entry/common.c:295 Fixes: 80da026a8e5d ("mm/slub: fix slab double-free in case of duplicate sysfs filename") Reported-by: Hulk Robot Signed-off-by: Wang Hai Signed-off-by: Andrew Morton Cc: Christoph Lameter Cc: Pekka Enberg Cc: David Rientjes Cc: Joonsoo Kim Link: http://lkml.kernel.org/r/20200602115033.1054-1-wanghai38@huawei.com Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- mm/slub.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mm/slub.c b/mm/slub.c index 9b44423f1cf0..3d45713187a4 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -5620,8 +5620,10 @@ static int sysfs_slab_add(struct kmem_cache *s) s->kobj.kset = cache_kset(s); err = kobject_init_and_add(&s->kobj, &slab_ktype, NULL, "%s", name); - if (err) + if (err) { + kobject_put(&s->kobj); goto out; + } err = sysfs_create_group(&s->kobj, &slab_attr_group); if (err) From cadb31d19d02dfe239223f0c753cdcdb0a02aba9 Mon Sep 17 00:00:00 2001 From: OGAWA Hirofumi Date: Thu, 4 Jun 2020 16:50:56 -0700 Subject: [PATCH 307/387] fat: don't allow to mount if the FAT length == 0 commit b1b65750b8db67834482f758fc385bfa7560d228 upstream. If FAT length == 0, the image doesn't have any data. And it can be the cause of overlapping the root dir and FAT entries. Also Windows treats it as invalid format. Reported-by: syzbot+6f1624f937d9d6911e2d@syzkaller.appspotmail.com Signed-off-by: OGAWA Hirofumi Signed-off-by: Andrew Morton Cc: Marco Elver Cc: Dmitry Vyukov Link: http://lkml.kernel.org/r/87r1wz8mrd.fsf@mail.parknet.co.jp Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- fs/fat/inode.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/fat/inode.c b/fs/fat/inode.c index f0387d040331..9af410142f78 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -1512,6 +1512,12 @@ static int fat_read_bpb(struct super_block *sb, struct fat_boot_sector *b, goto out; } + if (bpb->fat_fat_length == 0 && bpb->fat32_length == 0) { + if (!silent) + fat_msg(sb, KERN_ERR, "bogus number of FAT sectors"); + goto out; + } + error = 0; out: From 9bf3b3649d37a1bd9fe9f4f04707c14934298795 Mon Sep 17 00:00:00 2001 From: Barret Rhoden Date: Tue, 14 Apr 2020 18:29:20 -0400 Subject: [PATCH 308/387] perf: Add cond_resched() to task_function_call() commit 2ed6edd33a214bca02bd2b45e3fc3038a059436b upstream. Under rare circumstances, task_function_call() can repeatedly fail and cause a soft lockup. There is a slight race where the process is no longer running on the cpu we targeted by the time remote_function() runs. The code will simply try again. If we are very unlucky, this will continue to fail, until a watchdog fires. This can happen in a heavily loaded, multi-core virtual machine. Reported-by: syzbot+bb4935a5c09b5ff79940@syzkaller.appspotmail.com Signed-off-by: Barret Rhoden Signed-off-by: Peter Zijlstra (Intel) Link: https://lkml.kernel.org/r/20200414222920.121401-1-brho@google.com Signed-off-by: Greg Kroah-Hartman --- kernel/events/core.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 1f27b73bd7d4..b562467d2d49 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -90,11 +90,11 @@ static void remote_function(void *data) * @info: the function call argument * * Calls the function @func when the task is currently running. This might - * be on the current CPU, which just calls the function directly + * be on the current CPU, which just calls the function directly. This will + * retry due to any failures in smp_call_function_single(), such as if the + * task_cpu() goes offline concurrently. * - * returns: @func return value, or - * -ESRCH - when the process isn't running - * -EAGAIN - when the process moved away + * returns @func return value or -ESRCH when the process isn't running */ static int task_function_call(struct task_struct *p, remote_function_f func, void *info) @@ -107,11 +107,16 @@ task_function_call(struct task_struct *p, remote_function_f func, void *info) }; int ret; - do { - ret = smp_call_function_single(task_cpu(p), remote_function, &data, 1); - if (!ret) - ret = data.ret; - } while (ret == -EAGAIN); + for (;;) { + ret = smp_call_function_single(task_cpu(p), remote_function, + &data, 1); + ret = !ret ? data.ret : -EAGAIN; + + if (ret != -EAGAIN) + break; + + cond_resched(); + } return ret; } From 35de820ec802dac28bc37f757723847e7ecd70d2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 10 Apr 2020 09:35:35 +0100 Subject: [PATCH 309/387] agp/intel: Reinforce the barrier after GTT updates commit f30d3ced9fafa03e4855508929b5b6334907f45e upstream. After changing the timing between GTT updates and execution on the GPU, we started seeing sporadic failures on Ironlake. These were narrowed down to being an insufficiently strong enough barrier/delay after updating the GTT and scheduling execution on the GPU. By forcing the uncached read, and adding the missing barrier for the singular insert_page (relocation paths), the sporadic failures go away. Fixes: 983d308cb8f6 ("agp/intel: Serialise after GTT updates") Fixes: 3497971a71d8 ("agp/intel: Flush chipset writes after updating a single PTE") Signed-off-by: Chris Wilson Acked-by: Andi Shyti Cc: stable@vger.kernel.org # v4.0+ Link: https://patchwork.freedesktop.org/patch/msgid/20200410083535.25464-1-chris@chris-wilson.co.uk Signed-off-by: Greg Kroah-Hartman --- drivers/char/agp/intel-gtt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index a7cc5b7be598..871e7f4994e8 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -845,6 +845,7 @@ void intel_gtt_insert_page(dma_addr_t addr, unsigned int flags) { intel_private.driver->write_entry(addr, pg, flags); + readl(intel_private.gtt + pg); if (intel_private.driver->chipset_flush) intel_private.driver->chipset_flush(); } @@ -870,7 +871,7 @@ void intel_gtt_insert_sg_entries(struct sg_table *st, j++; } } - wmb(); + readl(intel_private.gtt + j - 1); if (intel_private.driver->chipset_flush) intel_private.driver->chipset_flush(); } @@ -1104,6 +1105,7 @@ static void i9xx_cleanup(void) static void i9xx_chipset_flush(void) { + wmb(); if (intel_private.i9xx_flush_page) writel(1, intel_private.i9xx_flush_page); } From c8ed03b9c541e9ac25085d4c2c74b775161c1654 Mon Sep 17 00:00:00 2001 From: Xiaolong Huang Date: Sat, 7 Dec 2019 22:40:24 +0800 Subject: [PATCH 310/387] can: kvaser_usb: kvaser_usb_leaf: Fix some info-leaks to USB devices commit da2311a6385c3b499da2ed5d9be59ce331fa93e9 upstream. Uninitialized Kernel memory can leak to USB devices. Fix this by using kzalloc() instead of kmalloc(). Signed-off-by: Xiaolong Huang Fixes: 7259124eac7d ("can: kvaser_usb: Split driver into kvaser_usb_core.c and kvaser_usb_leaf.c") Cc: linux-stable # >= v4.19 Signed-off-by: Marc Kleine-Budde [bwh: Backported to 4.9: adjust filename, context] Signed-off-by: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- drivers/net/can/usb/kvaser_usb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index 3a75352f632b..792a1afabf5d 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c @@ -791,7 +791,7 @@ static int kvaser_usb_simple_msg_async(struct kvaser_usb_net_priv *priv, if (!urb) return -ENOMEM; - buf = kmalloc(sizeof(struct kvaser_msg), GFP_ATOMIC); + buf = kzalloc(sizeof(struct kvaser_msg), GFP_ATOMIC); if (!buf) { usb_free_urb(urb); return -ENOMEM; @@ -1459,7 +1459,7 @@ static int kvaser_usb_set_opt_mode(const struct kvaser_usb_net_priv *priv) struct kvaser_msg *msg; int rc; - msg = kmalloc(sizeof(*msg), GFP_KERNEL); + msg = kzalloc(sizeof(*msg), GFP_KERNEL); if (!msg) return -ENOMEM; @@ -1592,7 +1592,7 @@ static int kvaser_usb_flush_queue(struct kvaser_usb_net_priv *priv) struct kvaser_msg *msg; int rc; - msg = kmalloc(sizeof(*msg), GFP_KERNEL); + msg = kzalloc(sizeof(*msg), GFP_KERNEL); if (!msg) return -ENOMEM; From 77d5f7fe23e92dfdeefcc9a225ee97eee2667d95 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 20 Jul 2017 18:12:07 -0400 Subject: [PATCH 311/387] media: dvb_frontend: ensure that inital front end status initialized commit a9e4998073d49a762a154a6b48a332ec6cb8e6b1 upstream. The fe_status variable s is not initialized meaning it can have any random garbage status. This could be problematic if fe->ops.tune is false as s is not updated by the call to fe->ops.tune() and a subsequent check on the change status will using a garbage value. Fix this by adding FE_NONE to the enum fe_status and initializing s to this. Detected by CoverityScan, CID#112887 ("Uninitialized scalar variable") Signed-off-by: Colin Ian King Reviewed-by: Shuah Khan Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Florian Fainelli Signed-off-by: Greg Kroah-Hartman --- drivers/media/dvb-core/dvb_frontend.c | 2 +- include/uapi/linux/dvb/frontend.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index 2f054db8807b..372057cabea4 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -629,7 +629,7 @@ static int dvb_frontend_thread(void *data) struct dvb_frontend *fe = data; struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct dvb_frontend_private *fepriv = fe->frontend_priv; - enum fe_status s; + enum fe_status s = FE_NONE; enum dvbfe_algo algo; bool re_tune = false; bool semheld = false; diff --git a/include/uapi/linux/dvb/frontend.h b/include/uapi/linux/dvb/frontend.h index 00a20cd21ee2..afc3972b0879 100644 --- a/include/uapi/linux/dvb/frontend.h +++ b/include/uapi/linux/dvb/frontend.h @@ -127,6 +127,7 @@ enum fe_sec_mini_cmd { * to reset DiSEqC, tone and parameters */ enum fe_status { + FE_NONE = 0x00, FE_HAS_SIGNAL = 0x01, FE_HAS_CARRIER = 0x02, FE_HAS_VITERBI = 0x04, From 7cfcf05c86f8143935e8c6983abcb57265890474 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Wed, 27 May 2020 13:37:00 +0200 Subject: [PATCH 312/387] ACPI: GED: use correct trigger type field in _Exx / _Lxx handling commit e5c399b0bd6490c12c0af2a9eaa9d7cd805d52c9 upstream. Commit ea6f3af4c5e63f69 ("ACPI: GED: add support for _Exx / _Lxx handler methods") added a reference to the 'triggering' field of either the normal or the extended ACPI IRQ resource struct, but inadvertently used the wrong pointer in the latter case. Note that both pointers refer to the same union, and the 'triggering' field appears at the same offset in both struct types, so it currently happens to work by accident. But let's fix it nonetheless Fixes: ea6f3af4c5e63f69 ("ACPI: GED: add support for _Exx / _Lxx handler methods") Signed-off-by: Ard Biesheuvel Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/evged.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/evged.c b/drivers/acpi/evged.c index 385e98bf7bd0..339e6d3dba7c 100644 --- a/drivers/acpi/evged.c +++ b/drivers/acpi/evged.c @@ -97,7 +97,7 @@ static acpi_status acpi_ged_request_interrupt(struct acpi_resource *ares, trigger = p->triggering; } else { gsi = pext->interrupts[0]; - trigger = p->triggering; + trigger = pext->triggering; } irq = r.start; From 4688ba5b53400215889151f34fee51de7b483f71 Mon Sep 17 00:00:00 2001 From: Brad Love Date: Thu, 14 Nov 2019 21:03:57 +0100 Subject: [PATCH 313/387] media: si2157: Better check for running tuner in init [ Upstream commit e955f959ac52e145f27ff2be9078b646d0352af0 ] Getting the Xtal trim property to check if running is less error prone. Reset if_frequency if state is unknown. Replaces the previous "garbage check". Signed-off-by: Brad Love Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/tuners/si2157.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c index 57b250847cd3..72a47da0db2a 100644 --- a/drivers/media/tuners/si2157.c +++ b/drivers/media/tuners/si2157.c @@ -84,24 +84,23 @@ static int si2157_init(struct dvb_frontend *fe) struct si2157_cmd cmd; const struct firmware *fw; const char *fw_name; - unsigned int uitmp, chip_id; + unsigned int chip_id, xtal_trim; dev_dbg(&client->dev, "\n"); - /* Returned IF frequency is garbage when firmware is not running */ - memcpy(cmd.args, "\x15\x00\x06\x07", 4); + /* Try to get Xtal trim property, to verify tuner still running */ + memcpy(cmd.args, "\x15\x00\x04\x02", 4); cmd.wlen = 4; cmd.rlen = 4; ret = si2157_cmd_execute(client, &cmd); - if (ret) - goto err; - uitmp = cmd.args[2] << 0 | cmd.args[3] << 8; - dev_dbg(&client->dev, "if_frequency kHz=%u\n", uitmp); + xtal_trim = cmd.args[2] | (cmd.args[3] << 8); - if (uitmp == dev->if_frequency / 1000) + if (ret == 0 && xtal_trim < 16) goto warm; + dev->if_frequency = 0; /* we no longer know current tuner state */ + /* power up */ if (dev->chiptype == SI2157_CHIPTYPE_SI2146) { memcpy(cmd.args, "\xc0\x05\x01\x00\x00\x0b\x00\x00\x01", 9); From b1f3bcd5494f920ab7a365b2bb5a195be54e25df Mon Sep 17 00:00:00 2001 From: Julien Thierry Date: Fri, 27 Mar 2020 15:28:41 +0000 Subject: [PATCH 314/387] objtool: Ignore empty alternatives [ Upstream commit 7170cf47d16f1ba29eca07fd818870b7af0a93a5 ] The .alternatives section can contain entries with no original instructions. Objtool will currently crash when handling such an entry. Just skip that entry, but still give a warning to discourage useless entries. Signed-off-by: Julien Thierry Acked-by: Peter Zijlstra (Intel) Reviewed-by: Miroslav Benes Signed-off-by: Josh Poimboeuf Signed-off-by: Ingo Molnar Signed-off-by: Sasha Levin --- tools/objtool/check.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index b0b8ba9b800c..c7399d7f4bc7 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -778,6 +778,12 @@ static int add_special_section_alts(struct objtool_file *file) } if (special_alt->group) { + if (!special_alt->orig_len) { + WARN_FUNC("empty alternative entry", + orig_insn->sec, orig_insn->offset); + continue; + } + ret = handle_group_alt(file, special_alt, orig_insn, &new_insn); if (ret) From 966de7bdeff501395b630c6503a17caaf8295d41 Mon Sep 17 00:00:00 2001 From: Arthur Kiyanovski Date: Sun, 3 May 2020 09:52:11 +0000 Subject: [PATCH 315/387] net: ena: fix error returning in ena_com_get_hash_function() [ Upstream commit e9a1de378dd46375f9abfd8de1e6f59ee114a793 ] In case the "func" parameter is NULL we now return "-EINVAL". This shouldn't happen in general, but when it does happen, this is the proper way to handle it. We also check func for NULL in the beginning of the function, as there is no reason to do all the work and realize in the end of the function it was useless. Signed-off-by: Sameeh Jubran Signed-off-by: Arthur Kiyanovski Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/amazon/ena/ena_com.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c b/drivers/net/ethernet/amazon/ena/ena_com.c index 905911f78693..e95f19e573a7 100644 --- a/drivers/net/ethernet/amazon/ena/ena_com.c +++ b/drivers/net/ethernet/amazon/ena/ena_com.c @@ -2096,6 +2096,9 @@ int ena_com_get_hash_function(struct ena_com_dev *ena_dev, rss->hash_key; int rc; + if (unlikely(!func)) + return -EINVAL; + rc = ena_com_get_feature_ex(ena_dev, &get_resp, ENA_ADMIN_RSS_HASH_FUNCTION, rss->hash_key_dma_addr, @@ -2108,8 +2111,7 @@ int ena_com_get_hash_function(struct ena_com_dev *ena_dev, if (rss->hash_func) rss->hash_func--; - if (func) - *func = rss->hash_func; + *func = rss->hash_func; if (key) memcpy(key, hash_key->key, (size_t)(hash_key->keys_num) << 2); From 3801effa5fe3a51f907170f932362d07fbfc8d2d Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 6 May 2020 18:30:18 +0300 Subject: [PATCH 316/387] spi: dw: Zero DMA Tx and Rx configurations on stack [ Upstream commit 3cb97e223d277f84171cc4ccecab31e08b2ee7b5 ] Some DMA controller drivers do not tolerate non-zero values in the DMA configuration structures. Zero them to avoid issues with such DMA controller drivers. Even despite above this is a good practice per se. Fixes: 7063c0d942a1 ("spi/dw_spi: add DMA support") Signed-off-by: Andy Shevchenko Acked-by: Feng Tang Cc: Feng Tang Link: https://lore.kernel.org/r/20200506153025.21441-1-andriy.shevchenko@linux.intel.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-dw-mid.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index e31971f91475..f77d03b658ab 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c @@ -155,6 +155,7 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_tx(struct dw_spi *dws, if (!xfer->tx_buf) return NULL; + memset(&txconf, 0, sizeof(txconf)); txconf.direction = DMA_MEM_TO_DEV; txconf.dst_addr = dws->dma_addr; txconf.dst_maxburst = 16; @@ -201,6 +202,7 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_rx(struct dw_spi *dws, if (!xfer->rx_buf) return NULL; + memset(&rxconf, 0, sizeof(rxconf)); rxconf.direction = DMA_DEV_TO_MEM; rxconf.src_addr = dws->dma_addr; rxconf.src_maxburst = 16; From 5b0660c7e1cf070d31e17319ce5b3bd30b310955 Mon Sep 17 00:00:00 2001 From: Hsin-Yu Chao Date: Fri, 15 May 2020 17:27:04 +0800 Subject: [PATCH 317/387] Bluetooth: Add SCO fallback for invalid LMP parameters error [ Upstream commit 56b5453a86203a44726f523b4133c1feca49ce7c ] Bluetooth PTS test case HFP/AG/ACC/BI-12-I accepts SCO connection with invalid parameter at the first SCO request expecting AG to attempt another SCO request with the use of "safe settings" for given codec, base on section 5.7.1.2 of HFP 1.7 specification. This patch addresses it by adding "Invalid LMP Parameters" (0x1e) to the SCO fallback case. Verified with below log: < HCI Command: Setup Synchronous Connection (0x01|0x0028) plen 17 Handle: 256 Transmit bandwidth: 8000 Receive bandwidth: 8000 Max latency: 13 Setting: 0x0003 Input Coding: Linear Input Data Format: 1's complement Input Sample Size: 8-bit # of bits padding at MSB: 0 Air Coding Format: Transparent Data Retransmission effort: Optimize for link quality (0x02) Packet type: 0x0380 3-EV3 may not be used 2-EV5 may not be used 3-EV5 may not be used > HCI Event: Command Status (0x0f) plen 4 Setup Synchronous Connection (0x01|0x0028) ncmd 1 Status: Success (0x00) > HCI Event: Number of Completed Packets (0x13) plen 5 Num handles: 1 Handle: 256 Count: 1 > HCI Event: Max Slots Change (0x1b) plen 3 Handle: 256 Max slots: 1 > HCI Event: Synchronous Connect Complete (0x2c) plen 17 Status: Invalid LMP Parameters / Invalid LL Parameters (0x1e) Handle: 0 Address: 00:1B:DC:F2:21:59 (OUI 00-1B-DC) Link type: eSCO (0x02) Transmission interval: 0x00 Retransmission window: 0x02 RX packet length: 0 TX packet length: 0 Air mode: Transparent (0x03) < HCI Command: Setup Synchronous Connection (0x01|0x0028) plen 17 Handle: 256 Transmit bandwidth: 8000 Receive bandwidth: 8000 Max latency: 8 Setting: 0x0003 Input Coding: Linear Input Data Format: 1's complement Input Sample Size: 8-bit # of bits padding at MSB: 0 Air Coding Format: Transparent Data Retransmission effort: Optimize for link quality (0x02) Packet type: 0x03c8 EV3 may be used 2-EV3 may not be used 3-EV3 may not be used 2-EV5 may not be used 3-EV5 may not be used > HCI Event: Command Status (0x0f) plen 4 Setup Synchronous Connection (0x01|0x0028) ncmd 1 Status: Success (0x00) > HCI Event: Max Slots Change (0x1b) plen 3 Handle: 256 Max slots: 5 > HCI Event: Max Slots Change (0x1b) plen 3 Handle: 256 Max slots: 1 > HCI Event: Synchronous Connect Complete (0x2c) plen 17 Status: Success (0x00) Handle: 257 Address: 00:1B:DC:F2:21:59 (OUI 00-1B-DC) Link type: eSCO (0x02) Transmission interval: 0x06 Retransmission window: 0x04 RX packet length: 30 TX packet length: 30 Air mode: Transparent (0x03) Signed-off-by: Hsin-Yu Chao Signed-off-by: Marcel Holtmann Signed-off-by: Sasha Levin --- net/bluetooth/hci_event.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 6f78489fdb13..a8aa3f29f2d6 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -3775,6 +3775,7 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, case 0x11: /* Unsupported Feature or Parameter Value */ case 0x1c: /* SCO interval rejected */ case 0x1a: /* Unsupported Remote Feature */ + case 0x1e: /* Invalid LMP Parameters */ case 0x1f: /* Unspecified error */ case 0x20: /* Unsupported LMP Parameter value */ if (conn->out) { From d39bb8ee76a0ccfd1086b6e76e2a0b247ecaa5fd Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Thu, 7 May 2020 13:08:44 -0700 Subject: [PATCH 318/387] kgdb: Prevent infinite recursive entries to the debugger [ Upstream commit 3ca676e4ca60d1834bb77535dafe24169cadacef ] If we detect that we recursively entered the debugger we should hack our I/O ops to NULL so that the panic() in the next line won't actually cause another recursion into the debugger. The first line of kgdb_panic() will check this and return. Signed-off-by: Douglas Anderson Reviewed-by: Daniel Thompson Link: https://lore.kernel.org/r/20200507130644.v4.6.I89de39f68736c9de610e6f241e68d8dbc44bc266@changeid Signed-off-by: Daniel Thompson Signed-off-by: Sasha Levin --- kernel/debug/debug_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index 79517e5549f1..9c939c6bf21c 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c @@ -443,6 +443,7 @@ static int kgdb_reenter_check(struct kgdb_state *ks) if (exception_level > 1) { dump_stack(); + kgdb_io_module_registered = false; panic("Recursive entry to debugger"); } From 3824e01d361ddfa9955c3db7e54543d930452cdb Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Fri, 22 May 2020 03:07:51 +0300 Subject: [PATCH 319/387] spi: dw: Enable interrupts in accordance with DMA xfer mode [ Upstream commit 43dba9f3f98c2b184a19f856f06fe22817bfd9e0 ] It's pointless to track the Tx overrun interrupts if Rx-only SPI transfer is issued. Similarly there is no need in handling the Rx overrun/underrun interrupts if Tx-only SPI transfer is executed. So lets unmask the interrupts only if corresponding SPI transactions are implied. Co-developed-by: Georgy Vlasov Signed-off-by: Georgy Vlasov Signed-off-by: Serge Semin Cc: Ramil Zaripov Cc: Alexey Malahov Cc: Thomas Bogendoerfer Cc: Paul Burton Cc: Ralf Baechle Cc: Arnd Bergmann Cc: Andy Shevchenko Cc: Rob Herring Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200522000806.7381-3-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-dw-mid.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index f77d03b658ab..fe0ca3848d35 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c @@ -228,19 +228,23 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_rx(struct dw_spi *dws, static int mid_spi_dma_setup(struct dw_spi *dws, struct spi_transfer *xfer) { - u16 dma_ctrl = 0; + u16 imr = 0, dma_ctrl = 0; dw_writel(dws, DW_SPI_DMARDLR, 0xf); dw_writel(dws, DW_SPI_DMATDLR, 0x10); - if (xfer->tx_buf) + if (xfer->tx_buf) { dma_ctrl |= SPI_DMA_TDMAE; - if (xfer->rx_buf) + imr |= SPI_INT_TXOI; + } + if (xfer->rx_buf) { dma_ctrl |= SPI_DMA_RDMAE; + imr |= SPI_INT_RXUI | SPI_INT_RXOI; + } dw_writel(dws, DW_SPI_DMACR, dma_ctrl); /* Set the interrupt mask */ - spi_umask_intr(dws, SPI_INT_TXOI | SPI_INT_RXUI | SPI_INT_RXOI); + spi_umask_intr(dws, imr); dws->transfer_handler = dma_transfer; From ec718fc8acdbba62351c2988dfb4355e73df8b3e Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Thu, 21 May 2020 23:48:15 +0300 Subject: [PATCH 320/387] clocksource: dw_apb_timer_of: Fix missing clockevent timers [ Upstream commit 6d2e16a3181bafb77b535095c39ad1c8b9558c8c ] Commit 100214889973 ("clocksource: dw_apb_timer_of: use clocksource_of_init") replaced a publicly available driver initialization method with one called by the timer_probe() method available after CLKSRC_OF. In current implementation it traverses all the timers available in the system and calls their initialization methods if corresponding devices were either in dtb or in acpi. But if before the commit any number of available timers would be installed as clockevent and clocksource devices, after that there would be at most two. The rest are just ignored since default case branch doesn't do anything. I don't see a reason of such behaviour, neither the commit message explains it. Moreover this might be wrong if on some platforms these timers might be used for different purpose, as virtually CPU-local clockevent timers and as an independent broadcast timer. So in order to keep the compatibility with the platforms where the order of the timers detection has some meaning, lets add the secondly discovered timer to be of clocksource/sched_clock type, while the very first and the others would provide the clockevents service. Fixes: 100214889973 ("clocksource: dw_apb_timer_of: use clocksource_of_init") Signed-off-by: Serge Semin Cc: Alexey Malahov Cc: Thomas Bogendoerfer Cc: Paul Burton Cc: Ralf Baechle Cc: Alessandro Zummo Cc: Alexandre Belloni Cc: Arnd Bergmann Cc: Rob Herring Cc: linux-mips@vger.kernel.org Cc: linux-rtc@vger.kernel.org Cc: devicetree@vger.kernel.org Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20200521204818.25436-7-Sergey.Semin@baikalelectronics.ru Signed-off-by: Sasha Levin --- drivers/clocksource/dw_apb_timer_of.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/clocksource/dw_apb_timer_of.c b/drivers/clocksource/dw_apb_timer_of.c index aee6c0d39a7c..024e6cc5025b 100644 --- a/drivers/clocksource/dw_apb_timer_of.c +++ b/drivers/clocksource/dw_apb_timer_of.c @@ -146,10 +146,6 @@ static int num_called; static int __init dw_apb_timer_init(struct device_node *timer) { switch (num_called) { - case 0: - pr_debug("%s: found clockevent timer\n", __func__); - add_clockevent(timer); - break; case 1: pr_debug("%s: found clocksource timer\n", __func__); add_clocksource(timer); @@ -160,6 +156,8 @@ static int __init dw_apb_timer_init(struct device_node *timer) #endif break; default: + pr_debug("%s: found clockevent timer\n", __func__); + add_clockevent(timer); break; } From 814d5b6f5758bded017b4b544cfddcef99ee853f Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Mon, 18 May 2020 12:15:09 +0100 Subject: [PATCH 321/387] btrfs: do not ignore error from btrfs_next_leaf() when inserting checksums [ Upstream commit 7e4a3f7ed5d54926ec671bbb13e171cfe179cc50 ] We are currently treating any non-zero return value from btrfs_next_leaf() the same way, by going to the code that inserts a new checksum item in the tree. However if btrfs_next_leaf() returns an error (a value < 0), we should just stop and return the error, and not behave as if nothing has happened, since in that case we do not have a way to know if there is a next leaf or we are currently at the last leaf already. So fix that by returning the error from btrfs_next_leaf(). Signed-off-by: Filipe Manana Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Sasha Levin --- fs/btrfs/file-item.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index d0d571c47d33..4f919628137c 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c @@ -779,10 +779,12 @@ again: nritems = btrfs_header_nritems(path->nodes[0]); if (!nritems || (path->slots[0] >= nritems - 1)) { ret = btrfs_next_leaf(root, path); - if (ret == 1) + if (ret < 0) { + goto out; + } else if (ret > 0) { found_next = 1; - if (ret != 0) goto insert; + } slot = path->slots[0]; } btrfs_item_key_to_cpu(path->nodes[0], &found_key, slot); From 58708a2ff7d31356bdbefa14232f0dd47fb0a218 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 19 May 2020 12:59:12 +0100 Subject: [PATCH 322/387] ARM: 8978/1: mm: make act_mm() respect THREAD_SIZE [ Upstream commit e1de94380af588bdf6ad6f0cc1f75004c35bc096 ] Recent work with KASan exposed the folling hard-coded bitmask in arch/arm/mm/proc-macros.S: bic rd, sp, #8128 bic rd, rd, #63 This forms the bitmask 0x1FFF that is coinciding with (PAGE_SIZE << THREAD_SIZE_ORDER) - 1, this code was assuming that THREAD_SIZE is always 8K (8192). As KASan was increasing THREAD_SIZE_ORDER to 2, I ran into this bug. Fix it by this little oneline suggested by Ard: bic rd, sp, #(THREAD_SIZE - 1) & ~63 Where THREAD_SIZE is defined using THREAD_SIZE_ORDER. We have to also include since the THREAD_SIZE expands to use the _AC() macro. Cc: Ard Biesheuvel Cc: Florian Fainelli Suggested-by: Ard Biesheuvel Signed-off-by: Linus Walleij Signed-off-by: Russell King Signed-off-by: Sasha Levin --- arch/arm/mm/proc-macros.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S index f8bb65032b79..796e8f675a93 100644 --- a/arch/arm/mm/proc-macros.S +++ b/arch/arm/mm/proc-macros.S @@ -4,6 +4,7 @@ * VMA_VM_FLAGS * VM_EXEC */ +#include #include #include @@ -34,7 +35,7 @@ * act_mm - get current->active_mm */ .macro act_mm, rd - bic \rd, sp, #8128 + bic \rd, sp, #(THREAD_SIZE - 1) & ~63 bic \rd, \rd, #63 ldr \rd, [\rd, #TI_TASK] ldr \rd, [\rd, #TSK_ACTIVE_MM] From 64a3108d20ab12b8387edcc2f18d07ccededdf53 Mon Sep 17 00:00:00 2001 From: Jon Doron Date: Fri, 24 Apr 2020 14:37:40 +0300 Subject: [PATCH 323/387] x86/kvm/hyper-v: Explicitly align hcall param for kvm_hyperv_exit [ Upstream commit f7d31e65368aeef973fab788aa22c4f1d5a6af66 ] The problem the patch is trying to address is the fact that 'struct kvm_hyperv_exit' has different layout on when compiling in 32 and 64 bit modes. In 64-bit mode the default alignment boundary is 64 bits thus forcing extra gaps after 'type' and 'msr' but in 32-bit mode the boundary is at 32 bits thus no extra gaps. This is an issue as even when the kernel is 64 bit, the userspace using the interface can be both 32 and 64 bit but the same 32 bit userspace has to work with 32 bit kernel. The issue is fixed by forcing the 64 bit layout, this leads to ABI change for 32 bit builds and while we are obviously breaking '32 bit userspace with 32 bit kernel' case, we're fixing the '32 bit userspace with 64 bit kernel' one. As the interface has no (known) users and 32 bit KVM is rather baroque nowadays, this seems like a reasonable decision. Reviewed-by: Vitaly Kuznetsov Signed-off-by: Jon Doron Message-Id: <20200424113746.3473563-2-arilou@gmail.com> Reviewed-by: Roman Kagan Signed-off-by: Paolo Bonzini Signed-off-by: Sasha Levin --- Documentation/virtual/kvm/api.txt | 2 ++ include/uapi/linux/kvm.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index d1908e50b506..b8f5bf2a890a 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -3534,9 +3534,11 @@ EOI was received. #define KVM_EXIT_HYPERV_SYNIC 1 #define KVM_EXIT_HYPERV_HCALL 2 __u32 type; + __u32 pad1; union { struct { __u32 msr; + __u32 pad2; __u64 control; __u64 evt_page; __u64 msg_page; diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index a0a365cbf3c9..0c02441d2cc9 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -159,9 +159,11 @@ struct kvm_hyperv_exit { #define KVM_EXIT_HYPERV_SYNIC 1 #define KVM_EXIT_HYPERV_HCALL 2 __u32 type; + __u32 pad1; union { struct { __u32 msr; + __u32 pad2; __u64 control; __u64 evt_page; __u64 msg_page; From f1e015f7aeccd7dadf209a4e32bbc13f3ce3636d Mon Sep 17 00:00:00 2001 From: Jia-Ju Bai Date: Sat, 30 May 2020 10:41:50 +0800 Subject: [PATCH 324/387] net: vmxnet3: fix possible buffer overflow caused by bad DMA value in vmxnet3_get_rss() [ Upstream commit 3e1c6846b9e108740ef8a37be80314053f5dd52a ] The value adapter->rss_conf is stored in DMA memory, and it is assigned to rssConf, so rssConf->indTableSize can be modified at anytime by malicious hardware. Because rssConf->indTableSize is assigned to n, buffer overflow may occur when the code "rssConf->indTable[n]" is executed. To fix this possible bug, n is checked after being used. Signed-off-by: Jia-Ju Bai Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/vmxnet3/vmxnet3_ethtool.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c index aabc6ef366b4..d63b83605748 100644 --- a/drivers/net/vmxnet3/vmxnet3_ethtool.c +++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c @@ -691,6 +691,8 @@ vmxnet3_get_rss(struct net_device *netdev, u32 *p, u8 *key, u8 *hfunc) *hfunc = ETH_RSS_HASH_TOP; if (!p) return 0; + if (n > UPT1_RSS_MAX_IND_TABLE_SIZE) + return 0; while (n--) p[n] = rssConf->indTable[n]; return 0; From 40e12d9a15a6575f6dccae621cb85eb7eb910c02 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 1 Jun 2020 21:50:23 -0700 Subject: [PATCH 325/387] staging: android: ion: use vmap instead of vm_map_ram [ Upstream commit 5bf9917452112694b2c774465ee4dbe441c84b77 ] vm_map_ram can keep mappings around after the vm_unmap_ram. Using that with non-PAGE_KERNEL mappings can lead to all kinds of aliasing issues. Signed-off-by: Christoph Hellwig Signed-off-by: Andrew Morton Acked-by: Greg Kroah-Hartman Acked-by: Peter Zijlstra (Intel) Cc: Christian Borntraeger Cc: Christophe Leroy Cc: Daniel Vetter Cc: David Airlie Cc: Gao Xiang Cc: Haiyang Zhang Cc: Johannes Weiner Cc: "K. Y. Srinivasan" Cc: Laura Abbott Cc: Mark Rutland Cc: Michael Kelley Cc: Minchan Kim Cc: Nitin Gupta Cc: Robin Murphy Cc: Sakari Ailus Cc: Stephen Hemminger Cc: Sumit Semwal Cc: Wei Liu Cc: Benjamin Herrenschmidt Cc: Catalin Marinas Cc: Heiko Carstens Cc: Paul Mackerras Cc: Vasily Gorbik Cc: Will Deacon Link: http://lkml.kernel.org/r/20200414131348.444715-4-hch@lst.de Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin --- drivers/staging/android/ion/ion_heap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c index c2a7cb95725b..4fc5de13582d 100644 --- a/drivers/staging/android/ion/ion_heap.c +++ b/drivers/staging/android/ion/ion_heap.c @@ -105,12 +105,12 @@ int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, static int ion_heap_clear_pages(struct page **pages, int num, pgprot_t pgprot) { - void *addr = vm_map_ram(pages, num, -1, pgprot); + void *addr = vmap(pages, num, VM_MAP, pgprot); if (!addr) return -ENOMEM; memset(addr, 0, PAGE_SIZE * num); - vm_unmap_ram(addr, num); + vunmap(addr); return 0; } From ede1f11ae5228f7248946485f9146c3f6274a421 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 19 Feb 2020 22:23:02 -0800 Subject: [PATCH 326/387] e1000: Distribute switch variables for initialization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit a34c7f5156654ebaf7eaace102938be7ff7036cb ] Variables declared in a switch statement before any case statements cannot be automatically initialized with compiler instrumentation (as they are not part of any execution flow). With GCC's proposed automatic stack variable initialization feature, this triggers a warning (and they don't get initialized). Clang's automatic stack variable initialization (via CONFIG_INIT_STACK_ALL=y) doesn't throw a warning, but it also doesn't initialize such variables[1]. Note that these warnings (or silent skipping) happen before the dead-store elimination optimization phase, so even when the automatic initializations are later elided in favor of direct initializations, the warnings remain. To avoid these problems, move such variables into the "case" where they're used or lift them up into the main function body. drivers/net/ethernet/intel/e1000/e1000_main.c: In function ‘e1000_xmit_frame’: drivers/net/ethernet/intel/e1000/e1000_main.c:3143:18: warning: statement will never be executed [-Wswitch-unreachable] 3143 | unsigned int pull_size; | ^~~~~~~~~ [1] https://bugs.llvm.org/show_bug.cgi?id=44916 Signed-off-by: Kees Cook Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher Signed-off-by: Sasha Levin --- drivers/net/ethernet/intel/e1000/e1000_main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 39a09e18c1b7..3b16ee0de246 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -3167,8 +3167,9 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); if (skb->data_len && hdr_len == len) { switch (hw->mac_type) { + case e1000_82544: { unsigned int pull_size; - case e1000_82544: + /* Make sure we have room to chop off 4 bytes, * and that the end alignment will work out to * this hardware's requirements @@ -3189,6 +3190,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, } len = skb_headlen(skb); break; + } default: /* do nothing */ break; From c76a7a4af64cd64936898d5b90af58f8f82e0221 Mon Sep 17 00:00:00 2001 From: Jitao Shi Date: Wed, 15 Apr 2020 09:13:17 +0800 Subject: [PATCH 327/387] dt-bindings: display: mediatek: control dpi pins mode to avoid leakage [ Upstream commit b0ff9b590733079f7f9453e5976a9dd2630949e3 ] Add property "pinctrl-names" to swap pin mode between gpio and dpi mode. Set the dpi pins to gpio mode and output-low to avoid leakage current when dpi disabled. Acked-by: Rob Herring Signed-off-by: Jitao Shi Signed-off-by: Chun-Kuang Hu Signed-off-by: Sasha Levin --- .../devicetree/bindings/display/mediatek/mediatek,dpi.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.txt index b6a7e7397b8b..b944fe067188 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.txt +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.txt @@ -16,6 +16,9 @@ Required properties: Documentation/devicetree/bindings/graph.txt. This port should be connected to the input port of an attached HDMI or LVDS encoder chip. +Optional properties: +- pinctrl-names: Contain "default" and "sleep". + Example: dpi0: dpi@1401d000 { @@ -26,6 +29,9 @@ dpi0: dpi@1401d000 { <&mmsys CLK_MM_DPI_ENGINE>, <&apmixedsys CLK_APMIXED_TVDPLL>; clock-names = "pixel", "engine", "pll"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&dpi_pin_func>; + pinctrl-1 = <&dpi_pin_idle>; port { dpi0_out: endpoint { From cef66945b620e7e96c71d075c0cc58b2dd30d277 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 10 Feb 2020 18:51:33 +0100 Subject: [PATCH 328/387] media: dvb: return -EREMOTEIO on i2c transfer failure. [ Upstream commit 96f3a9392799dd0f6472648a7366622ffd0989f3 ] Currently when i2c transfers fail the error return -EREMOTEIO is assigned to err but then later overwritten when the tuner attach call is made. Fix this by returning early with the error return code -EREMOTEIO on i2c transfer failure errors. If the transfer fails, an uninitialized value will be read from b2. Addresses-Coverity: ("Unused value") Fixes: fbfee8684ff2 ("V4L/DVB (5651): Dibusb-mb: convert pll handling to properly use dvb-pll") Signed-off-by: Colin Ian King Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/usb/dvb-usb/dibusb-mb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/usb/dvb-usb/dibusb-mb.c b/drivers/media/usb/dvb-usb/dibusb-mb.c index a0057641cc86..c55180912c3a 100644 --- a/drivers/media/usb/dvb-usb/dibusb-mb.c +++ b/drivers/media/usb/dvb-usb/dibusb-mb.c @@ -84,7 +84,7 @@ static int dibusb_tuner_probe_and_attach(struct dvb_usb_adapter *adap) if (i2c_transfer(&adap->dev->i2c_adap, msg, 2) != 2) { err("tuner i2c write failed."); - ret = -EREMOTEIO; + return -EREMOTEIO; } if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl) From 6ac24bdb294e6e51d967c38e31fccd2059437b53 Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Tue, 7 Apr 2020 17:44:17 +0200 Subject: [PATCH 329/387] media: platform: fcp: Set appropriate DMA parameters [ Upstream commit dd844fb8e50b12e65bbdc5746c9876c6735500df ] Enabling CONFIG_DMA_API_DEBUG=y and CONFIG_DMA_API_DEBUG_SG=y will enable extra validation on DMA operations ensuring that the size restraints are met. When using the FCP in conjunction with the VSP1/DU, and display frames, the size of the DMA operations is larger than the default maximum segment size reported by the DMA core (64K). With the DMA debug enabled, this produces a warning such as the following: "DMA-API: rcar-fcp fea27000.fcp: mapping sg segment longer than device claims to support [len=3145728] [max=65536]" We have no specific limitation on the segment size which isn't already handled by the VSP1/DU which actually handles the DMA allcoations and buffer management, so define a maximum segment size of up to 4GB (a 32 bit mask). Reported-by: Geert Uytterhoeven Fixes: 7b49235e83b2 ("[media] v4l: Add Renesas R-Car FCP driver") Signed-off-by: Kieran Bingham Reviewed-by: Geert Uytterhoeven Tested-by: Geert Uytterhoeven Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/platform/rcar-fcp.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/media/platform/rcar-fcp.c b/drivers/media/platform/rcar-fcp.c index f3a3f31cdfa9..8e9c3bd36d03 100644 --- a/drivers/media/platform/rcar-fcp.c +++ b/drivers/media/platform/rcar-fcp.c @@ -12,6 +12,7 @@ */ #include +#include #include #include #include @@ -24,6 +25,7 @@ struct rcar_fcp_device { struct list_head list; struct device *dev; + struct device_dma_parameters dma_parms; }; static LIST_HEAD(fcp_devices); @@ -140,6 +142,9 @@ static int rcar_fcp_probe(struct platform_device *pdev) fcp->dev = &pdev->dev; + fcp->dev->dma_parms = &fcp->dma_parms; + dma_set_max_seg_size(fcp->dev, DMA_BIT_MASK(32)); + pm_runtime_enable(&pdev->dev); mutex_lock(&fcp_lock); From 6ff43399c7cacff321a0c7331894c574c8323a6b Mon Sep 17 00:00:00 2001 From: Tiezhu Yang Date: Tue, 21 Apr 2020 19:59:46 +0800 Subject: [PATCH 330/387] MIPS: Make sparse_init() using top-down allocation [ Upstream commit 269b3a9ac538c4ae87f84be640b9fa89914a2489 ] In the current code, if CONFIG_SWIOTLB is set, when failed to get IO TLB memory from the low pages by plat_swiotlb_setup(), it may lead to the boot process failed with kernel panic. (1) On the Loongson and SiByte platform arch/mips/loongson64/dma.c arch/mips/sibyte/common/dma.c void __init plat_swiotlb_setup(void) { swiotlb_init(1); } kernel/dma/swiotlb.c void __init swiotlb_init(int verbose) { ... vstart = memblock_alloc_low(PAGE_ALIGN(bytes), PAGE_SIZE); if (vstart && !swiotlb_init_with_tbl(vstart, io_tlb_nslabs, verbose)) return; ... pr_warn("Cannot allocate buffer"); no_iotlb_memory = true; } phys_addr_t swiotlb_tbl_map_single() { ... if (no_iotlb_memory) panic("Can not allocate SWIOTLB buffer earlier ..."); ... } (2) On the Cavium OCTEON platform arch/mips/cavium-octeon/dma-octeon.c void __init plat_swiotlb_setup(void) { ... octeon_swiotlb = memblock_alloc_low(swiotlbsize, PAGE_SIZE); if (!octeon_swiotlb) panic("%s: Failed to allocate %zu bytes align=%lx\n", __func__, swiotlbsize, PAGE_SIZE); ... } Because IO_TLB_DEFAULT_SIZE is 64M, if the rest size of low memory is less than 64M when call plat_swiotlb_setup(), we can easily reproduce the panic case. In order to reduce the possibility of kernel panic when failed to get IO TLB memory under CONFIG_SWIOTLB, it is better to allocate low memory as small as possible before plat_swiotlb_setup(), so make sparse_init() using top-down allocation. Reported-by: Juxin Gao Co-developed-by: Juxin Gao Signed-off-by: Juxin Gao Signed-off-by: Tiezhu Yang Signed-off-by: Thomas Bogendoerfer Signed-off-by: Sasha Levin --- arch/mips/kernel/setup.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 7cc1d29334ee..2c3b89a65317 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -847,7 +847,17 @@ static void __init arch_mem_init(char **cmdline_p) BOOTMEM_DEFAULT); #endif device_tree_init(); + + /* + * In order to reduce the possibility of kernel panic when failed to + * get IO TLB memory under CONFIG_SWIOTLB, it is better to allocate + * low memory as small as possible before plat_swiotlb_setup(), so + * make sparse_init() using top-down allocation. + */ + memblock_set_bottom_up(false); sparse_init(); + memblock_set_bottom_up(true); + plat_swiotlb_setup(); dma_contiguous_reserve(PFN_PHYS(max_low_pfn)); From fbe0bd6f77e0331e5491d1c65cd0d4b224f07761 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Fri, 24 Apr 2020 21:55:34 +0200 Subject: [PATCH 331/387] netfilter: nft_nat: return EOPNOTSUPP if type or flags are not supported [ Upstream commit 0d7c83463fdf7841350f37960a7abadd3e650b41 ] Instead of EINVAL which should be used for malformed netlink messages. Fixes: eb31628e37a0 ("netfilter: nf_tables: Add support for IPv6 NAT") Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin --- net/netfilter/nft_nat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/netfilter/nft_nat.c b/net/netfilter/nft_nat.c index 4c48e9bb21e2..d2510e432c18 100644 --- a/net/netfilter/nft_nat.c +++ b/net/netfilter/nft_nat.c @@ -135,7 +135,7 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr, priv->type = NF_NAT_MANIP_DST; break; default: - return -EINVAL; + return -EOPNOTSUPP; } err = nft_nat_validate(ctx, expr, NULL); @@ -206,7 +206,7 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr, if (tb[NFTA_NAT_FLAGS]) { priv->flags = ntohl(nla_get_be32(tb[NFTA_NAT_FLAGS])); if (priv->flags & ~NF_NAT_RANGE_MASK) - return -EINVAL; + return -EOPNOTSUPP; } return 0; From ed3cbbfeba8dd13aefb5e89b6ef40f5342723b9b Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Tue, 21 Apr 2020 14:47:04 -0700 Subject: [PATCH 332/387] lib/mpi: Fix 64-bit MIPS build with Clang [ Upstream commit 18f1ca46858eac22437819937ae44aa9a8f9f2fa ] When building 64r6_defconfig with CONFIG_MIPS32_O32 disabled and CONFIG_CRYPTO_RSA enabled: lib/mpi/generic_mpih-mul1.c:37:24: error: invalid use of a cast in a inline asm context requiring an l-value: remove the cast or build with -fheinous-gnu-extensions umul_ppmm(prod_high, prod_low, s1_ptr[j], s2_limb); ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ lib/mpi/longlong.h:664:22: note: expanded from macro 'umul_ppmm' : "=d" ((UDItype)(w0)) ~~~~~~~~~~^~~ lib/mpi/generic_mpih-mul1.c:37:13: error: invalid use of a cast in a inline asm context requiring an l-value: remove the cast or build with -fheinous-gnu-extensions umul_ppmm(prod_high, prod_low, s1_ptr[j], s2_limb); ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ lib/mpi/longlong.h:668:22: note: expanded from macro 'umul_ppmm' : "=d" ((UDItype)(w1)) ~~~~~~~~~~^~~ 2 errors generated. This special case for umul_ppmm for MIPS64r6 was added in commit bbc25bee37d2b ("lib/mpi: Fix umul_ppmm() for MIPS64r6"), due to GCC being inefficient and emitting a __multi3 intrinsic. There is no such issue with clang; with this patch applied, I can build this configuration without any problems and there are no link errors like mentioned in the commit above (which I can still reproduce with GCC 9.3.0 when that commit is reverted). Only use this definition when GCC is being used. This really should have been caught by commit b0c091ae04f67 ("lib/mpi: Eliminate unused umul_ppmm definitions for MIPS") when I was messing around in this area but I was not testing 64-bit MIPS at the time. Link: https://github.com/ClangBuiltLinux/linux/issues/885 Reported-by: Dmitry Golovin Signed-off-by: Nathan Chancellor Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- lib/mpi/longlong.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mpi/longlong.h b/lib/mpi/longlong.h index 8f383cca6bb1..623440d3d365 100644 --- a/lib/mpi/longlong.h +++ b/lib/mpi/longlong.h @@ -671,7 +671,7 @@ do { \ ************** MIPS/64 ************** ***************************************/ #if (defined(__mips) && __mips >= 3) && W_TYPE_SIZE == 64 -#if defined(__mips_isa_rev) && __mips_isa_rev >= 6 +#if defined(__mips_isa_rev) && __mips_isa_rev >= 6 && defined(CONFIG_CC_IS_GCC) /* * GCC ends up emitting a __multi3 intrinsic call for MIPS64r6 with the plain C * code below, so we special case MIPS64r6 until the compiler can do better. From 1e587ce792e3803f42a8ef19bdcd3ae2cec2892f Mon Sep 17 00:00:00 2001 From: Jann Horn Date: Thu, 5 Mar 2020 23:06:57 +0100 Subject: [PATCH 333/387] exit: Move preemption fixup up, move blocking operations down [ Upstream commit 586b58cac8b4683eb58a1446fbc399de18974e40 ] With CONFIG_DEBUG_ATOMIC_SLEEP=y and CONFIG_CGROUPS=y, kernel oopses in non-preemptible context look untidy; after the main oops, the kernel prints a "sleeping function called from invalid context" report because exit_signals() -> cgroup_threadgroup_change_begin() -> percpu_down_read() can sleep, and that happens before the preempt_count_set(PREEMPT_ENABLED) fixup. It looks like the same thing applies to profile_task_exit() and kcov_task_exit(). Fix it by moving the preemption fixup up and the calls to profile_task_exit() and kcov_task_exit() down. Fixes: 1dc0fffc48af ("sched/core: Robustify preemption leak checks") Signed-off-by: Jann Horn Signed-off-by: Peter Zijlstra (Intel) Link: https://lkml.kernel.org/r/20200305220657.46800-1-jannh@google.com Signed-off-by: Sasha Levin --- kernel/exit.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/kernel/exit.c b/kernel/exit.c index d9394fcd0e2c..27f4168eaeb1 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -739,8 +739,12 @@ void __noreturn do_exit(long code) int group_dead; TASKS_RCU(int tasks_rcu_i); - profile_task_exit(tsk); - kcov_task_exit(tsk); + /* + * We can get here from a kernel oops, sometimes with preemption off. + * Start by checking for critical errors. + * Then fix up important state like USER_DS and preemption. + * Then do everything else. + */ WARN_ON(blk_needs_flush_plug(tsk)); @@ -758,6 +762,16 @@ void __noreturn do_exit(long code) */ set_fs(USER_DS); + if (unlikely(in_atomic())) { + pr_info("note: %s[%d] exited with preempt_count %d\n", + current->comm, task_pid_nr(current), + preempt_count()); + preempt_count_set(PREEMPT_ENABLED); + } + + profile_task_exit(tsk); + kcov_task_exit(tsk); + ptrace_event(PTRACE_EVENT_EXIT, code); validate_creds_for_do_exit(tsk); @@ -794,13 +808,6 @@ void __noreturn do_exit(long code) */ raw_spin_unlock_wait(&tsk->pi_lock); - if (unlikely(in_atomic())) { - pr_info("note: %s[%d] exited with preempt_count %d\n", - current->comm, task_pid_nr(current), - preempt_count()); - preempt_count_set(PREEMPT_ENABLED); - } - /* sync mm's RSS info before statistics gathering */ if (tsk->mm) sync_mm_rss(tsk->mm); From e6eadb140096cffc51e3111fa2f6fcae6d2df77e Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 27 Apr 2020 12:15:07 +0000 Subject: [PATCH 334/387] net: lpc-enet: fix error return code in lpc_mii_init() [ Upstream commit 88ec7cb22ddde725ed4ce15991f0bd9dd817fd85 ] Fix to return a negative error code from the error handling case instead of 0, as done elsewhere in this function. Fixes: b7370112f519 ("lpc32xx: Added ethernet driver") Signed-off-by: Wei Yongjun Acked-by: Vladimir Zapolskiy Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/nxp/lpc_eth.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c index 9fcaf1910633..9b98ec3dcb82 100644 --- a/drivers/net/ethernet/nxp/lpc_eth.c +++ b/drivers/net/ethernet/nxp/lpc_eth.c @@ -845,7 +845,8 @@ static int lpc_mii_init(struct netdata_local *pldat) if (mdiobus_register(pldat->mii_bus)) goto err_out_unregister_bus; - if (lpc_mii_probe(pldat->ndev) != 0) + err = lpc_mii_probe(pldat->ndev); + if (err) goto err_out_unregister_bus; return 0; From 720b4f27b187e50df1217a35d686ed09cbe06c75 Mon Sep 17 00:00:00 2001 From: Yunjian Wang Date: Tue, 5 May 2020 10:49:20 +0800 Subject: [PATCH 335/387] net: allwinner: Fix use correct return type for ndo_start_xmit() [ Upstream commit 09f6c44aaae0f1bdb8b983d7762676d5018c53bc ] The method ndo_start_xmit() returns a value of type netdev_tx_t. Fix the ndo function to use the correct type. And emac_start_xmit() can leak one skb if 'channel' == 3. Signed-off-by: Yunjian Wang Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/allwinner/sun4i-emac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c index 6ffdff68bfc4..672a8212c8d9 100644 --- a/drivers/net/ethernet/allwinner/sun4i-emac.c +++ b/drivers/net/ethernet/allwinner/sun4i-emac.c @@ -412,7 +412,7 @@ static void emac_timeout(struct net_device *dev) /* Hardware start transmission. * Send a packet to media from the upper layer. */ -static int emac_start_xmit(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t emac_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct emac_board_info *db = netdev_priv(dev); unsigned long channel; @@ -420,7 +420,7 @@ static int emac_start_xmit(struct sk_buff *skb, struct net_device *dev) channel = db->tx_fifo_stat & 3; if (channel == 3) - return 1; + return NETDEV_TX_BUSY; channel = (channel == 1 ? 1 : 0); From 123a8d0b68ac0159e5ab4ecf61701bd9fb42c7f9 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Tue, 5 May 2020 12:12:50 +0200 Subject: [PATCH 336/387] powerpc/spufs: fix copy_to_user while atomic [ Upstream commit 88413a6bfbbe2f648df399b62f85c934460b7a4d ] Currently, we may perform a copy_to_user (through simple_read_from_buffer()) while holding a context's register_lock, while accessing the context save area. This change uses a temporary buffer for the context save area data, which we then pass to simple_read_from_buffer. Includes changes from Christoph Hellwig . Fixes: bf1ab978be23 ("[POWERPC] coredump: Add SPU elf notes to coredump.") Signed-off-by: Jeremy Kerr Reviewed-by: Arnd Bergmann [hch: renamed to function to avoid ___-prefixes] Signed-off-by: Christoph Hellwig Signed-off-by: Al Viro Signed-off-by: Sasha Levin --- arch/powerpc/platforms/cell/spufs/file.c | 113 +++++++++++++++-------- 1 file changed, 75 insertions(+), 38 deletions(-) diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 06254467e4dd..f12b00a056cb 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -2044,8 +2044,9 @@ static ssize_t __spufs_mbox_info_read(struct spu_context *ctx, static ssize_t spufs_mbox_info_read(struct file *file, char __user *buf, size_t len, loff_t *pos) { - int ret; struct spu_context *ctx = file->private_data; + u32 stat, data; + int ret; if (!access_ok(VERIFY_WRITE, buf, len)) return -EFAULT; @@ -2054,11 +2055,16 @@ static ssize_t spufs_mbox_info_read(struct file *file, char __user *buf, if (ret) return ret; spin_lock(&ctx->csa.register_lock); - ret = __spufs_mbox_info_read(ctx, buf, len, pos); + stat = ctx->csa.prob.mb_stat_R; + data = ctx->csa.prob.pu_mb_R; spin_unlock(&ctx->csa.register_lock); spu_release_saved(ctx); - return ret; + /* EOF if there's no entry in the mbox */ + if (!(stat & 0x0000ff)) + return 0; + + return simple_read_from_buffer(buf, len, pos, &data, sizeof(data)); } static const struct file_operations spufs_mbox_info_fops = { @@ -2085,6 +2091,7 @@ static ssize_t spufs_ibox_info_read(struct file *file, char __user *buf, size_t len, loff_t *pos) { struct spu_context *ctx = file->private_data; + u32 stat, data; int ret; if (!access_ok(VERIFY_WRITE, buf, len)) @@ -2094,11 +2101,16 @@ static ssize_t spufs_ibox_info_read(struct file *file, char __user *buf, if (ret) return ret; spin_lock(&ctx->csa.register_lock); - ret = __spufs_ibox_info_read(ctx, buf, len, pos); + stat = ctx->csa.prob.mb_stat_R; + data = ctx->csa.priv2.puint_mb_R; spin_unlock(&ctx->csa.register_lock); spu_release_saved(ctx); - return ret; + /* EOF if there's no entry in the ibox */ + if (!(stat & 0xff0000)) + return 0; + + return simple_read_from_buffer(buf, len, pos, &data, sizeof(data)); } static const struct file_operations spufs_ibox_info_fops = { @@ -2107,6 +2119,11 @@ static const struct file_operations spufs_ibox_info_fops = { .llseek = generic_file_llseek, }; +static size_t spufs_wbox_info_cnt(struct spu_context *ctx) +{ + return (4 - ((ctx->csa.prob.mb_stat_R & 0x00ff00) >> 8)) * sizeof(u32); +} + static ssize_t __spufs_wbox_info_read(struct spu_context *ctx, char __user *buf, size_t len, loff_t *pos) { @@ -2115,7 +2132,7 @@ static ssize_t __spufs_wbox_info_read(struct spu_context *ctx, u32 wbox_stat; wbox_stat = ctx->csa.prob.mb_stat_R; - cnt = 4 - ((wbox_stat & 0x00ff00) >> 8); + cnt = spufs_wbox_info_cnt(ctx); for (i = 0; i < cnt; i++) { data[i] = ctx->csa.spu_mailbox_data[i]; } @@ -2128,7 +2145,8 @@ static ssize_t spufs_wbox_info_read(struct file *file, char __user *buf, size_t len, loff_t *pos) { struct spu_context *ctx = file->private_data; - int ret; + u32 data[ARRAY_SIZE(ctx->csa.spu_mailbox_data)]; + int ret, count; if (!access_ok(VERIFY_WRITE, buf, len)) return -EFAULT; @@ -2137,11 +2155,13 @@ static ssize_t spufs_wbox_info_read(struct file *file, char __user *buf, if (ret) return ret; spin_lock(&ctx->csa.register_lock); - ret = __spufs_wbox_info_read(ctx, buf, len, pos); + count = spufs_wbox_info_cnt(ctx); + memcpy(&data, &ctx->csa.spu_mailbox_data, sizeof(data)); spin_unlock(&ctx->csa.register_lock); spu_release_saved(ctx); - return ret; + return simple_read_from_buffer(buf, len, pos, &data, + count * sizeof(u32)); } static const struct file_operations spufs_wbox_info_fops = { @@ -2150,27 +2170,33 @@ static const struct file_operations spufs_wbox_info_fops = { .llseek = generic_file_llseek, }; -static ssize_t __spufs_dma_info_read(struct spu_context *ctx, - char __user *buf, size_t len, loff_t *pos) +static void spufs_get_dma_info(struct spu_context *ctx, + struct spu_dma_info *info) { - struct spu_dma_info info; - struct mfc_cq_sr *qp, *spuqp; int i; - info.dma_info_type = ctx->csa.priv2.spu_tag_status_query_RW; - info.dma_info_mask = ctx->csa.lscsa->tag_mask.slot[0]; - info.dma_info_status = ctx->csa.spu_chnldata_RW[24]; - info.dma_info_stall_and_notify = ctx->csa.spu_chnldata_RW[25]; - info.dma_info_atomic_command_status = ctx->csa.spu_chnldata_RW[27]; + info->dma_info_type = ctx->csa.priv2.spu_tag_status_query_RW; + info->dma_info_mask = ctx->csa.lscsa->tag_mask.slot[0]; + info->dma_info_status = ctx->csa.spu_chnldata_RW[24]; + info->dma_info_stall_and_notify = ctx->csa.spu_chnldata_RW[25]; + info->dma_info_atomic_command_status = ctx->csa.spu_chnldata_RW[27]; for (i = 0; i < 16; i++) { - qp = &info.dma_info_command_data[i]; - spuqp = &ctx->csa.priv2.spuq[i]; + struct mfc_cq_sr *qp = &info->dma_info_command_data[i]; + struct mfc_cq_sr *spuqp = &ctx->csa.priv2.spuq[i]; qp->mfc_cq_data0_RW = spuqp->mfc_cq_data0_RW; qp->mfc_cq_data1_RW = spuqp->mfc_cq_data1_RW; qp->mfc_cq_data2_RW = spuqp->mfc_cq_data2_RW; qp->mfc_cq_data3_RW = spuqp->mfc_cq_data3_RW; } +} + +static ssize_t __spufs_dma_info_read(struct spu_context *ctx, + char __user *buf, size_t len, loff_t *pos) +{ + struct spu_dma_info info; + + spufs_get_dma_info(ctx, &info); return simple_read_from_buffer(buf, len, pos, &info, sizeof info); @@ -2180,6 +2206,7 @@ static ssize_t spufs_dma_info_read(struct file *file, char __user *buf, size_t len, loff_t *pos) { struct spu_context *ctx = file->private_data; + struct spu_dma_info info; int ret; if (!access_ok(VERIFY_WRITE, buf, len)) @@ -2189,11 +2216,12 @@ static ssize_t spufs_dma_info_read(struct file *file, char __user *buf, if (ret) return ret; spin_lock(&ctx->csa.register_lock); - ret = __spufs_dma_info_read(ctx, buf, len, pos); + spufs_get_dma_info(ctx, &info); spin_unlock(&ctx->csa.register_lock); spu_release_saved(ctx); - return ret; + return simple_read_from_buffer(buf, len, pos, &info, + sizeof(info)); } static const struct file_operations spufs_dma_info_fops = { @@ -2202,13 +2230,31 @@ static const struct file_operations spufs_dma_info_fops = { .llseek = no_llseek, }; +static void spufs_get_proxydma_info(struct spu_context *ctx, + struct spu_proxydma_info *info) +{ + int i; + + info->proxydma_info_type = ctx->csa.prob.dma_querytype_RW; + info->proxydma_info_mask = ctx->csa.prob.dma_querymask_RW; + info->proxydma_info_status = ctx->csa.prob.dma_tagstatus_R; + + for (i = 0; i < 8; i++) { + struct mfc_cq_sr *qp = &info->proxydma_info_command_data[i]; + struct mfc_cq_sr *puqp = &ctx->csa.priv2.puq[i]; + + qp->mfc_cq_data0_RW = puqp->mfc_cq_data0_RW; + qp->mfc_cq_data1_RW = puqp->mfc_cq_data1_RW; + qp->mfc_cq_data2_RW = puqp->mfc_cq_data2_RW; + qp->mfc_cq_data3_RW = puqp->mfc_cq_data3_RW; + } +} + static ssize_t __spufs_proxydma_info_read(struct spu_context *ctx, char __user *buf, size_t len, loff_t *pos) { struct spu_proxydma_info info; - struct mfc_cq_sr *qp, *puqp; int ret = sizeof info; - int i; if (len < ret) return -EINVAL; @@ -2216,18 +2262,7 @@ static ssize_t __spufs_proxydma_info_read(struct spu_context *ctx, if (!access_ok(VERIFY_WRITE, buf, len)) return -EFAULT; - info.proxydma_info_type = ctx->csa.prob.dma_querytype_RW; - info.proxydma_info_mask = ctx->csa.prob.dma_querymask_RW; - info.proxydma_info_status = ctx->csa.prob.dma_tagstatus_R; - for (i = 0; i < 8; i++) { - qp = &info.proxydma_info_command_data[i]; - puqp = &ctx->csa.priv2.puq[i]; - - qp->mfc_cq_data0_RW = puqp->mfc_cq_data0_RW; - qp->mfc_cq_data1_RW = puqp->mfc_cq_data1_RW; - qp->mfc_cq_data2_RW = puqp->mfc_cq_data2_RW; - qp->mfc_cq_data3_RW = puqp->mfc_cq_data3_RW; - } + spufs_get_proxydma_info(ctx, &info); return simple_read_from_buffer(buf, len, pos, &info, sizeof info); @@ -2237,17 +2272,19 @@ static ssize_t spufs_proxydma_info_read(struct file *file, char __user *buf, size_t len, loff_t *pos) { struct spu_context *ctx = file->private_data; + struct spu_proxydma_info info; int ret; ret = spu_acquire_saved(ctx); if (ret) return ret; spin_lock(&ctx->csa.register_lock); - ret = __spufs_proxydma_info_read(ctx, buf, len, pos); + spufs_get_proxydma_info(ctx, &info); spin_unlock(&ctx->csa.register_lock); spu_release_saved(ctx); - return ret; + return simple_read_from_buffer(buf, len, pos, &info, + sizeof(info)); } static const struct file_operations spufs_proxydma_info_fops = { From 8b01fb175d6bdaa0ca963bfb8f18c79b04ab36c4 Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Wed, 6 May 2020 13:52:45 +0800 Subject: [PATCH 337/387] MIPS: Truncate link address into 32bit for 32bit kernel [ Upstream commit ff487d41036035376e47972c7c522490b839ab37 ] LLD failed to link vmlinux with 64bit load address for 32bit ELF while bfd will strip 64bit address into 32bit silently. To fix LLD build, we should truncate load address provided by platform into 32bit for 32bit kernel. Signed-off-by: Jiaxun Yang Link: https://github.com/ClangBuiltLinux/linux/issues/786 Link: https://sourceware.org/bugzilla/show_bug.cgi?id=25784 Reviewed-by: Fangrui Song Reviewed-by: Kees Cook Tested-by: Nathan Chancellor Cc: Maciej W. Rozycki Tested-by: Nick Desaulniers Signed-off-by: Thomas Bogendoerfer Signed-off-by: Sasha Levin --- arch/mips/Makefile | 13 ++++++++++++- arch/mips/boot/compressed/Makefile | 2 +- arch/mips/kernel/vmlinux.lds.S | 2 +- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 1a6bac7b076f..25f3bfef9b39 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -256,12 +256,23 @@ ifdef CONFIG_64BIT endif endif +# When linking a 32-bit executable the LLVM linker cannot cope with a +# 32-bit load address that has been sign-extended to 64 bits. Simply +# remove the upper 32 bits then, as it is safe to do so with other +# linkers. +ifdef CONFIG_64BIT + load-ld = $(load-y) +else + load-ld = $(subst 0xffffffff,0x,$(load-y)) +endif + KBUILD_AFLAGS += $(cflags-y) KBUILD_CFLAGS += $(cflags-y) -KBUILD_CPPFLAGS += -DVMLINUX_LOAD_ADDRESS=$(load-y) +KBUILD_CPPFLAGS += -DVMLINUX_LOAD_ADDRESS=$(load-y) -DLINKER_LOAD_ADDRESS=$(load-ld) KBUILD_CPPFLAGS += -DDATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0) bootvars-y = VMLINUX_LOAD_ADDRESS=$(load-y) \ + LINKER_LOAD_ADDRESS=$(load-ld) \ VMLINUX_ENTRY_ADDRESS=$(entry-y) \ PLATFORM="$(platform-y)" ifdef CONFIG_32BIT diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile index 2f77e250b91d..0fa91c981658 100644 --- a/arch/mips/boot/compressed/Makefile +++ b/arch/mips/boot/compressed/Makefile @@ -87,7 +87,7 @@ ifneq ($(zload-y),) VMLINUZ_LOAD_ADDRESS := $(zload-y) else VMLINUZ_LOAD_ADDRESS = $(shell $(obj)/calc_vmlinuz_load_addr \ - $(obj)/vmlinux.bin $(VMLINUX_LOAD_ADDRESS)) + $(obj)/vmlinux.bin $(LINKER_LOAD_ADDRESS)) endif vmlinuzobjs-y += $(obj)/piggy.o diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 2d965d91fee4..612b2b301280 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -49,7 +49,7 @@ SECTIONS /* . = 0xa800000000300000; */ . = 0xffffffff80300000; #endif - . = VMLINUX_LOAD_ADDRESS; + . = LINKER_LOAD_ADDRESS; /* read-only */ _text = .; /* Text and read-only data */ .text : { From bb3bcde17baaf703b43646519c85f47cf343766e Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Wed, 6 May 2020 20:42:22 +0300 Subject: [PATCH 338/387] mips: cm: Fix an invalid error code of INTVN_*_ERR [ Upstream commit 8a0efb8b101665a843205eab3d67ab09cb2d9a8d ] Commit 3885c2b463f6 ("MIPS: CM: Add support for reporting CM cache errors") adds cm2_causes[] array with map of error type ID and pointers to the short description string. There is a mistake in the table, since according to MIPS32 manual CM2_ERROR_TYPE = {17,18} correspond to INTVN_WR_ERR and INTVN_RD_ERR, while the table claims they have {0x17,0x18} codes. This is obviously hex-dec copy-paste bug. Moreover codes {0x18 - 0x1a} indicate L2 ECC errors. Fixes: 3885c2b463f6 ("MIPS: CM: Add support for reporting CM cache errors") Signed-off-by: Serge Semin Cc: Alexey Malahov Cc: Thomas Bogendoerfer Cc: Paul Burton Cc: Ralf Baechle Cc: Arnd Bergmann Cc: Rob Herring Cc: linux-pm@vger.kernel.org Cc: devicetree@vger.kernel.org Signed-off-by: Thomas Bogendoerfer Signed-off-by: Sasha Levin --- arch/mips/kernel/mips-cm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c index 60177a612cb1..df65516778a2 100644 --- a/arch/mips/kernel/mips-cm.c +++ b/arch/mips/kernel/mips-cm.c @@ -123,9 +123,9 @@ static char *cm2_causes[32] = { "COH_RD_ERR", "MMIO_WR_ERR", "MMIO_RD_ERR", "0x07", "0x08", "0x09", "0x0a", "0x0b", "0x0c", "0x0d", "0x0e", "0x0f", - "0x10", "0x11", "0x12", "0x13", - "0x14", "0x15", "0x16", "INTVN_WR_ERR", - "INTVN_RD_ERR", "0x19", "0x1a", "0x1b", + "0x10", "INTVN_WR_ERR", "INTVN_RD_ERR", "0x13", + "0x14", "0x15", "0x16", "0x17", + "0x18", "0x19", "0x1a", "0x1b", "0x1c", "0x1d", "0x1e", "0x1f" }; From fb228bf21e21a594d68eba1ff3b3236a0fef9cb4 Mon Sep 17 00:00:00 2001 From: Daniel Thompson Date: Wed, 6 May 2020 17:42:23 +0100 Subject: [PATCH 339/387] kgdb: Fix spurious true from in_dbg_master() [ Upstream commit 3fec4aecb311995189217e64d725cfe84a568de3 ] Currently there is a small window where a badly timed migration could cause in_dbg_master() to spuriously return true. Specifically if we migrate to a new core after reading the processor id and the previous core takes a breakpoint then we will evaluate true if we read kgdb_active before we get the IPI to bring us to halt. Fix this by checking irqs_disabled() first. Interrupts are always disabled when we are executing the kgdb trap so this is an acceptable prerequisite. This also allows us to replace raw_smp_processor_id() with smp_processor_id() since the short circuit logic will prevent warnings from PREEMPT_DEBUG. Fixes: dcc7871128e9 ("kgdb: core changes to support kdb") Suggested-by: Will Deacon Link: https://lore.kernel.org/r/20200506164223.2875760-1-daniel.thompson@linaro.org Reviewed-by: Douglas Anderson Signed-off-by: Daniel Thompson Signed-off-by: Sasha Levin --- include/linux/kgdb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h index e465bb15912d..6be5545d3584 100644 --- a/include/linux/kgdb.h +++ b/include/linux/kgdb.h @@ -317,7 +317,7 @@ extern void gdbstub_exit(int status); extern int kgdb_single_step; extern atomic_t kgdb_active; #define in_dbg_master() \ - (raw_smp_processor_id() == atomic_read(&kgdb_active)) + (irqs_disabled() && (smp_processor_id() == atomic_read(&kgdb_active))) extern bool dbg_is_early; extern void __init dbg_late_init(void); #else /* ! CONFIG_KGDB */ From 9e9b57c4a2445f1174306a26e4ebe732c1ef2fae Mon Sep 17 00:00:00 2001 From: Guoqing Jiang Date: Sat, 4 Apr 2020 23:57:09 +0200 Subject: [PATCH 340/387] md: don't flush workqueue unconditionally in md_open [ Upstream commit f6766ff6afff70e2aaf39e1511e16d471de7c3ae ] We need to check mddev->del_work before flush workqueu since the purpose of flush is to ensure the previous md is disappeared. Otherwise the similar deadlock appeared if LOCKDEP is enabled, it is due to md_open holds the bdev->bd_mutex before flush workqueue. kernel: [ 154.522645] ====================================================== kernel: [ 154.522647] WARNING: possible circular locking dependency detected kernel: [ 154.522650] 5.6.0-rc7-lp151.27-default #25 Tainted: G O kernel: [ 154.522651] ------------------------------------------------------ kernel: [ 154.522653] mdadm/2482 is trying to acquire lock: kernel: [ 154.522655] ffff888078529128 ((wq_completion)md_misc){+.+.}, at: flush_workqueue+0x84/0x4b0 kernel: [ 154.522673] kernel: [ 154.522673] but task is already holding lock: kernel: [ 154.522675] ffff88804efa9338 (&bdev->bd_mutex){+.+.}, at: __blkdev_get+0x79/0x590 kernel: [ 154.522691] kernel: [ 154.522691] which lock already depends on the new lock. kernel: [ 154.522691] kernel: [ 154.522694] kernel: [ 154.522694] the existing dependency chain (in reverse order) is: kernel: [ 154.522696] kernel: [ 154.522696] -> #4 (&bdev->bd_mutex){+.+.}: kernel: [ 154.522704] __mutex_lock+0x87/0x950 kernel: [ 154.522706] __blkdev_get+0x79/0x590 kernel: [ 154.522708] blkdev_get+0x65/0x140 kernel: [ 154.522709] blkdev_get_by_dev+0x2f/0x40 kernel: [ 154.522716] lock_rdev+0x3d/0x90 [md_mod] kernel: [ 154.522719] md_import_device+0xd6/0x1b0 [md_mod] kernel: [ 154.522723] new_dev_store+0x15e/0x210 [md_mod] kernel: [ 154.522728] md_attr_store+0x7a/0xc0 [md_mod] kernel: [ 154.522732] kernfs_fop_write+0x117/0x1b0 kernel: [ 154.522735] vfs_write+0xad/0x1a0 kernel: [ 154.522737] ksys_write+0xa4/0xe0 kernel: [ 154.522745] do_syscall_64+0x64/0x2b0 kernel: [ 154.522748] entry_SYSCALL_64_after_hwframe+0x49/0xbe kernel: [ 154.522749] kernel: [ 154.522749] -> #3 (&mddev->reconfig_mutex){+.+.}: kernel: [ 154.522752] __mutex_lock+0x87/0x950 kernel: [ 154.522756] new_dev_store+0xc9/0x210 [md_mod] kernel: [ 154.522759] md_attr_store+0x7a/0xc0 [md_mod] kernel: [ 154.522761] kernfs_fop_write+0x117/0x1b0 kernel: [ 154.522763] vfs_write+0xad/0x1a0 kernel: [ 154.522765] ksys_write+0xa4/0xe0 kernel: [ 154.522767] do_syscall_64+0x64/0x2b0 kernel: [ 154.522769] entry_SYSCALL_64_after_hwframe+0x49/0xbe kernel: [ 154.522770] kernel: [ 154.522770] -> #2 (kn->count#253){++++}: kernel: [ 154.522775] __kernfs_remove+0x253/0x2c0 kernel: [ 154.522778] kernfs_remove+0x1f/0x30 kernel: [ 154.522780] kobject_del+0x28/0x60 kernel: [ 154.522783] mddev_delayed_delete+0x24/0x30 [md_mod] kernel: [ 154.522786] process_one_work+0x2a7/0x5f0 kernel: [ 154.522788] worker_thread+0x2d/0x3d0 kernel: [ 154.522793] kthread+0x117/0x130 kernel: [ 154.522795] ret_from_fork+0x3a/0x50 kernel: [ 154.522796] kernel: [ 154.522796] -> #1 ((work_completion)(&mddev->del_work)){+.+.}: kernel: [ 154.522800] process_one_work+0x27e/0x5f0 kernel: [ 154.522802] worker_thread+0x2d/0x3d0 kernel: [ 154.522804] kthread+0x117/0x130 kernel: [ 154.522806] ret_from_fork+0x3a/0x50 kernel: [ 154.522807] kernel: [ 154.522807] -> #0 ((wq_completion)md_misc){+.+.}: kernel: [ 154.522813] __lock_acquire+0x1392/0x1690 kernel: [ 154.522816] lock_acquire+0xb4/0x1a0 kernel: [ 154.522818] flush_workqueue+0xab/0x4b0 kernel: [ 154.522821] md_open+0xb6/0xc0 [md_mod] kernel: [ 154.522823] __blkdev_get+0xea/0x590 kernel: [ 154.522825] blkdev_get+0x65/0x140 kernel: [ 154.522828] do_dentry_open+0x1d1/0x380 kernel: [ 154.522831] path_openat+0x567/0xcc0 kernel: [ 154.522834] do_filp_open+0x9b/0x110 kernel: [ 154.522836] do_sys_openat2+0x201/0x2a0 kernel: [ 154.522838] do_sys_open+0x57/0x80 kernel: [ 154.522840] do_syscall_64+0x64/0x2b0 kernel: [ 154.522842] entry_SYSCALL_64_after_hwframe+0x49/0xbe kernel: [ 154.522844] kernel: [ 154.522844] other info that might help us debug this: kernel: [ 154.522844] kernel: [ 154.522846] Chain exists of: kernel: [ 154.522846] (wq_completion)md_misc --> &mddev->reconfig_mutex --> &bdev->bd_mutex kernel: [ 154.522846] kernel: [ 154.522850] Possible unsafe locking scenario: kernel: [ 154.522850] kernel: [ 154.522852] CPU0 CPU1 kernel: [ 154.522853] ---- ---- kernel: [ 154.522854] lock(&bdev->bd_mutex); kernel: [ 154.522856] lock(&mddev->reconfig_mutex); kernel: [ 154.522858] lock(&bdev->bd_mutex); kernel: [ 154.522860] lock((wq_completion)md_misc); kernel: [ 154.522861] kernel: [ 154.522861] *** DEADLOCK *** kernel: [ 154.522861] kernel: [ 154.522864] 1 lock held by mdadm/2482: kernel: [ 154.522865] #0: ffff88804efa9338 (&bdev->bd_mutex){+.+.}, at: __blkdev_get+0x79/0x590 kernel: [ 154.522868] kernel: [ 154.522868] stack backtrace: kernel: [ 154.522873] CPU: 1 PID: 2482 Comm: mdadm Tainted: G O 5.6.0-rc7-lp151.27-default #25 kernel: [ 154.522875] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014 kernel: [ 154.522878] Call Trace: kernel: [ 154.522881] dump_stack+0x8f/0xcb kernel: [ 154.522884] check_noncircular+0x194/0x1b0 kernel: [ 154.522888] ? __lock_acquire+0x1392/0x1690 kernel: [ 154.522890] __lock_acquire+0x1392/0x1690 kernel: [ 154.522893] lock_acquire+0xb4/0x1a0 kernel: [ 154.522895] ? flush_workqueue+0x84/0x4b0 kernel: [ 154.522898] flush_workqueue+0xab/0x4b0 kernel: [ 154.522900] ? flush_workqueue+0x84/0x4b0 kernel: [ 154.522905] ? md_open+0xb6/0xc0 [md_mod] kernel: [ 154.522908] md_open+0xb6/0xc0 [md_mod] kernel: [ 154.522910] __blkdev_get+0xea/0x590 kernel: [ 154.522912] ? bd_acquire+0xc0/0xc0 kernel: [ 154.522914] blkdev_get+0x65/0x140 kernel: [ 154.522916] ? bd_acquire+0xc0/0xc0 kernel: [ 154.522918] do_dentry_open+0x1d1/0x380 kernel: [ 154.522921] path_openat+0x567/0xcc0 kernel: [ 154.522923] ? __lock_acquire+0x380/0x1690 kernel: [ 154.522926] do_filp_open+0x9b/0x110 kernel: [ 154.522929] ? __alloc_fd+0xe5/0x1f0 kernel: [ 154.522935] ? kmem_cache_alloc+0x28c/0x630 kernel: [ 154.522939] ? do_sys_openat2+0x201/0x2a0 kernel: [ 154.522941] do_sys_openat2+0x201/0x2a0 kernel: [ 154.522944] do_sys_open+0x57/0x80 kernel: [ 154.522946] do_syscall_64+0x64/0x2b0 kernel: [ 154.522948] entry_SYSCALL_64_after_hwframe+0x49/0xbe kernel: [ 154.522951] RIP: 0033:0x7f98d279d9ae And md_alloc also flushed the same workqueue, but the thing is different here. Because all the paths call md_alloc don't hold bdev->bd_mutex, and the flush is necessary to avoid race condition, so leave it as it is. Signed-off-by: Guoqing Jiang Signed-off-by: Song Liu Signed-off-by: Sasha Levin --- drivers/md/md.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index da8708b65356..3485d2a79600 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -7101,7 +7101,8 @@ static int md_open(struct block_device *bdev, fmode_t mode) */ mddev_put(mddev); /* Wait until bdev->bd_disk is definitely gone */ - flush_workqueue(md_misc_wq); + if (work_pending(&mddev->del_work)) + flush_workqueue(md_misc_wq); /* Then retry the open from the top */ return -ERESTARTSYS; } From 5f78833e82a6de3e629a6b2100663ca0d451e172 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 13 May 2020 12:39:51 +0300 Subject: [PATCH 341/387] rtlwifi: Fix a double free in _rtl_usb_tx_urb_setup() [ Upstream commit beb12813bc75d4a23de43b85ad1c7cb28d27631e ] Seven years ago we tried to fix a leak but actually introduced a double free instead. It was an understandable mistake because the code was a bit confusing and the free was done in the wrong place. The "skb" pointer is freed in both _rtl_usb_tx_urb_setup() and _rtl_usb_transmit(). The free belongs _rtl_usb_transmit() instead of _rtl_usb_tx_urb_setup() and I've cleaned the code up a bit to hopefully make it more clear. Fixes: 36ef0b473fbf ("rtlwifi: usb: add missing freeing of skbuff") Signed-off-by: Dan Carpenter Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200513093951.GD347693@mwanda Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtlwifi/usb.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/usb.c b/drivers/net/wireless/realtek/rtlwifi/usb.c index 1f02461de261..93b22a5b6878 100644 --- a/drivers/net/wireless/realtek/rtlwifi/usb.c +++ b/drivers/net/wireless/realtek/rtlwifi/usb.c @@ -927,10 +927,8 @@ static struct urb *_rtl_usb_tx_urb_setup(struct ieee80211_hw *hw, WARN_ON(NULL == skb); _urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!_urb) { - kfree_skb(skb); + if (!_urb) return NULL; - } _rtl_install_trx_info(rtlusb, skb, ep_num); usb_fill_bulk_urb(_urb, rtlusb->udev, usb_sndbulkpipe(rtlusb->udev, ep_num), skb->data, skb->len, _rtl_tx_complete, skb); @@ -945,7 +943,6 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb, struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); u32 ep_num; struct urb *_urb = NULL; - struct sk_buff *_skb = NULL; WARN_ON(NULL == rtlusb->usb_tx_aggregate_hdl); if (unlikely(IS_USB_STOP(rtlusb))) { @@ -955,8 +952,7 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb, return; } ep_num = rtlusb->ep_map.ep_mapping[qnum]; - _skb = skb; - _urb = _rtl_usb_tx_urb_setup(hw, _skb, ep_num); + _urb = _rtl_usb_tx_urb_setup(hw, skb, ep_num); if (unlikely(!_urb)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't allocate urb. Drop skb!\n"); From 33c2268e8ccd4351a95e434cf52b46594b58dbb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 15 May 2020 09:59:24 +0200 Subject: [PATCH 342/387] mwifiex: Fix memory corruption in dump_station MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 3aa42bae9c4d1641aeb36f1a8585cd1d506cf471 ] The mwifiex_cfg80211_dump_station() uses static variable for iterating over a linked list of all associated stations (when the driver is in UAP role). This has a race condition if .dump_station is called in parallel for multiple interfaces. This corruption can be triggered by registering multiple SSIDs and calling, in parallel for multiple interfaces iw dev station dump [16750.719775] Unable to handle kernel paging request at virtual address dead000000000110 ... [16750.899173] Call trace: [16750.901696] mwifiex_cfg80211_dump_station+0x94/0x100 [mwifiex] [16750.907824] nl80211_dump_station+0xbc/0x278 [cfg80211] [16750.913160] netlink_dump+0xe8/0x320 [16750.916827] netlink_recvmsg+0x1b4/0x338 [16750.920861] ____sys_recvmsg+0x7c/0x2b0 [16750.924801] ___sys_recvmsg+0x70/0x98 [16750.928564] __sys_recvmsg+0x58/0xa0 [16750.932238] __arm64_sys_recvmsg+0x28/0x30 [16750.936453] el0_svc_common.constprop.3+0x90/0x158 [16750.941378] do_el0_svc+0x74/0x90 [16750.944784] el0_sync_handler+0x12c/0x1a8 [16750.948903] el0_sync+0x114/0x140 [16750.952312] Code: f9400003 f907f423 eb02007f 54fffd60 (b9401060) [16750.958583] ---[ end trace c8ad181c2f4b8576 ]--- This patch drops the use of the static iterator, and instead every time the function is called iterates to the idx-th position of the linked-list. It would be better to convert the code not to use linked list for associated stations storage (since the chip has a limited number of associated stations anyway - it could just be an array). Such a change may be proposed in the future. In the meantime this patch can backported into stable kernels in this simple form. Fixes: 8baca1a34d4c ("mwifiex: dump station support in uap mode") Signed-off-by: Pali Rohár Acked-by: Ganapathi Bhat Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200515075924.13841-1-pali@kernel.org Signed-off-by: Sasha Levin --- drivers/net/wireless/marvell/mwifiex/cfg80211.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c index 94901b0041ce..c597af69f48f 100644 --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c @@ -1446,7 +1446,8 @@ mwifiex_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *dev, int idx, u8 *mac, struct station_info *sinfo) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); - static struct mwifiex_sta_node *node; + struct mwifiex_sta_node *node; + int i; if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && priv->media_connected && idx == 0) { @@ -1456,13 +1457,10 @@ mwifiex_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *dev, mwifiex_send_cmd(priv, HOST_CMD_APCMD_STA_LIST, HostCmd_ACT_GEN_GET, 0, NULL, true); - if (node && (&node->list == &priv->sta_list)) { - node = NULL; - return -ENOENT; - } - - node = list_prepare_entry(node, &priv->sta_list, list); - list_for_each_entry_continue(node, &priv->sta_list, list) { + i = 0; + list_for_each_entry(node, &priv->sta_list, list) { + if (i++ != idx) + continue; ether_addr_copy(mac, node->mac_addr); return mwifiex_dump_station_info(priv, node, sinfo); } From 93b6bebee07976327189940a17ecfd626ba57f09 Mon Sep 17 00:00:00 2001 From: Arvind Sankar Date: Fri, 7 Feb 2020 16:49:26 -0500 Subject: [PATCH 343/387] x86/boot: Correct relocation destination on old linkers [ Upstream commit 5214028dd89e49ba27007c3ee475279e584261f0 ] For the 32-bit kernel, as described in 6d92bc9d483a ("x86/build: Build compressed x86 kernels as PIE"), pre-2.26 binutils generates R_386_32 relocations in PIE mode. Since the startup code does not perform relocation, any reloc entry with R_386_32 will remain as 0 in the executing code. Commit 974f221c84b0 ("x86/boot: Move compressed kernel to the end of the decompression buffer") added a new symbol _end but did not mark it hidden, which doesn't give the correct offset on older linkers. This causes the compressed kernel to be copied beyond the end of the decompression buffer, rather than flush against it. This region of memory may be reserved or already allocated for other purposes by the bootloader. Mark _end as hidden to fix. This changes the relocation from R_386_32 to R_386_RELATIVE even on the pre-2.26 binutils. For 64-bit, this is not strictly necessary, as the 64-bit kernel is only built as PIE if the linker supports -z noreloc-overflow, which implies binutils-2.27+, but for consistency, mark _end as hidden here too. The below illustrates the before/after impact of the patch using binutils-2.25 and gcc-4.6.4 (locally compiled from source) and QEMU. Disassembly before patch: 48: 8b 86 60 02 00 00 mov 0x260(%esi),%eax 4e: 2d 00 00 00 00 sub $0x0,%eax 4f: R_386_32 _end Disassembly after patch: 48: 8b 86 60 02 00 00 mov 0x260(%esi),%eax 4e: 2d 00 f0 76 00 sub $0x76f000,%eax 4f: R_386_RELATIVE *ABS* Dump from extract_kernel before patch: early console in extract_kernel input_data: 0x0207c098 <--- this is at output + init_size input_len: 0x0074fef1 output: 0x01000000 output_len: 0x00fa63d0 kernel_total_size: 0x0107c000 needed_size: 0x0107c000 Dump from extract_kernel after patch: early console in extract_kernel input_data: 0x0190d098 <--- this is at output + init_size - _end input_len: 0x0074fef1 output: 0x01000000 output_len: 0x00fa63d0 kernel_total_size: 0x0107c000 needed_size: 0x0107c000 Fixes: 974f221c84b0 ("x86/boot: Move compressed kernel to the end of the decompression buffer") Signed-off-by: Arvind Sankar Signed-off-by: Borislav Petkov Link: https://lkml.kernel.org/r/20200207214926.3564079-1-nivedita@alum.mit.edu Signed-off-by: Sasha Levin --- arch/x86/boot/compressed/head_32.S | 5 +++-- arch/x86/boot/compressed/head_64.S | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index 7532f6f53677..93f41b4f05ce 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S @@ -48,16 +48,17 @@ * Position Independent Executable (PIE) so that linker won't optimize * R_386_GOT32X relocation to its fixed symbol address. Older * linkers generate R_386_32 relocations against locally defined symbols, - * _bss, _ebss, _got and _egot, in PIE. It isn't wrong, just less + * _bss, _ebss, _got, _egot and _end, in PIE. It isn't wrong, just less * optimal than R_386_RELATIVE. But the x86 kernel fails to properly handle * R_386_32 relocations when relocating the kernel. To generate - * R_386_RELATIVE relocations, we mark _bss, _ebss, _got and _egot as + * R_386_RELATIVE relocations, we mark _bss, _ebss, _got, _egot and _end as * hidden: */ .hidden _bss .hidden _ebss .hidden _got .hidden _egot + .hidden _end __HEAD ENTRY(startup_32) diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index 3fac2d133e4e..d096bcfcb3f6 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S @@ -40,6 +40,7 @@ .hidden _ebss .hidden _got .hidden _egot + .hidden _end __HEAD .code32 From b935463db5ed883eeaff0c01b775e8f10e544982 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Thu, 21 May 2020 17:07:22 +0300 Subject: [PATCH 344/387] mips: Add udelay lpj numbers adjustment [ Upstream commit ed26aacfb5f71eecb20a51c4467da440cb719d66 ] Loops-per-jiffies is a special number which represents a number of noop-loop cycles per CPU-scheduler quantum - jiffies. As you understand aside from CPU-specific implementation it depends on the CPU frequency. So when a platform has the CPU frequency fixed, we have no problem and the current udelay interface will work just fine. But as soon as CPU-freq driver is enabled and the cores frequency changes, we'll end up with distorted udelay's. In order to fix this we have to accordinly adjust the per-CPU udelay_val (the same as the global loops_per_jiffy) number. This can be done in the CPU-freq transition event handler. We subscribe to that event in the MIPS arch time-inititalization method. Co-developed-by: Alexey Malahov Signed-off-by: Alexey Malahov Signed-off-by: Serge Semin Reviewed-by: Jiaxun Yang Cc: Thomas Bogendoerfer Cc: Paul Burton Cc: Ralf Baechle Cc: Arnd Bergmann Cc: Rob Herring Cc: devicetree@vger.kernel.org Signed-off-by: Thomas Bogendoerfer Signed-off-by: Sasha Levin --- arch/mips/kernel/time.c | 70 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index a7f81261c781..b7f7e08e1ce4 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -22,12 +22,82 @@ #include #include #include +#include +#include #include #include #include #include +#ifdef CONFIG_CPU_FREQ + +static DEFINE_PER_CPU(unsigned long, pcp_lpj_ref); +static DEFINE_PER_CPU(unsigned long, pcp_lpj_ref_freq); +static unsigned long glb_lpj_ref; +static unsigned long glb_lpj_ref_freq; + +static int cpufreq_callback(struct notifier_block *nb, + unsigned long val, void *data) +{ + struct cpufreq_freqs *freq = data; + struct cpumask *cpus = freq->policy->cpus; + unsigned long lpj; + int cpu; + + /* + * Skip lpj numbers adjustment if the CPU-freq transition is safe for + * the loops delay. (Is this possible?) + */ + if (freq->flags & CPUFREQ_CONST_LOOPS) + return NOTIFY_OK; + + /* Save the initial values of the lpjes for future scaling. */ + if (!glb_lpj_ref) { + glb_lpj_ref = boot_cpu_data.udelay_val; + glb_lpj_ref_freq = freq->old; + + for_each_online_cpu(cpu) { + per_cpu(pcp_lpj_ref, cpu) = + cpu_data[cpu].udelay_val; + per_cpu(pcp_lpj_ref_freq, cpu) = freq->old; + } + } + + /* + * Adjust global lpj variable and per-CPU udelay_val number in + * accordance with the new CPU frequency. + */ + if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) || + (val == CPUFREQ_POSTCHANGE && freq->old > freq->new)) { + loops_per_jiffy = cpufreq_scale(glb_lpj_ref, + glb_lpj_ref_freq, + freq->new); + + for_each_cpu(cpu, cpus) { + lpj = cpufreq_scale(per_cpu(pcp_lpj_ref, cpu), + per_cpu(pcp_lpj_ref_freq, cpu), + freq->new); + cpu_data[cpu].udelay_val = (unsigned int)lpj; + } + } + + return NOTIFY_OK; +} + +static struct notifier_block cpufreq_notifier = { + .notifier_call = cpufreq_callback, +}; + +static int __init register_cpufreq_notifier(void) +{ + return cpufreq_register_notifier(&cpufreq_notifier, + CPUFREQ_TRANSITION_NOTIFIER); +} +core_initcall(register_cpufreq_notifier); + +#endif /* CONFIG_CPU_FREQ */ + /* * forward reference */ From eeb233a0f5e48fde8f2ac3f9347daadc7563d480 Mon Sep 17 00:00:00 2001 From: Arvind Sankar Date: Sat, 29 Feb 2020 18:11:20 -0500 Subject: [PATCH 345/387] x86/mm: Stop printing BRK addresses [ Upstream commit 67d631b7c05eff955ccff4139327f0f92a5117e5 ] This currently leaks kernel physical addresses into userspace. Signed-off-by: Arvind Sankar Signed-off-by: Borislav Petkov Acked-by: Kees Cook Acked-by: Dave Hansen Link: https://lkml.kernel.org/r/20200229231120.1147527-1-nivedita@alum.mit.edu Signed-off-by: Sasha Levin --- arch/x86/mm/init.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index ce092a62fc5d..bc2455c2fcab 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -110,8 +110,6 @@ __ref void *alloc_low_pages(unsigned int num) } else { pfn = pgt_buf_end; pgt_buf_end += num; - printk(KERN_DEBUG "BRK [%#010lx, %#010lx] PGTABLE\n", - pfn << PAGE_SHIFT, (pgt_buf_end << PAGE_SHIFT) - 1); } for (i = 0; i < num; i++) { From 04c01ac27d08fdf8933ecdf3e74fed9737e6fb55 Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Wed, 20 May 2020 14:32:02 +1000 Subject: [PATCH 346/387] m68k: mac: Don't call via_flush_cache() on Mac IIfx [ Upstream commit bcc44f6b74106b31f0b0408b70305a40360d63b7 ] There is no VIA2 chip on the Mac IIfx, so don't call via_flush_cache(). This avoids a boot crash which appeared in v5.4. printk: console [ttyS0] enabled printk: bootconsole [debug0] disabled printk: bootconsole [debug0] disabled Calibrating delay loop... 9.61 BogoMIPS (lpj=48064) pid_max: default: 32768 minimum: 301 Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear) Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear) devtmpfs: initialized random: get_random_u32 called from bucket_table_alloc.isra.27+0x68/0x194 with crng_init=0 clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns futex hash table entries: 256 (order: -1, 3072 bytes, linear) NET: Registered protocol family 16 Data read fault at 0x00000000 in Super Data (pc=0x8a6a) BAD KERNEL BUSERR Oops: 00000000 Modules linked in: PC: [<00008a6a>] via_flush_cache+0x12/0x2c SR: 2700 SP: 01c1fe3c a2: 01c24000 d0: 00001119 d1: 0000000c d2: 00012000 d3: 0000000f d4: 01c06840 d5: 00033b92 a0: 00000000 a1: 00000000 Process swapper (pid: 1, task=01c24000) Frame format=B ssw=0755 isc=0200 isb=fff7 daddr=00000000 dobuf=01c1fed0 baddr=00008a6e dibuf=0000004e ver=f Stack from 01c1fec4: 01c1fed0 00007d7e 00010080 01c1fedc 0000792e 00000001 01c1fef4 00006b40 01c80000 00040000 00000006 00000003 01c1ff1c 004a545e 004ff200 00040000 00000000 00000003 01c06840 00033b92 004a5410 004b6c88 01c1ff84 000021e2 00000073 00000003 01c06840 00033b92 0038507a 004bb094 004b6ca8 004b6c88 004b6ca4 004b6c88 000021ae 00020002 00000000 01c0685d 00000000 01c1ffb4 0049f938 00409c85 01c06840 0045bd40 00000073 00000002 00000002 00000000 Call Trace: [<00007d7e>] mac_cache_card_flush+0x12/0x1c [<00010080>] fix_dnrm+0x2/0x18 [<0000792e>] cache_push+0x46/0x5a [<00006b40>] arch_dma_prep_coherent+0x60/0x6e [<00040000>] switched_to_dl+0x76/0xd0 [<004a545e>] dma_atomic_pool_init+0x4e/0x188 [<00040000>] switched_to_dl+0x76/0xd0 [<00033b92>] parse_args+0x0/0x370 [<004a5410>] dma_atomic_pool_init+0x0/0x188 [<000021e2>] do_one_initcall+0x34/0x1be [<00033b92>] parse_args+0x0/0x370 [<0038507a>] strcpy+0x0/0x1e [<000021ae>] do_one_initcall+0x0/0x1be [<00020002>] do_proc_dointvec_conv+0x54/0x74 [<0049f938>] kernel_init_freeable+0x126/0x190 [<0049f94c>] kernel_init_freeable+0x13a/0x190 [<004a5410>] dma_atomic_pool_init+0x0/0x188 [<00041798>] complete+0x0/0x3c [<000b9b0c>] kfree+0x0/0x20a [<0038df98>] schedule+0x0/0xd0 [<0038d604>] kernel_init+0x0/0xda [<0038d610>] kernel_init+0xc/0xda [<0038d604>] kernel_init+0x0/0xda [<00002d38>] ret_from_kernel_thread+0xc/0x14 Code: 0000 2079 0048 10da 2279 0048 10c8 d3c8 <1011> 0200 fff7 1280 d1f9 0048 10c8 1010 0000 0008 1080 4e5e 4e75 4e56 0000 2039 Disabling lock debugging due to kernel taint Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b Thanks to Stan Johnson for capturing the console log and running git bisect. Git bisect said commit 8e3a68fb55e0 ("dma-mapping: make dma_atomic_pool_init self-contained") is the first "bad" commit. I don't know why. Perhaps mach_l2_flush first became reachable with that commit. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-and-tested-by: Stan Johnson Signed-off-by: Finn Thain Cc: Joshua Thompson Link: https://lore.kernel.org/r/b8bbeef197d6b3898e82ed0d231ad08f575a4b34.1589949122.git.fthain@telegraphics.com.au Signed-off-by: Geert Uytterhoeven Signed-off-by: Sasha Levin --- arch/m68k/include/asm/mac_via.h | 1 + arch/m68k/mac/config.c | 21 ++------------------- arch/m68k/mac/via.c | 6 +++++- 3 files changed, 8 insertions(+), 20 deletions(-) diff --git a/arch/m68k/include/asm/mac_via.h b/arch/m68k/include/asm/mac_via.h index 53c632c85b03..dff6db19ae4d 100644 --- a/arch/m68k/include/asm/mac_via.h +++ b/arch/m68k/include/asm/mac_via.h @@ -256,6 +256,7 @@ extern int rbv_present,via_alt_mapping; struct irq_desc; +extern void via_l2_flush(int writeback); extern void via_register_interrupts(void); extern void via_irq_enable(int); extern void via_irq_disable(int); diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c index e46895316eb0..dcf18e1ca0bb 100644 --- a/arch/m68k/mac/config.c +++ b/arch/m68k/mac/config.c @@ -61,7 +61,6 @@ extern void iop_preinit(void); extern void iop_init(void); extern void via_init(void); extern void via_init_clock(irq_handler_t func); -extern void via_flush_cache(void); extern void oss_init(void); extern void psc_init(void); extern void baboon_init(void); @@ -132,21 +131,6 @@ int __init mac_parse_bootinfo(const struct bi_record *record) return unknown; } -/* - * Flip into 24bit mode for an instant - flushes the L2 cache card. We - * have to disable interrupts for this. Our IRQ handlers will crap - * themselves if they take an IRQ in 24bit mode! - */ - -static void mac_cache_card_flush(int writeback) -{ - unsigned long flags; - - local_irq_save(flags); - via_flush_cache(); - local_irq_restore(flags); -} - void __init config_mac(void) { if (!MACH_IS_MAC) @@ -179,9 +163,8 @@ void __init config_mac(void) * not. */ - if (macintosh_config->ident == MAC_MODEL_IICI - || macintosh_config->ident == MAC_MODEL_IIFX) - mach_l2_flush = mac_cache_card_flush; + if (macintosh_config->ident == MAC_MODEL_IICI) + mach_l2_flush = via_l2_flush; } diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c index a435aced6e43..35382c1b563f 100644 --- a/arch/m68k/mac/via.c +++ b/arch/m68k/mac/via.c @@ -299,10 +299,14 @@ void via_debug_dump(void) * the system into 24-bit mode for an instant. */ -void via_flush_cache(void) +void via_l2_flush(int writeback) { + unsigned long flags; + + local_irq_save(flags); via2[gBufB] &= ~VIA2B_vMode32; via2[gBufB] |= VIA2B_vMode32; + local_irq_restore(flags); } /* From 9c8ca9eeeedac951e41f0e6ed2174a95ba141430 Mon Sep 17 00:00:00 2001 From: Alexander Sverdlin Date: Tue, 26 May 2020 14:27:51 +0200 Subject: [PATCH 347/387] macvlan: Skip loopback packets in RX handler [ Upstream commit 81f3dc9349ce0bf7b8447f147f45e70f0a5b36a6 ] Ignore loopback-originatig packets soon enough and don't try to process L2 header where it doesn't exist. The very similar br_handle_frame() in bridge code performs exactly the same check. This is an example of such ICMPv6 packet: skb len=96 headroom=40 headlen=96 tailroom=56 mac=(40,0) net=(40,40) trans=80 shinfo(txflags=0 nr_frags=0 gso(size=0 type=0 segs=0)) csum(0xae2e9a2f ip_summed=1 complete_sw=0 valid=0 level=0) hash(0xc97ebd88 sw=1 l4=1) proto=0x86dd pkttype=5 iif=24 dev name=etha01.212 feat=0x0x0000000040005000 skb headroom: 00000000: 00 7c 86 52 84 88 ff ff 00 00 00 00 00 00 08 00 skb headroom: 00000010: 45 00 00 9e 5d 5c 40 00 40 11 33 33 00 00 00 01 skb headroom: 00000020: 02 40 43 80 00 00 86 dd skb linear: 00000000: 60 09 88 bd 00 38 3a ff fe 80 00 00 00 00 00 00 skb linear: 00000010: 00 40 43 ff fe 80 00 00 ff 02 00 00 00 00 00 00 skb linear: 00000020: 00 00 00 00 00 00 00 01 86 00 61 00 40 00 00 2d skb linear: 00000030: 00 00 00 00 00 00 00 00 03 04 40 e0 00 00 01 2c skb linear: 00000040: 00 00 00 78 00 00 00 00 fd 5f 42 68 23 87 a8 81 skb linear: 00000050: 00 00 00 00 00 00 00 00 01 01 02 40 43 80 00 00 skb tailroom: 00000000: ... skb tailroom: 00000010: ... skb tailroom: 00000020: ... skb tailroom: 00000030: ... Call Trace, how it happens exactly: ... macvlan_handle_frame+0x321/0x425 [macvlan] ? macvlan_forward_source+0x110/0x110 [macvlan] __netif_receive_skb_core+0x545/0xda0 ? enqueue_task_fair+0xe5/0x8e0 ? __netif_receive_skb_one_core+0x36/0x70 __netif_receive_skb_one_core+0x36/0x70 process_backlog+0x97/0x140 net_rx_action+0x1eb/0x350 ? __hrtimer_run_queues+0x136/0x2e0 __do_softirq+0xe3/0x383 do_softirq_own_stack+0x2a/0x40 do_softirq.part.4+0x4e/0x50 netif_rx_ni+0x60/0xd0 dev_loopback_xmit+0x83/0xf0 ip6_finish_output2+0x575/0x590 [ipv6] ? ip6_cork_release.isra.1+0x64/0x90 [ipv6] ? __ip6_make_skb+0x38d/0x680 [ipv6] ? ip6_output+0x6c/0x140 [ipv6] ip6_output+0x6c/0x140 [ipv6] ip6_send_skb+0x1e/0x60 [ipv6] rawv6_sendmsg+0xc4b/0xe10 [ipv6] ? proc_put_long+0xd0/0xd0 ? rw_copy_check_uvector+0x4e/0x110 ? sock_sendmsg+0x36/0x40 sock_sendmsg+0x36/0x40 ___sys_sendmsg+0x2b6/0x2d0 ? proc_dointvec+0x23/0x30 ? addrconf_sysctl_forward+0x8d/0x250 [ipv6] ? dev_forward_change+0x130/0x130 [ipv6] ? _raw_spin_unlock+0x12/0x30 ? proc_sys_call_handler.isra.14+0x9f/0x110 ? __call_rcu+0x213/0x510 ? get_max_files+0x10/0x10 ? trace_hardirqs_on+0x2c/0xe0 ? __sys_sendmsg+0x63/0xa0 __sys_sendmsg+0x63/0xa0 do_syscall_64+0x6c/0x1e0 entry_SYSCALL_64_after_hwframe+0x49/0xbe Signed-off-by: Alexander Sverdlin Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/macvlan.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 4f582ce929f2..9dda2dc6b5e7 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -421,6 +421,10 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb) int ret; rx_handler_result_t handle_res; + /* Packets from dev_loopback_xmit() do not have L2 header, bail out */ + if (unlikely(skb->pkt_type == PACKET_LOOPBACK)) + return RX_HANDLER_PASS; + port = macvlan_port_get_rcu(skb->dev); if (is_multicast_ether_addr(eth->h_dest)) { unsigned int hash; From 97aad0ad757b65300870b2ac7974fb761445ff44 Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Tue, 26 May 2020 17:21:12 +0800 Subject: [PATCH 348/387] PCI: Don't disable decoding when mmio_always_on is set [ Upstream commit b6caa1d8c80cb71b6162cb1f1ec13aa655026c9f ] Don't disable MEM/IO decoding when a device have both non_compliant_bars and mmio_always_on. That would allow us quirk devices with junk in BARs but can't disable their decoding. Signed-off-by: Jiaxun Yang Acked-by: Bjorn Helgaas Signed-off-by: Thomas Bogendoerfer Signed-off-by: Sasha Levin --- drivers/pci/probe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 16611cf3aba4..be63f008167b 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1251,7 +1251,7 @@ int pci_setup_device(struct pci_dev *dev) /* device class may be changed after fixup */ class = dev->class >> 8; - if (dev->non_compliant_bars) { + if (dev->non_compliant_bars && !dev->mmio_always_on) { pci_read_config_word(dev, PCI_COMMAND, &cmd); if (cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { dev_info(&dev->dev, "device has non-compliant BARs; disabling IO/MEM decoding\n"); From cf4c788ecebbe11edf59f09e62893e49d1037874 Mon Sep 17 00:00:00 2001 From: YuanJunQing Date: Wed, 27 May 2020 14:11:30 +0800 Subject: [PATCH 349/387] MIPS: Fix IRQ tracing when call handle_fpe() and handle_msa_fpe() [ Upstream commit 31e1b3efa802f97a17628dde280006c4cee4ce5e ] Register "a1" is unsaved in this function, when CONFIG_TRACE_IRQFLAGS is enabled, the TRACE_IRQS_OFF macro will call trace_hardirqs_off(), and this may change register "a1". The changed register "a1" as argument will be send to do_fpe() and do_msa_fpe(). Signed-off-by: YuanJunQing Signed-off-by: Thomas Bogendoerfer Signed-off-by: Sasha Levin --- arch/mips/kernel/genex.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index ae810da4d499..59ed811eb32a 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S @@ -429,20 +429,20 @@ NESTED(nmi_handler, PT_SIZE, sp) .endm .macro __build_clear_fpe + CLI + TRACE_IRQS_OFF .set push /* gas fails to assemble cfc1 for some archs (octeon).*/ \ .set mips1 SET_HARDFLOAT cfc1 a1, fcr31 .set pop - CLI - TRACE_IRQS_OFF .endm .macro __build_clear_msa_fpe - _cfcmsa a1, MSA_CSR CLI TRACE_IRQS_OFF + _cfcmsa a1, MSA_CSR .endm .macro __build_clear_ade From bf14387351b94c376b6c55ee87b00b3dd3bb7300 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 14 Apr 2020 18:14:13 +0200 Subject: [PATCH 350/387] staging: greybus: sdio: Respect the cmd->busy_timeout from the mmc core [ Upstream commit a389087ee9f195fcf2f31cd771e9ec5f02c16650 ] Using a fixed 1s timeout for all commands is a bit problematic. For some commands it means waiting longer than needed for the timeout to expire, which may not a big issue, but still. For other commands, like for an erase (CMD38) that uses a R1B response, may require longer timeouts than 1s. In these cases, we may end up treating the command as it failed, while it just needed some more time to complete successfully. Fix the problem by respecting the cmd->busy_timeout, which is provided by the mmc core. Cc: Rui Miguel Silva Cc: Johan Hovold Cc: Alex Elder Cc: Greg Kroah-Hartman Cc: greybus-dev@lists.linaro.org Signed-off-by: Ulf Hansson Acked-by: Rui Miguel Silva Acked-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20200414161413.3036-20-ulf.hansson@linaro.org Signed-off-by: Ulf Hansson Signed-off-by: Sasha Levin --- drivers/staging/greybus/sdio.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/staging/greybus/sdio.c b/drivers/staging/greybus/sdio.c index 5649ef1e379d..82a1c2cf6687 100644 --- a/drivers/staging/greybus/sdio.c +++ b/drivers/staging/greybus/sdio.c @@ -413,6 +413,7 @@ static int gb_sdio_command(struct gb_sdio_host *host, struct mmc_command *cmd) struct gb_sdio_command_request request = {0}; struct gb_sdio_command_response response; struct mmc_data *data = host->mrq->data; + unsigned int timeout_ms; u8 cmd_flags; u8 cmd_type; int i; @@ -471,9 +472,12 @@ static int gb_sdio_command(struct gb_sdio_host *host, struct mmc_command *cmd) request.data_blksz = cpu_to_le16(data->blksz); } - ret = gb_operation_sync(host->connection, GB_SDIO_TYPE_COMMAND, - &request, sizeof(request), &response, - sizeof(response)); + timeout_ms = cmd->busy_timeout ? cmd->busy_timeout : + GB_OPERATION_TIMEOUT_DEFAULT; + + ret = gb_operation_sync_timeout(host->connection, GB_SDIO_TYPE_COMMAND, + &request, sizeof(request), &response, + sizeof(response), timeout_ms); if (ret < 0) goto out; From 74b775b3ba34879cc24e081bda9e8395eaf27156 Mon Sep 17 00:00:00 2001 From: Xie XiuQi Date: Tue, 5 May 2020 10:45:21 +0800 Subject: [PATCH 351/387] ixgbe: fix signed-integer-overflow warning [ Upstream commit 3b70683fc4d68f5d915d9dc7e5ba72c732c7315c ] ubsan report this warning, fix it by adding a unsigned suffix. UBSAN: signed-integer-overflow in drivers/net/ethernet/intel/ixgbe/ixgbe_common.c:2246:26 65535 * 65537 cannot be represented in type 'int' CPU: 21 PID: 7 Comm: kworker/u256:0 Not tainted 5.7.0-rc3-debug+ #39 Hardware name: Huawei TaiShan 2280 V2/BC82AMDC, BIOS 2280-V2 03/27/2020 Workqueue: ixgbe ixgbe_service_task [ixgbe] Call trace: dump_backtrace+0x0/0x3f0 show_stack+0x28/0x38 dump_stack+0x154/0x1e4 ubsan_epilogue+0x18/0x60 handle_overflow+0xf8/0x148 __ubsan_handle_mul_overflow+0x34/0x48 ixgbe_fc_enable_generic+0x4d0/0x590 [ixgbe] ixgbe_service_task+0xc20/0x1f78 [ixgbe] process_one_work+0x8f0/0xf18 worker_thread+0x430/0x6d0 kthread+0x218/0x238 ret_from_fork+0x10/0x18 Reported-by: Hulk Robot Signed-off-by: Xie XiuQi Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher Signed-off-by: Sasha Levin --- drivers/net/ethernet/intel/ixgbe/ixgbe_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c index 0d2baec546e1..c17135b7fca7 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c @@ -2219,7 +2219,7 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw) } /* Configure pause time (2 TCs per register) */ - reg = hw->fc.pause_time * 0x00010001; + reg = hw->fc.pause_time * 0x00010001U; for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++) IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg); From 109f1be271d6b5eaa46cdb7cd355ea14d5187068 Mon Sep 17 00:00:00 2001 From: Haibo Chen Date: Tue, 26 May 2020 18:22:01 +0800 Subject: [PATCH 352/387] mmc: sdhci-esdhc-imx: fix the mask for tuning start point [ Upstream commit 1194be8c949b8190b2882ad8335a5d98aa50c735 ] According the RM, the bit[6~0] of register ESDHC_TUNING_CTRL is TUNING_START_TAP, bit[7] of this register is to disable the command CRC check for standard tuning. So fix it here. Fixes: d87fc9663688 ("mmc: sdhci-esdhc-imx: support setting tuning start point") Signed-off-by: Haibo Chen Link: https://lore.kernel.org/r/1590488522-9292-1-git-send-email-haibo.chen@nxp.com Signed-off-by: Ulf Hansson Signed-off-by: Sasha Levin --- drivers/mmc/host/sdhci-esdhc-imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 445fc47dc3e7..b4336534f628 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -79,7 +79,7 @@ #define ESDHC_STD_TUNING_EN (1 << 24) /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */ #define ESDHC_TUNING_START_TAP_DEFAULT 0x1 -#define ESDHC_TUNING_START_TAP_MASK 0xff +#define ESDHC_TUNING_START_TAP_MASK 0x7f #define ESDHC_TUNING_STEP_MASK 0x00070000 #define ESDHC_TUNING_STEP_SHIFT 16 From d6043872c76058256b0ee80511076f00ba9f9020 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Fri, 29 May 2020 16:11:51 +0300 Subject: [PATCH 353/387] spi: dw: Return any value retrieved from the dma_transfer callback [ Upstream commit f0410bbf7d0fb80149e3b17d11d31f5b5197873e ] DW APB SSI DMA-part of the driver may need to perform the requested SPI-transfer synchronously. In that case the dma_transfer() callback will return 0 as a marker of the SPI transfer being finished so the SPI core doesn't need to wait and may proceed with the SPI message trasnfers pumping procedure. This will be needed to fix the problem when DMA transactions are finished, but there is still data left in the SPI Tx/Rx FIFOs being sent/received. But for now make dma_transfer to return 1 as the normal dw_spi_transfer_one() method. Signed-off-by: Serge Semin Cc: Georgy Vlasov Cc: Ramil Zaripov Cc: Alexey Malahov Cc: Thomas Bogendoerfer Cc: Arnd Bergmann Cc: Andy Shevchenko Cc: Feng Tang Cc: Rob Herring Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200529131205.31838-3-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-dw-mid.c | 2 +- drivers/spi/spi-dw.c | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index fe0ca3848d35..c079ab36275f 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c @@ -274,7 +274,7 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, struct spi_transfer *xfer) dma_async_issue_pending(dws->txchan); } - return 0; + return 1; } static void mid_spi_dma_stop(struct dw_spi *dws) diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index c5a2f369941c..91f44e3e1930 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -384,11 +384,8 @@ static int dw_spi_transfer_one(struct spi_master *master, spi_enable_chip(dws, 1); - if (dws->dma_mapped) { - ret = dws->dma_ops->dma_transfer(dws, transfer); - if (ret < 0) - return ret; - } + if (dws->dma_mapped) + return dws->dma_ops->dma_transfer(dws, transfer); if (chip->poll_mode) return poll_transfer(dws); From 42b548b9e9248ffd2f378bd4cbcb31d692ef3280 Mon Sep 17 00:00:00 2001 From: Qiushi Wu Date: Thu, 28 May 2020 13:20:46 -0500 Subject: [PATCH 354/387] cpuidle: Fix three reference count leaks [ Upstream commit c343bf1ba5efcbf2266a1fe3baefec9cc82f867f ] kobject_init_and_add() takes reference even when it fails. If this function returns an error, kobject_put() must be called to properly clean up the memory associated with the object. Previous commit "b8eb718348b8" fixed a similar problem. Signed-off-by: Qiushi Wu [ rjw: Subject ] Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/cpuidle/sysfs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c index 9e98a5fbbc1d..e7e92ed34f0c 100644 --- a/drivers/cpuidle/sysfs.c +++ b/drivers/cpuidle/sysfs.c @@ -412,7 +412,7 @@ static int cpuidle_add_state_sysfs(struct cpuidle_device *device) ret = kobject_init_and_add(&kobj->kobj, &ktype_state_cpuidle, &kdev->kobj, "state%d", i); if (ret) { - kfree(kobj); + kobject_put(&kobj->kobj); goto error_state; } kobject_uevent(&kobj->kobj, KOBJ_ADD); @@ -542,7 +542,7 @@ static int cpuidle_add_driver_sysfs(struct cpuidle_device *dev) ret = kobject_init_and_add(&kdrv->kobj, &ktype_driver_cpuidle, &kdev->kobj, "driver"); if (ret) { - kfree(kdrv); + kobject_put(&kdrv->kobj); return ret; } @@ -636,7 +636,7 @@ int cpuidle_add_sysfs(struct cpuidle_device *dev) error = kobject_init_and_add(&kdev->kobj, &ktype_cpuidle, &cpu_dev->kobj, "cpuidle"); if (error) { - kfree(kdev); + kobject_put(&kdev->kobj); return error; } From 9e36fae9ac971377e9c640d684192e816a953bb8 Mon Sep 17 00:00:00 2001 From: Marcos Paulo de Souza Date: Sun, 10 May 2020 23:15:07 -0300 Subject: [PATCH 355/387] btrfs: send: emit file capabilities after chown commit 89efda52e6b6930f80f5adda9c3c9edfb1397191 upstream. Whenever a chown is executed, all capabilities of the file being touched are lost. When doing incremental send with a file with capabilities, there is a situation where the capability can be lost on the receiving side. The sequence of actions bellow shows the problem: $ mount /dev/sda fs1 $ mount /dev/sdb fs2 $ touch fs1/foo.bar $ setcap cap_sys_nice+ep fs1/foo.bar $ btrfs subvolume snapshot -r fs1 fs1/snap_init $ btrfs send fs1/snap_init | btrfs receive fs2 $ chgrp adm fs1/foo.bar $ setcap cap_sys_nice+ep fs1/foo.bar $ btrfs subvolume snapshot -r fs1 fs1/snap_complete $ btrfs subvolume snapshot -r fs1 fs1/snap_incremental $ btrfs send fs1/snap_complete | btrfs receive fs2 $ btrfs send -p fs1/snap_init fs1/snap_incremental | btrfs receive fs2 At this point, only a chown was emitted by "btrfs send" since only the group was changed. This makes the cap_sys_nice capability to be dropped from fs2/snap_incremental/foo.bar To fix that, only emit capabilities after chown is emitted. The current code first checks for xattrs that are new/changed, emits them, and later emit the chown. Now, __process_new_xattr skips capabilities, letting only finish_inode_if_needed to emit them, if they exist, for the inode being processed. This behavior was being worked around in "btrfs receive" side by caching the capability and only applying it after chown. Now, xattrs are only emmited _after_ chown, making that workaround not needed anymore. Link: https://github.com/kdave/btrfs-progs/issues/202 CC: stable@vger.kernel.org # 4.4+ Suggested-by: Filipe Manana Reviewed-by: Filipe Manana Signed-off-by: Marcos Paulo de Souza Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/send.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index edfc7ba38b33..080b12d65b0c 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c @@ -35,6 +35,7 @@ #include "btrfs_inode.h" #include "transaction.h" #include "compression.h" +#include "xattr.h" /* * Maximum number of references an extent can have in order for us to attempt to @@ -4368,6 +4369,10 @@ static int __process_new_xattr(int num, struct btrfs_key *di_key, struct fs_path *p; struct posix_acl_xattr_header dummy_acl; + /* Capabilities are emitted by finish_inode_if_needed */ + if (!strncmp(name, XATTR_NAME_CAPS, name_len)) + return 0; + p = fs_path_alloc(); if (!p) return -ENOMEM; @@ -4904,6 +4909,64 @@ static int send_extent_data(struct send_ctx *sctx, return 0; } +/* + * Search for a capability xattr related to sctx->cur_ino. If the capability is + * found, call send_set_xattr function to emit it. + * + * Return 0 if there isn't a capability, or when the capability was emitted + * successfully, or < 0 if an error occurred. + */ +static int send_capabilities(struct send_ctx *sctx) +{ + struct fs_path *fspath = NULL; + struct btrfs_path *path; + struct btrfs_dir_item *di; + struct extent_buffer *leaf; + unsigned long data_ptr; + char *buf = NULL; + int buf_len; + int ret = 0; + + path = alloc_path_for_send(); + if (!path) + return -ENOMEM; + + di = btrfs_lookup_xattr(NULL, sctx->send_root, path, sctx->cur_ino, + XATTR_NAME_CAPS, strlen(XATTR_NAME_CAPS), 0); + if (!di) { + /* There is no xattr for this inode */ + goto out; + } else if (IS_ERR(di)) { + ret = PTR_ERR(di); + goto out; + } + + leaf = path->nodes[0]; + buf_len = btrfs_dir_data_len(leaf, di); + + fspath = fs_path_alloc(); + buf = kmalloc(buf_len, GFP_KERNEL); + if (!fspath || !buf) { + ret = -ENOMEM; + goto out; + } + + ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, fspath); + if (ret < 0) + goto out; + + data_ptr = (unsigned long)(di + 1) + btrfs_dir_name_len(leaf, di); + read_extent_buffer(leaf, buf, data_ptr, buf_len); + + ret = send_set_xattr(sctx, fspath, XATTR_NAME_CAPS, + strlen(XATTR_NAME_CAPS), buf, buf_len); +out: + kfree(buf); + fs_path_free(fspath); + btrfs_free_path(path); + return ret; +} + static int clone_range(struct send_ctx *sctx, struct clone_root *clone_root, const u64 disk_byte, @@ -5615,6 +5678,10 @@ static int finish_inode_if_needed(struct send_ctx *sctx, int at_end) goto out; } + ret = send_capabilities(sctx); + if (ret < 0) + goto out; + /* * If other directory inodes depended on our current directory * inode's move/rename, now do their move/rename operations. From d93d7bd61072a03dde173d36ae5815488a585fc0 Mon Sep 17 00:00:00 2001 From: Andrea Arcangeli Date: Wed, 27 May 2020 19:06:24 -0400 Subject: [PATCH 356/387] mm: thp: make the THP mapcount atomic against __split_huge_pmd_locked() commit c444eb564fb16645c172d550359cb3d75fe8a040 upstream. Write protect anon page faults require an accurate mapcount to decide if to break the COW or not. This is implemented in the THP path with reuse_swap_page() -> page_trans_huge_map_swapcount()/page_trans_huge_mapcount(). If the COW triggers while the other processes sharing the page are under a huge pmd split, to do an accurate reading, we must ensure the mapcount isn't computed while it's being transferred from the head page to the tail pages. reuse_swap_cache() already runs serialized by the page lock, so it's enough to add the page lock around __split_huge_pmd_locked too, in order to add the missing serialization. Note: the commit in "Fixes" is just to facilitate the backporting, because the code before such commit didn't try to do an accurate THP mapcount calculation and it instead used the page_count() to decide if to COW or not. Both the page_count and the pin_count are THP-wide refcounts, so they're inaccurate if used in reuse_swap_page(). Reverting such commit (besides the unrelated fix to the local anon_vma assignment) would have also opened the window for memory corruption side effects to certain workloads as documented in such commit header. Signed-off-by: Andrea Arcangeli Suggested-by: Jann Horn Reported-by: Jann Horn Acked-by: Kirill A. Shutemov Fixes: 6d0a07edd17c ("mm: thp: calculate the mapcount correctly for THP pages during WP faults") Cc: stable@vger.kernel.org Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- mm/huge_memory.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 5fbd77d52602..cf4c0a61b370 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -1755,6 +1755,8 @@ void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, spinlock_t *ptl; struct mm_struct *mm = vma->vm_mm; unsigned long haddr = address & HPAGE_PMD_MASK; + bool was_locked = false; + pmd_t _pmd; mmu_notifier_invalidate_range_start(mm, haddr, haddr + HPAGE_PMD_SIZE); ptl = pmd_lock(mm, pmd); @@ -1764,11 +1766,32 @@ void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, * pmd against. Otherwise we can end up replacing wrong page. */ VM_BUG_ON(freeze && !page); - if (page && page != pmd_page(*pmd)) - goto out; + if (page) { + VM_WARN_ON_ONCE(!PageLocked(page)); + was_locked = true; + if (page != pmd_page(*pmd)) + goto out; + } +repeat: if (pmd_trans_huge(*pmd)) { - page = pmd_page(*pmd); + if (!page) { + page = pmd_page(*pmd); + if (unlikely(!trylock_page(page))) { + get_page(page); + _pmd = *pmd; + spin_unlock(ptl); + lock_page(page); + spin_lock(ptl); + if (unlikely(!pmd_same(*pmd, _pmd))) { + unlock_page(page); + put_page(page); + page = NULL; + goto repeat; + } + put_page(page); + } + } if (PageMlocked(page)) clear_page_mlock(page); } else if (!pmd_devmap(*pmd)) @@ -1776,6 +1799,8 @@ void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, __split_huge_pmd_locked(vma, pmd, haddr, freeze); out: spin_unlock(ptl); + if (!was_locked && page) + unlock_page(page); mmu_notifier_invalidate_range_end(mm, haddr, haddr + HPAGE_PMD_SIZE); } From 446e3919b51043f722f7c5b196798997ce900ae0 Mon Sep 17 00:00:00 2001 From: Krzysztof Struczynski Date: Tue, 28 Apr 2020 09:30:10 +0200 Subject: [PATCH 357/387] ima: Fix ima digest hash table key calculation commit 1129d31b55d509f15e72dc68e4b5c3a4d7b4da8d upstream. Function hash_long() accepts unsigned long, while currently only one byte is passed from ima_hash_key(), which calculates a key for ima_htable. Given that hashing the digest does not give clear benefits compared to using the digest itself, remove hash_long() and return the modulus calculated on the first two bytes of the digest with the number of slots. Also reduce the depth of the hash table by doubling the number of slots. Cc: stable@vger.kernel.org Fixes: 3323eec921ef ("integrity: IMA as an integrity service provider") Co-developed-by: Roberto Sassu Signed-off-by: Roberto Sassu Signed-off-by: Krzysztof Struczynski Acked-by: David.Laight@aculab.com (big endian system concerns) Signed-off-by: Mimi Zohar Signed-off-by: Greg Kroah-Hartman --- security/integrity/ima/ima.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index df7834aa1b8f..5f2a0a07ceac 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -36,7 +36,7 @@ enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 }; #define IMA_DIGEST_SIZE SHA1_DIGEST_SIZE #define IMA_EVENT_NAME_LEN_MAX 255 -#define IMA_HASH_BITS 9 +#define IMA_HASH_BITS 10 #define IMA_MEASURE_HTABLE_SIZE (1 << IMA_HASH_BITS) #define IMA_TEMPLATE_FIELD_ID_MAX_LEN 16 @@ -136,9 +136,10 @@ struct ima_h_table { }; extern struct ima_h_table ima_htable; -static inline unsigned long ima_hash_key(u8 *digest) +static inline unsigned int ima_hash_key(u8 *digest) { - return hash_long(*digest, IMA_HASH_BITS); + /* there is no point in taking a hash of part of a digest */ + return (digest[0] | digest[1] << 8) % IMA_MEASURE_HTABLE_SIZE; } enum ima_hooks { From 63125a4a45284122064495ac4a3336b17735b252 Mon Sep 17 00:00:00 2001 From: Roberto Sassu Date: Wed, 3 Jun 2020 17:08:20 +0200 Subject: [PATCH 358/387] ima: Directly assign the ima_default_policy pointer to ima_rules commit 067a436b1b0aafa593344fddd711a755a58afb3b upstream. This patch prevents the following oops: [ 10.771813] BUG: kernel NULL pointer dereference, address: 0000000000000 [...] [ 10.779790] RIP: 0010:ima_match_policy+0xf7/0xb80 [...] [ 10.798576] Call Trace: [ 10.798993] ? ima_lsm_policy_change+0x2b0/0x2b0 [ 10.799753] ? inode_init_owner+0x1a0/0x1a0 [ 10.800484] ? _raw_spin_lock+0x7a/0xd0 [ 10.801592] ima_must_appraise.part.0+0xb6/0xf0 [ 10.802313] ? ima_fix_xattr.isra.0+0xd0/0xd0 [ 10.803167] ima_must_appraise+0x4f/0x70 [ 10.804004] ima_post_path_mknod+0x2e/0x80 [ 10.804800] do_mknodat+0x396/0x3c0 It occurs when there is a failure during IMA initialization, and ima_init_policy() is not called. IMA hooks still call ima_match_policy() but ima_rules is NULL. This patch prevents the crash by directly assigning the ima_default_policy pointer to ima_rules when ima_rules is defined. This wouldn't alter the existing behavior, as ima_rules is always set at the end of ima_init_policy(). Cc: stable@vger.kernel.org # 3.7.x Fixes: 07f6a79415d7d ("ima: add appraise action keywords and default rules") Reported-by: Takashi Iwai Signed-off-by: Roberto Sassu Signed-off-by: Mimi Zohar Signed-off-by: Greg Kroah-Hartman --- security/integrity/ima/ima_policy.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index aed47b777a57..4926a5a1bc94 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -150,7 +150,7 @@ static struct ima_rule_entry default_appraise_rules[] = { static LIST_HEAD(ima_default_rules); static LIST_HEAD(ima_policy_rules); static LIST_HEAD(ima_temp_rules); -static struct list_head *ima_rules; +static struct list_head *ima_rules = &ima_default_rules; static int ima_policy __initdata; @@ -429,7 +429,6 @@ void __init ima_init_policy(void) temp_ima_appraise |= IMA_APPRAISE_POLICY; } - ima_rules = &ima_default_rules; ima_update_policy_flag(); } From 4b9d238c8a534a0374a56c771c7791cb18f3fbed Mon Sep 17 00:00:00 2001 From: Roberto Sassu Date: Tue, 14 Apr 2020 10:01:31 +0200 Subject: [PATCH 359/387] evm: Fix possible memory leak in evm_calc_hmac_or_hash() commit 0c4395fb2aa77341269ea619c5419ea48171883f upstream. Don't immediately return if the signature is portable and security.ima is not present. Just set error so that memory allocated is freed before returning from evm_calc_hmac_or_hash(). Fixes: 50b977481fce9 ("EVM: Add support for portable signature format") Signed-off-by: Roberto Sassu Cc: stable@vger.kernel.org Signed-off-by: Mimi Zohar Signed-off-by: Greg Kroah-Hartman --- security/integrity/evm/evm_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c index e034dc21421e..b0440cf34970 100644 --- a/security/integrity/evm/evm_crypto.c +++ b/security/integrity/evm/evm_crypto.c @@ -240,7 +240,7 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry, /* Portable EVM signatures must include an IMA hash */ if (type == EVM_XATTR_PORTABLE_DIGSIG && !ima_present) - return -EPERM; + error = -EPERM; out: kfree(xattr_value); kfree(desc); From b61a98f7173bff9ed2cf982619222d3608fac2d1 Mon Sep 17 00:00:00 2001 From: Harshad Shirwadkar Date: Mon, 20 Apr 2020 19:39:59 -0700 Subject: [PATCH 360/387] ext4: fix EXT_MAX_EXTENT/INDEX to check for zeroed eh_max commit c36a71b4e35ab35340facdd6964a00956b9fef0a upstream. If eh->eh_max is 0, EXT_MAX_EXTENT/INDEX would evaluate to unsigned (-1) resulting in illegal memory accesses. Although there is no consistent repro, we see that generic/019 sometimes crashes because of this bug. Ran gce-xfstests smoke and verified that there were no regressions. Signed-off-by: Harshad Shirwadkar Link: https://lore.kernel.org/r/20200421023959.20879-2-harshadshirwadkar@gmail.com Signed-off-by: Theodore Ts'o Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman --- fs/ext4/ext4_extents.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/fs/ext4/ext4_extents.h b/fs/ext4/ext4_extents.h index a284fb28944b..63291c265aa0 100644 --- a/fs/ext4/ext4_extents.h +++ b/fs/ext4/ext4_extents.h @@ -169,10 +169,13 @@ struct ext4_ext_path { (EXT_FIRST_EXTENT((__hdr__)) + le16_to_cpu((__hdr__)->eh_entries) - 1) #define EXT_LAST_INDEX(__hdr__) \ (EXT_FIRST_INDEX((__hdr__)) + le16_to_cpu((__hdr__)->eh_entries) - 1) -#define EXT_MAX_EXTENT(__hdr__) \ - (EXT_FIRST_EXTENT((__hdr__)) + le16_to_cpu((__hdr__)->eh_max) - 1) +#define EXT_MAX_EXTENT(__hdr__) \ + ((le16_to_cpu((__hdr__)->eh_max)) ? \ + ((EXT_FIRST_EXTENT((__hdr__)) + le16_to_cpu((__hdr__)->eh_max) - 1)) \ + : 0) #define EXT_MAX_INDEX(__hdr__) \ - (EXT_FIRST_INDEX((__hdr__)) + le16_to_cpu((__hdr__)->eh_max) - 1) + ((le16_to_cpu((__hdr__)->eh_max)) ? \ + ((EXT_FIRST_INDEX((__hdr__)) + le16_to_cpu((__hdr__)->eh_max) - 1)) : 0) static inline struct ext4_extent_header *ext_inode_hdr(struct inode *inode) { From 86498641bfff80f65ce848db03bd3cd462db844c Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Wed, 6 May 2020 11:31:40 -0700 Subject: [PATCH 361/387] ext4: fix race between ext4_sync_parent() and rename() commit 08adf452e628b0e2ce9a01048cfbec52353703d7 upstream. 'igrab(d_inode(dentry->d_parent))' without holding dentry->d_lock is broken because without d_lock, d_parent can be concurrently changed due to a rename(). Then if the old directory is immediately deleted, old d_parent->inode can be NULL. That causes a NULL dereference in igrab(). To fix this, use dget_parent() to safely grab a reference to the parent dentry, which pins the inode. This also eliminates the need to use d_find_any_alias() other than for the initial inode, as we no longer throw away the dentry at each step. This is an extremely hard race to hit, but it is possible. Adding a udelay() in between the reads of ->d_parent and its ->d_inode makes it reproducible on a no-journal filesystem using the following program: #include #include int main() { if (fork()) { for (;;) { mkdir("dir1", 0700); int fd = open("dir1/file", O_RDWR|O_CREAT|O_SYNC); write(fd, "X", 1); close(fd); } } else { mkdir("dir2", 0700); for (;;) { rename("dir1/file", "dir2/file"); rmdir("dir1"); } } } Fixes: d59729f4e794 ("ext4: fix races in ext4_sync_parent()") Cc: stable@vger.kernel.org Signed-off-by: Eric Biggers Link: https://lore.kernel.org/r/20200506183140.541194-1-ebiggers@kernel.org Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/fsync.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c index 88effb1053c7..6dc0b89c7b55 100644 --- a/fs/ext4/fsync.c +++ b/fs/ext4/fsync.c @@ -43,30 +43,28 @@ */ static int ext4_sync_parent(struct inode *inode) { - struct dentry *dentry = NULL; - struct inode *next; + struct dentry *dentry, *next; int ret = 0; if (!ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY)) return 0; - inode = igrab(inode); + dentry = d_find_any_alias(inode); + if (!dentry) + return 0; while (ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY)) { ext4_clear_inode_state(inode, EXT4_STATE_NEWENTRY); - dentry = d_find_any_alias(inode); - if (!dentry) - break; - next = igrab(d_inode(dentry->d_parent)); + + next = dget_parent(dentry); dput(dentry); - if (!next) - break; - iput(inode); - inode = next; + dentry = next; + inode = dentry->d_inode; + /* * The directory inode may have gone through rmdir by now. But * the inode itself and its blocks are still allocated (we hold - * a reference to the inode so it didn't go through - * ext4_evict_inode()) and so we are safe to flush metadata - * blocks and the inode. + * a reference to the inode via its dentry), so it didn't go + * through ext4_evict_inode()) and so we are safe to flush + * metadata blocks and the inode. */ ret = sync_mapping_buffers(inode->i_mapping); if (ret) @@ -75,7 +73,7 @@ static int ext4_sync_parent(struct inode *inode) if (ret) break; } - iput(inode); + dput(dentry); return ret; } From ed80f400f6dd6a9228ef297a00803ede191e3007 Mon Sep 17 00:00:00 2001 From: Omar Sandoval Date: Thu, 16 Apr 2020 14:46:12 -0700 Subject: [PATCH 362/387] btrfs: fix error handling when submitting direct I/O bio [ Upstream commit 6d3113a193e3385c72240096fe397618ecab6e43 ] In btrfs_submit_direct_hook(), if a direct I/O write doesn't span a RAID stripe or chunk, we submit orig_bio without cloning it. In this case, we don't increment pending_bios. Then, if btrfs_submit_dio_bio() fails, we decrement pending_bios to -1, and we never complete orig_bio. Fix it by initializing pending_bios to 1 instead of incrementing later. Fixing this exposes another bug: we put orig_bio prematurely and then put it again from end_io. Fix it by not putting orig_bio. After this change, pending_bios is really more of a reference count, but I'll leave that cleanup separate to keep the fix small. Fixes: e65e15355429 ("btrfs: fix panic caused by direct IO") CC: stable@vger.kernel.org # 4.4+ Reviewed-by: Nikolay Borisov Reviewed-by: Josef Bacik Reviewed-by: Johannes Thumshirn Signed-off-by: Omar Sandoval Signed-off-by: David Sterba Signed-off-by: Sasha Levin --- fs/btrfs/inode.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 250c8403ec67..c425443c31fe 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -8494,7 +8494,6 @@ static int btrfs_submit_direct_hook(struct btrfs_dio_private *dip, bio->bi_private = dip; bio->bi_end_io = btrfs_end_dio_bio; btrfs_io_bio(bio)->logical = file_offset; - atomic_inc(&dip->pending_bios); while (bvec <= (orig_bio->bi_io_vec + orig_bio->bi_vcnt - 1)) { nr_sectors = BTRFS_BYTES_TO_BLKS(root->fs_info, bvec->bv_len); @@ -8560,7 +8559,8 @@ submit: if (!ret) return 0; - bio_put(bio); + if (bio != orig_bio) + bio_put(bio); out_err: dip->errors = 1; /* @@ -8607,7 +8607,7 @@ static void btrfs_submit_direct(struct bio *dio_bio, struct inode *inode, io_bio->bi_private = dip; dip->orig_bio = io_bio; dip->dio_bio = dio_bio; - atomic_set(&dip->pending_bios, 0); + atomic_set(&dip->pending_bios, 1); btrfs_bio = btrfs_io_bio(io_bio); btrfs_bio->logical = file_offset; From 6754baabb890eed09f30c84016242c52a6c2d2d4 Mon Sep 17 00:00:00 2001 From: Giuliano Procida Date: Thu, 18 Jun 2020 19:30:22 +0100 Subject: [PATCH 363/387] blk-mq: move blk_mq_update_nr_hw_queues synchronize_rcu call This fixes the 4.9 backport commit f530afb974c2e82047bd6220303a2dbe30eff304 which was upstream commit f5bbbbe4d63577026f908a809f22f5fd5a90ea1f. The upstream commit added a call to synchronize_rcu to _blk_mq_update_nr_hw_queues, just after freezing queues. In the backport this landed (in blk_mq_update_nr_hw_queues instead), just after unfreezeing queues. This commit moves the call to its intended place. Fixes: f530afb974c2 ("blk-mq: sync the update nr_hw_queues with blk_mq_queue_tag_busy_iter") Signed-off-by: Giuliano Procida Signed-off-by: Sasha Levin --- block/blk-mq.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/block/blk-mq.c b/block/blk-mq.c index 58be2eaa5aaa..e0ed7317e98c 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -2331,6 +2331,10 @@ void blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, int nr_hw_queues) list_for_each_entry(q, &set->tag_list, tag_set_list) blk_mq_freeze_queue(q); + /* + * Sync with blk_mq_queue_tag_busy_iter. + */ + synchronize_rcu(); set->nr_hw_queues = nr_hw_queues; list_for_each_entry(q, &set->tag_list, tag_set_list) { @@ -2346,10 +2350,6 @@ void blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, int nr_hw_queues) list_for_each_entry(q, &set->tag_list, tag_set_list) blk_mq_unfreeze_queue(q); - /* - * Sync with blk_mq_queue_tag_busy_iter. - */ - synchronize_rcu(); } EXPORT_SYMBOL_GPL(blk_mq_update_nr_hw_queues); From 08727720bb441e83a5117d25744d5ca2156c7553 Mon Sep 17 00:00:00 2001 From: Ashok Raj Date: Fri, 27 Mar 2020 14:16:15 -0700 Subject: [PATCH 364/387] PCI: Program MPS for RCiEP devices commit aa0ce96d72dd2e1b0dfd0fb868f82876e7790878 upstream. Root Complex Integrated Endpoints (RCiEPs) do not have an upstream bridge, so pci_configure_mps() previously ignored them, which may result in reduced performance. Instead, program the Max_Payload_Size of RCiEPs to the maximum supported value (unless it is limited for the PCIE_BUS_PEER2PEER case). This also affects the subsequent programming of Max_Read_Request_Size because Linux programs MRRS based on the MPS value. Fixes: 9dae3a97297f ("PCI: Move MPS configuration check to pci_configure_device()") Link: https://lore.kernel.org/r/1585343775-4019-1-git-send-email-ashok.raj@intel.com Tested-by: Dave Jiang Signed-off-by: Ashok Raj Signed-off-by: Bjorn Helgaas Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/pci/probe.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index be63f008167b..19658873b4c1 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1360,13 +1360,33 @@ static void pci_configure_mps(struct pci_dev *dev) struct pci_dev *bridge = pci_upstream_bridge(dev); int mps, p_mps, rc; - if (!pci_is_pcie(dev) || !bridge || !pci_is_pcie(bridge)) + if (!pci_is_pcie(dev)) return; /* MPS and MRRS fields are of type 'RsvdP' for VFs, short-circuit out */ if (dev->is_virtfn) return; + /* + * For Root Complex Integrated Endpoints, program the maximum + * supported value unless limited by the PCIE_BUS_PEER2PEER case. + */ + if (pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END) { + if (pcie_bus_config == PCIE_BUS_PEER2PEER) + mps = 128; + else + mps = 128 << dev->pcie_mpss; + rc = pcie_set_mps(dev, mps); + if (rc) { + pci_warn(dev, "can't set Max Payload Size to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n", + mps); + } + return; + } + + if (!bridge || !pci_is_pcie(bridge)) + return; + mps = pcie_get_mps(dev); p_mps = pcie_get_mps(bridge); From 831e063654bca5b43245505de3e140d97e7b8e7e Mon Sep 17 00:00:00 2001 From: Punit Agrawal Date: Fri, 15 May 2020 13:31:27 +0900 Subject: [PATCH 365/387] e1000e: Relax condition to trigger reset for ME workaround commit d601afcae2febc49665008e9a79e701248d56c50 upstream. It's an error if the value of the RX/TX tail descriptor does not match what was written. The error condition is true regardless the duration of the interference from ME. But the driver only performs the reset if E1000_ICH_FWSM_PCIM2PCI_COUNT (2000) iterations of 50us delay have transpired. The extra condition can lead to inconsistency between the state of hardware as expected by the driver. Fix this by dropping the check for number of delay iterations. While at it, also make __ew32_prepare() static as it's not used anywhere else. CC: stable Signed-off-by: Punit Agrawal Reviewed-by: Alexander Duyck Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/intel/e1000e/e1000.h | 1 - drivers/net/ethernet/intel/e1000e/netdev.c | 12 +++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index 879cca47b021..62675938cb59 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -589,7 +589,6 @@ static inline u32 __er32(struct e1000_hw *hw, unsigned long reg) #define er32(reg) __er32(hw, E1000_##reg) -s32 __ew32_prepare(struct e1000_hw *hw); void __ew32(struct e1000_hw *hw, unsigned long reg, u32 val); #define ew32(reg, val) __ew32(hw, E1000_##reg, (val)) diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index a0f97c5ab6ef..be324b4761eb 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -136,14 +136,12 @@ static const struct e1000_reg_info e1000_reg_info_tbl[] = { * has bit 24 set while ME is accessing MAC CSR registers, wait if it is set * and try again a number of times. **/ -s32 __ew32_prepare(struct e1000_hw *hw) +static void __ew32_prepare(struct e1000_hw *hw) { s32 i = E1000_ICH_FWSM_PCIM2PCI_COUNT; while ((er32(FWSM) & E1000_ICH_FWSM_PCIM2PCI) && --i) udelay(50); - - return i; } void __ew32(struct e1000_hw *hw, unsigned long reg, u32 val) @@ -624,11 +622,11 @@ static void e1000e_update_rdt_wa(struct e1000_ring *rx_ring, unsigned int i) { struct e1000_adapter *adapter = rx_ring->adapter; struct e1000_hw *hw = &adapter->hw; - s32 ret_val = __ew32_prepare(hw); + __ew32_prepare(hw); writel(i, rx_ring->tail); - if (unlikely(!ret_val && (i != readl(rx_ring->tail)))) { + if (unlikely(i != readl(rx_ring->tail))) { u32 rctl = er32(RCTL); ew32(RCTL, rctl & ~E1000_RCTL_EN); @@ -641,11 +639,11 @@ static void e1000e_update_tdt_wa(struct e1000_ring *tx_ring, unsigned int i) { struct e1000_adapter *adapter = tx_ring->adapter; struct e1000_hw *hw = &adapter->hw; - s32 ret_val = __ew32_prepare(hw); + __ew32_prepare(hw); writel(i, tx_ring->tail); - if (unlikely(!ret_val && (i != readl(tx_ring->tail)))) { + if (unlikely(i != readl(tx_ring->tail))) { u32 tctl = er32(TCTL); ew32(TCTL, tctl & ~E1000_TCTL_EN); From bd16f8d4869552b8224c03393370ef1ccb6a12c5 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Tue, 5 May 2020 10:42:09 +0300 Subject: [PATCH 366/387] carl9170: remove P2P_GO support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit b14fba7ebd04082f7767a11daea7f12f3593de22 upstream. This patch follows up on a bug-report by Frank Schäfer that discovered P2P GO wasn't working with wpa_supplicant. This patch removes part of the broken P2P GO support but keeps the vif switchover code in place. Cc: Link: Reported-by: Frank Schäfer Signed-off-by: Christian Lamparter Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200425092811.9494-1-chunkeey@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/carl9170/fw.c | 4 +--- drivers/net/wireless/ath/carl9170/main.c | 21 ++++----------------- 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c index 88045f93a76c..62ed0977f32c 100644 --- a/drivers/net/wireless/ath/carl9170/fw.c +++ b/drivers/net/wireless/ath/carl9170/fw.c @@ -351,9 +351,7 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC); if (SUPP(CARL9170FW_WLANTX_CAB)) { - if_comb_types |= - BIT(NL80211_IFTYPE_AP) | - BIT(NL80211_IFTYPE_P2P_GO); + if_comb_types |= BIT(NL80211_IFTYPE_AP); #ifdef CONFIG_MAC80211_MESH if_comb_types |= diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index ffb22a04beeb..202f421e0e37 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -582,11 +582,10 @@ static int carl9170_init_interface(struct ar9170 *ar, ar->disable_offload |= ((vif->type != NL80211_IFTYPE_STATION) && (vif->type != NL80211_IFTYPE_AP)); - /* While the driver supports HW offload in a single - * P2P client configuration, it doesn't support HW - * offload in the favourit, concurrent P2P GO+CLIENT - * configuration. Hence, HW offload will always be - * disabled for P2P. + /* The driver used to have P2P GO+CLIENT support, + * but since this was dropped and we don't know if + * there are any gremlins lurking in the shadows, + * so best we keep HW offload disabled for P2P. */ ar->disable_offload |= vif->p2p; @@ -639,18 +638,6 @@ static int carl9170_op_add_interface(struct ieee80211_hw *hw, if (vif->type == NL80211_IFTYPE_STATION) break; - /* P2P GO [master] use-case - * Because the P2P GO station is selected dynamically - * by all participating peers of a WIFI Direct network, - * the driver has be able to change the main interface - * operating mode on the fly. - */ - if (main_vif->p2p && vif->p2p && - vif->type == NL80211_IFTYPE_AP) { - old_main = main_vif; - break; - } - err = -EBUSY; rcu_read_unlock(); From 3e70f204f62f2198f3b88932c71e5ac29a5fbb10 Mon Sep 17 00:00:00 2001 From: Chuhong Yuan Date: Tue, 10 Dec 2019 04:15:48 +0100 Subject: [PATCH 367/387] media: go7007: fix a miss of snd_card_free commit 9453264ef58638ce8976121ac44c07a3ef375983 upstream. go7007_snd_init() misses a snd_card_free() in an error path. Add the missed call to fix it. Signed-off-by: Chuhong Yuan Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab [Salvatore Bonaccorso: Adjust context for backport to versions which do not contain c0decac19da3 ("media: use strscpy() instead of strlcpy()") and ba78170ef153 ("media: go7007: Fix misuse of strscpy")] Signed-off-by: Salvatore Bonaccorso Signed-off-by: Greg Kroah-Hartman --- drivers/media/usb/go7007/snd-go7007.c | 35 +++++++++++++-------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/drivers/media/usb/go7007/snd-go7007.c b/drivers/media/usb/go7007/snd-go7007.c index 070871fb1fc4..6e1a85ff3fff 100644 --- a/drivers/media/usb/go7007/snd-go7007.c +++ b/drivers/media/usb/go7007/snd-go7007.c @@ -243,22 +243,18 @@ int go7007_snd_init(struct go7007 *go) gosnd->capturing = 0; ret = snd_card_new(go->dev, index[dev], id[dev], THIS_MODULE, 0, &gosnd->card); - if (ret < 0) { - kfree(gosnd); - return ret; - } + if (ret < 0) + goto free_snd; + ret = snd_device_new(gosnd->card, SNDRV_DEV_LOWLEVEL, go, &go7007_snd_device_ops); - if (ret < 0) { - kfree(gosnd); - return ret; - } + if (ret < 0) + goto free_card; + ret = snd_pcm_new(gosnd->card, "go7007", 0, 0, 1, &gosnd->pcm); - if (ret < 0) { - snd_card_free(gosnd->card); - kfree(gosnd); - return ret; - } + if (ret < 0) + goto free_card; + strlcpy(gosnd->card->driver, "go7007", sizeof(gosnd->card->driver)); strlcpy(gosnd->card->shortname, go->name, sizeof(gosnd->card->driver)); strlcpy(gosnd->card->longname, gosnd->card->shortname, @@ -269,11 +265,8 @@ int go7007_snd_init(struct go7007 *go) &go7007_snd_capture_ops); ret = snd_card_register(gosnd->card); - if (ret < 0) { - snd_card_free(gosnd->card); - kfree(gosnd); - return ret; - } + if (ret < 0) + goto free_card; gosnd->substream = NULL; go->snd_context = gosnd; @@ -281,6 +274,12 @@ int go7007_snd_init(struct go7007 *go) ++dev; return 0; + +free_card: + snd_card_free(gosnd->card); +free_snd: + kfree(gosnd); + return ret; } EXPORT_SYMBOL(go7007_snd_init); From 7581e7d31ebdc911f7fa76ddf99c89a97e06f88d Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Tue, 7 Apr 2020 14:00:43 -0500 Subject: [PATCH 368/387] b43legacy: Fix case where channel status is corrupted commit ec4d3e3a054578de34cd0b587ab8a1ac36f629d9 upstream. This patch fixes commit 75388acd0cd8 ("add mac80211-based driver for legacy BCM43xx devices") In https://bugzilla.kernel.org/show_bug.cgi?id=207093, a defect in b43legacy is reported. Upon testing, thus problem exists on PPC and X86 platforms, is present in the oldest kernel tested (3.2), and has been present in the driver since it was first added to the kernel. The problem is a corrupted channel status received from the device. Both the internal card in a PowerBook G4 and the PCMCIA version (Broadcom BCM4306 with PCI ID 14e4:4320) have the problem. Only Rev, 2 (revision 4 of the 802.11 core) of the chip has been tested. No other devices using b43legacy are available for testing. Various sources of the problem were considered. Buffer overrun and other sources of corruption within the driver were rejected because the faulty channel status is always the same, not a random value. It was concluded that the faulty data is coming from the device, probably due to a firmware bug. As that source is not available, the driver must take appropriate action to recover. At present, the driver reports the error, and them continues to process the bad packet. This is believed that to be a mistake, and the correct action is to drop the correpted packet. Fixes: 75388acd0cd8 ("add mac80211-based driver for legacy BCM43xx devices") Cc: Stable Signed-off-by: Larry Finger Reported-and-tested by: F. Erhard Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200407190043.1686-1-Larry.Finger@lwfinger.net Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/broadcom/b43legacy/xmit.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/broadcom/b43legacy/xmit.c b/drivers/net/wireless/broadcom/b43legacy/xmit.c index 35ccf400b02c..87045e30e585 100644 --- a/drivers/net/wireless/broadcom/b43legacy/xmit.c +++ b/drivers/net/wireless/broadcom/b43legacy/xmit.c @@ -571,6 +571,7 @@ void b43legacy_rx(struct b43legacy_wldev *dev, default: b43legacywarn(dev->wl, "Unexpected value for chanstat (0x%X)\n", chanstat); + goto drop; } memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); From 4646d0032969575499c374bd2fe7798227385fcd Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Tue, 26 May 2020 10:59:08 -0500 Subject: [PATCH 369/387] b43: Fix connection problem with WPA3 commit 75d057bda1fbca6ade21378aa45db712e5f7d962 upstream. Since the driver was first introduced into the kernel, it has only handled the ciphers associated with WEP, WPA, and WPA2. It fails with WPA3 even though mac80211 can handle those additional ciphers in software, b43 did not report that it could handle them. By setting MFP_CAPABLE using ieee80211_set_hw(), the problem is fixed. With this change, b43 will handle the ciphers it knows in hardware, and let mac80211 handle the others in software. It is not necessary to use the module parameter NOHWCRYPT to turn hardware encryption off. Although this change essentially eliminates that module parameter, I am choosing to keep it for cases where the hardware is broken, and software encryption is required for all ciphers. Reported-and-tested-by: Rui Salvaterra Signed-off-by: Larry Finger Cc: Stable Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200526155909.5807-2-Larry.Finger@lwfinger.net Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/broadcom/b43/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/broadcom/b43/main.c b/drivers/net/wireless/broadcom/b43/main.c index a635fc6b1722..e57a50cc1d87 100644 --- a/drivers/net/wireless/broadcom/b43/main.c +++ b/drivers/net/wireless/broadcom/b43/main.c @@ -5596,7 +5596,7 @@ static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev) /* fill hw info */ ieee80211_hw_set(hw, RX_INCLUDES_FCS); ieee80211_hw_set(hw, SIGNAL_DBM); - + ieee80211_hw_set(hw, MFP_CAPABLE); hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MESH_POINT) | From f67f751870f11b4b2b394c4c50840279b07e80c4 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Tue, 26 May 2020 10:59:09 -0500 Subject: [PATCH 370/387] b43_legacy: Fix connection problem with WPA3 commit 6a29d134c04a8acebb7a95251acea7ad7abba106 upstream. Since the driver was first introduced into the kernel, it has only handled the ciphers associated with WEP, WPA, and WPA2. It fails with WPA3 even though mac80211 can handle those additional ciphers in software, b43legacy did not report that it could handle them. By setting MFP_CAPABLE using ieee80211_set_hw(), the problem is fixed. With this change, b43legacy will handle the ciphers it knows in hardware, and let mac80211 handle the others in software. It is not necessary to use the module parameter NOHWCRYPT to turn hardware encryption off. Although this change essentially eliminates that module parameter, I am choosing to keep it for cases where the hardware is broken, and software encryption is required for all ciphers. Signed-off-by: Larry Finger Cc: Stable Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200526155909.5807-3-Larry.Finger@lwfinger.net Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/broadcom/b43legacy/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/broadcom/b43legacy/main.c b/drivers/net/wireless/broadcom/b43legacy/main.c index 9da8bd792702..fe658a9b53cb 100644 --- a/drivers/net/wireless/broadcom/b43legacy/main.c +++ b/drivers/net/wireless/broadcom/b43legacy/main.c @@ -3835,6 +3835,7 @@ static int b43legacy_wireless_init(struct ssb_device *dev) /* fill hw info */ ieee80211_hw_set(hw, RX_INCLUDES_FCS); ieee80211_hw_set(hw, SIGNAL_DBM); + ieee80211_hw_set(hw, MFP_CAPABLE); /* Allow WPA3 in software */ hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_AP) | From dc46fcf2ddff780cfb5c923e902bd1116ac00cd5 Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Tue, 5 May 2020 12:01:54 +0800 Subject: [PATCH 371/387] igb: Report speed and duplex as unknown when device is runtime suspended commit 165ae7a8feb53dc47fb041357e4b253bfc927cf9 upstream. igb device gets runtime suspended when there's no link partner. We can't get correct speed under that state: $ cat /sys/class/net/enp3s0/speed 1000 In addition to that, an error can also be spotted in dmesg: [ 385.991957] igb 0000:03:00.0 enp3s0: PCIe link lost Since device can only be runtime suspended when there's no link partner, we can skip reading register and let the following logic set speed and duplex with correct status. The more generic approach will be wrap get_link_ksettings() with begin() and complete() callbacks. However, for this particular issue, begin() calls igb_runtime_resume() , which tries to rtnl_lock() while the lock is already hold by upper ethtool layer. So let's take this approach until the igb_runtime_resume() no longer needs to hold rtnl_lock. CC: stable Suggested-by: Alexander Duyck Signed-off-by: Kai-Heng Feng Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/intel/igb/igb_ethtool.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c index 737b664d004c..b02e262ed76a 100644 --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c @@ -153,7 +153,8 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) u32 status; u32 speed; - status = rd32(E1000_STATUS); + status = pm_runtime_suspended(&adapter->pdev->dev) ? + 0 : rd32(E1000_STATUS); if (hw->phy.media_type == e1000_media_type_copper) { ecmd->supported = (SUPPORTED_10baseT_Half | From efb8d8753feb6180d0f845b1cacdf2f587ccf7f1 Mon Sep 17 00:00:00 2001 From: Anders Roxell Date: Wed, 27 May 2020 13:26:04 +0200 Subject: [PATCH 372/387] power: vexpress: add suppress_bind_attrs to true commit 73174acc9c75960af2daa7dcbdb9781fc0d135cb upstream. Make sure that the POWER_RESET_VEXPRESS driver won't have bind/unbind attributes available via the sysfs, so lets be explicit here and use ".suppress_bind_attrs = true" to prevent userspace from doing something silly. Link: https://lore.kernel.org/r/20200527112608.3886105-2-anders.roxell@linaro.org Cc: stable@vger.kernel.org Signed-off-by: Anders Roxell Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/power/reset/vexpress-poweroff.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/power/reset/vexpress-poweroff.c b/drivers/power/reset/vexpress-poweroff.c index e9e749f87517..8fb43c4438e6 100644 --- a/drivers/power/reset/vexpress-poweroff.c +++ b/drivers/power/reset/vexpress-poweroff.c @@ -150,6 +150,7 @@ static struct platform_driver vexpress_reset_driver = { .driver = { .name = "vexpress-reset", .of_match_table = vexpress_reset_of_match, + .suppress_bind_attrs = true, }, }; From c346341a3dc5a6d5ee0174605d664976e4097393 Mon Sep 17 00:00:00 2001 From: Jonathan Bakker Date: Sat, 25 Apr 2020 16:10:46 -0700 Subject: [PATCH 373/387] pinctrl: samsung: Save/restore eint_mask over suspend for EINT_TYPE GPIOs commit f354157a7d184db430c1a564c506434e33b1bec5 upstream. Currently, for EINT_TYPE GPIOs, the CON and FLTCON registers are saved and restored over a suspend/resume cycle. However, the EINT_MASK registers are not. On S5PV210 at the very least, these registers are not retained over suspend, leading to the interrupts remaining masked upon resume and therefore no interrupts being triggered for the device. There should be no effect on any SoCs that do retain these registers as theoretically we would just be re-writing what was already there. Fixes: 7ccbc60cd9c2 ("pinctrl: exynos: Handle suspend/resume of GPIO EINT registers") Cc: Signed-off-by: Jonathan Bakker Signed-off-by: Krzysztof Kozlowski Signed-off-by: Greg Kroah-Hartman --- drivers/pinctrl/samsung/pinctrl-exynos.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index e8aee6d88a40..6a23136bc813 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -289,6 +289,7 @@ struct exynos_eint_gpio_save { u32 eint_con; u32 eint_fltcon0; u32 eint_fltcon1; + u32 eint_mask; }; /* @@ -585,10 +586,13 @@ static void exynos_pinctrl_suspend_bank( + 2 * bank->eint_offset); save->eint_fltcon1 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET + 2 * bank->eint_offset + 4); + save->eint_mask = readl(regs + bank->irq_chip->eint_mask + + bank->eint_offset); pr_debug("%s: save con %#010x\n", bank->name, save->eint_con); pr_debug("%s: save fltcon0 %#010x\n", bank->name, save->eint_fltcon0); pr_debug("%s: save fltcon1 %#010x\n", bank->name, save->eint_fltcon1); + pr_debug("%s: save mask %#010x\n", bank->name, save->eint_mask); } static void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata) @@ -617,6 +621,9 @@ static void exynos_pinctrl_resume_bank( pr_debug("%s: fltcon1 %#010x => %#010x\n", bank->name, readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET + 2 * bank->eint_offset + 4), save->eint_fltcon1); + pr_debug("%s: mask %#010x => %#010x\n", bank->name, + readl(regs + bank->irq_chip->eint_mask + + bank->eint_offset), save->eint_mask); writel(save->eint_con, regs + EXYNOS_GPIO_ECON_OFFSET + bank->eint_offset); @@ -624,6 +631,8 @@ static void exynos_pinctrl_resume_bank( + 2 * bank->eint_offset); writel(save->eint_fltcon1, regs + EXYNOS_GPIO_EFLTCON_OFFSET + 2 * bank->eint_offset + 4); + writel(save->eint_mask, regs + bank->irq_chip->eint_mask + + bank->eint_offset); } static void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata) From 9c90a2d5693eeecbbb80e328e802a27ef65da42e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 17 May 2020 12:20:40 -0400 Subject: [PATCH 374/387] sparc32: fix register window handling in genregs32_[gs]et() commit cf51e129b96847f969bfb8af1ee1516a01a70b39 upstream. It needs access_process_vm() if the traced process does not share mm with the caller. Solution is similar to what sparc64 does. Note that genregs32_set() is only ever called with pos being 0 or 32 * sizeof(u32) (the latter - as part of PTRACE_SETREGS handling). Cc: stable@kernel.org Signed-off-by: Al Viro Signed-off-by: Greg Kroah-Hartman --- arch/sparc/kernel/ptrace_32.c | 228 +++++++++++++++------------------- 1 file changed, 98 insertions(+), 130 deletions(-) diff --git a/arch/sparc/kernel/ptrace_32.c b/arch/sparc/kernel/ptrace_32.c index a331fdc11a2c..396dbdea0cfa 100644 --- a/arch/sparc/kernel/ptrace_32.c +++ b/arch/sparc/kernel/ptrace_32.c @@ -45,82 +45,79 @@ enum sparc_regset { REGSET_FP, }; +static int regwindow32_get(struct task_struct *target, + const struct pt_regs *regs, + u32 *uregs) +{ + unsigned long reg_window = regs->u_regs[UREG_I6]; + int size = 16 * sizeof(u32); + + if (target == current) { + if (copy_from_user(uregs, (void __user *)reg_window, size)) + return -EFAULT; + } else { + if (access_process_vm(target, reg_window, uregs, size, + FOLL_FORCE) != size) + return -EFAULT; + } + return 0; +} + +static int regwindow32_set(struct task_struct *target, + const struct pt_regs *regs, + u32 *uregs) +{ + unsigned long reg_window = regs->u_regs[UREG_I6]; + int size = 16 * sizeof(u32); + + if (target == current) { + if (copy_to_user((void __user *)reg_window, uregs, size)) + return -EFAULT; + } else { + if (access_process_vm(target, reg_window, uregs, size, + FOLL_FORCE | FOLL_WRITE) != size) + return -EFAULT; + } + return 0; +} + static int genregs32_get(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) { const struct pt_regs *regs = target->thread.kregs; - unsigned long __user *reg_window; - unsigned long *k = kbuf; - unsigned long __user *u = ubuf; - unsigned long reg; + u32 uregs[16]; + int ret; if (target == current) flush_user_windows(); - pos /= sizeof(reg); - count /= sizeof(reg); + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + regs->u_regs, + 0, 16 * sizeof(u32)); + if (ret || !count) + return ret; - if (kbuf) { - for (; count > 0 && pos < 16; count--) - *k++ = regs->u_regs[pos++]; - - reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; - reg_window -= 16; - for (; count > 0 && pos < 32; count--) { - if (get_user(*k++, ®_window[pos++])) - return -EFAULT; - } - } else { - for (; count > 0 && pos < 16; count--) { - if (put_user(regs->u_regs[pos++], u++)) - return -EFAULT; - } - - reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; - reg_window -= 16; - for (; count > 0 && pos < 32; count--) { - if (get_user(reg, ®_window[pos++]) || - put_user(reg, u++)) - return -EFAULT; - } - } - while (count > 0) { - switch (pos) { - case 32: /* PSR */ - reg = regs->psr; - break; - case 33: /* PC */ - reg = regs->pc; - break; - case 34: /* NPC */ - reg = regs->npc; - break; - case 35: /* Y */ - reg = regs->y; - break; - case 36: /* WIM */ - case 37: /* TBR */ - reg = 0; - break; - default: - goto finish; - } - - if (kbuf) - *k++ = reg; - else if (put_user(reg, u++)) + if (pos < 32 * sizeof(u32)) { + if (regwindow32_get(target, regs, uregs)) return -EFAULT; - pos++; - count--; + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + uregs, + 16 * sizeof(u32), 32 * sizeof(u32)); + if (ret || !count) + return ret; } -finish: - pos *= sizeof(reg); - count *= sizeof(reg); - return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, - 38 * sizeof(reg), -1); + uregs[0] = regs->psr; + uregs[1] = regs->pc; + uregs[2] = regs->npc; + uregs[3] = regs->y; + uregs[4] = 0; /* WIM */ + uregs[5] = 0; /* TBR */ + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, + uregs, + 32 * sizeof(u32), 38 * sizeof(u32)); } static int genregs32_set(struct task_struct *target, @@ -129,82 +126,53 @@ static int genregs32_set(struct task_struct *target, const void *kbuf, const void __user *ubuf) { struct pt_regs *regs = target->thread.kregs; - unsigned long __user *reg_window; - const unsigned long *k = kbuf; - const unsigned long __user *u = ubuf; - unsigned long reg; + u32 uregs[16]; + u32 psr; + int ret; if (target == current) flush_user_windows(); - pos /= sizeof(reg); - count /= sizeof(reg); + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + regs->u_regs, + 0, 16 * sizeof(u32)); + if (ret || !count) + return ret; - if (kbuf) { - for (; count > 0 && pos < 16; count--) - regs->u_regs[pos++] = *k++; - - reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; - reg_window -= 16; - for (; count > 0 && pos < 32; count--) { - if (put_user(*k++, ®_window[pos++])) - return -EFAULT; - } - } else { - for (; count > 0 && pos < 16; count--) { - if (get_user(reg, u++)) - return -EFAULT; - regs->u_regs[pos++] = reg; - } - - reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; - reg_window -= 16; - for (; count > 0 && pos < 32; count--) { - if (get_user(reg, u++) || - put_user(reg, ®_window[pos++])) - return -EFAULT; - } - } - while (count > 0) { - unsigned long psr; - - if (kbuf) - reg = *k++; - else if (get_user(reg, u++)) + if (pos < 32 * sizeof(u32)) { + if (regwindow32_get(target, regs, uregs)) return -EFAULT; - - switch (pos) { - case 32: /* PSR */ - psr = regs->psr; - psr &= ~(PSR_ICC | PSR_SYSCALL); - psr |= (reg & (PSR_ICC | PSR_SYSCALL)); - regs->psr = psr; - break; - case 33: /* PC */ - regs->pc = reg; - break; - case 34: /* NPC */ - regs->npc = reg; - break; - case 35: /* Y */ - regs->y = reg; - break; - case 36: /* WIM */ - case 37: /* TBR */ - break; - default: - goto finish; - } - - pos++; - count--; + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + uregs, + 16 * sizeof(u32), 32 * sizeof(u32)); + if (ret) + return ret; + if (regwindow32_set(target, regs, uregs)) + return -EFAULT; + if (!count) + return 0; } -finish: - pos *= sizeof(reg); - count *= sizeof(reg); - + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &psr, + 32 * sizeof(u32), 33 * sizeof(u32)); + if (ret) + return ret; + regs->psr = (regs->psr & ~(PSR_ICC | PSR_SYSCALL)) | + (psr & (PSR_ICC | PSR_SYSCALL)); + if (!count) + return 0; + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + ®s->pc, + 33 * sizeof(u32), 34 * sizeof(u32)); + if (ret || !count) + return ret; + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + ®s->y, + 34 * sizeof(u32), 35 * sizeof(u32)); + if (ret || !count) + return ret; return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, - 38 * sizeof(reg), -1); + 35 * sizeof(u32), 38 * sizeof(u32)); } static int fpregs32_get(struct task_struct *target, From 3f948036c7f39e08f8c7170e000e466e85579b7c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 17 May 2020 15:37:50 -0400 Subject: [PATCH 375/387] sparc64: fix misuses of access_process_vm() in genregs32_[sg]et() commit 142cd25293f6a7ecbdff4fb0af17de6438d46433 upstream. We do need access_process_vm() to access the target's reg_window. However, access to caller's memory (storing the result in genregs32_get(), fetching the new values in case of genregs32_set()) should be done by normal uaccess primitives. Fixes: ad4f95764040 ([SPARC64]: Fix user accesses in regset code.) Cc: stable@kernel.org Signed-off-by: Al Viro Signed-off-by: Greg Kroah-Hartman --- arch/sparc/kernel/ptrace_64.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c index 7037ca3b4328..0a89a0546077 100644 --- a/arch/sparc/kernel/ptrace_64.c +++ b/arch/sparc/kernel/ptrace_64.c @@ -533,19 +533,13 @@ static int genregs32_get(struct task_struct *target, for (; count > 0 && pos < 32; count--) { if (access_process_vm(target, (unsigned long) - ®_window[pos], + ®_window[pos++], ®, sizeof(reg), FOLL_FORCE) != sizeof(reg)) return -EFAULT; - if (access_process_vm(target, - (unsigned long) u, - ®, sizeof(reg), - FOLL_FORCE | FOLL_WRITE) - != sizeof(reg)) + if (put_user(reg, u++)) return -EFAULT; - pos++; - u++; } } } @@ -645,12 +639,7 @@ static int genregs32_set(struct task_struct *target, } } else { for (; count > 0 && pos < 32; count--) { - if (access_process_vm(target, - (unsigned long) - u, - ®, sizeof(reg), - FOLL_FORCE) - != sizeof(reg)) + if (get_user(reg, u++)) return -EFAULT; if (access_process_vm(target, (unsigned long) From b7827de2fd7f9ee6d55c29aed23cc5a138338354 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Mon, 4 May 2020 10:50:17 -0700 Subject: [PATCH 376/387] kernel/cpu_pm: Fix uninitted local in cpu_pm commit b5945214b76a1f22929481724ffd448000ede914 upstream. cpu_pm_notify() is basically a wrapper of notifier_call_chain(). notifier_call_chain() doesn't initialize *nr_calls to 0 before it starts incrementing it--presumably it's up to the callers to do this. Unfortunately the callers of cpu_pm_notify() don't init *nr_calls. This potentially means you could get too many or two few calls to CPU_PM_ENTER_FAILED or CPU_CLUSTER_PM_ENTER_FAILED depending on the luck of the stack. Let's fix this. Fixes: ab10023e0088 ("cpu_pm: Add cpu power management notifiers") Cc: stable@vger.kernel.org Cc: Rafael J. Wysocki Reviewed-by: Stephen Boyd Reviewed-by: Greg Kroah-Hartman Signed-off-by: Douglas Anderson Link: https://lore.kernel.org/r/20200504104917.v6.3.I2d44fc0053d019f239527a4e5829416714b7e299@changeid Signed-off-by: Bjorn Andersson Signed-off-by: Greg Kroah-Hartman --- kernel/cpu_pm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/cpu_pm.c b/kernel/cpu_pm.c index 009cc9a17d95..f1042d639eee 100644 --- a/kernel/cpu_pm.c +++ b/kernel/cpu_pm.c @@ -97,7 +97,7 @@ EXPORT_SYMBOL_GPL(cpu_pm_unregister_notifier); */ int cpu_pm_enter(void) { - int nr_calls; + int nr_calls = 0; int ret = 0; read_lock(&cpu_pm_notifier_lock); @@ -156,7 +156,7 @@ EXPORT_SYMBOL_GPL(cpu_pm_exit); */ int cpu_cluster_pm_enter(void) { - int nr_calls; + int nr_calls = 0; int ret = 0; read_lock(&cpu_pm_notifier_lock); From 7dda6ebb5b30899da6eee8d1d0f554e64e2c2ac2 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Fri, 13 Mar 2020 12:01:04 +0300 Subject: [PATCH 377/387] ARM: tegra: Correct PL310 Auxiliary Control Register initialization commit 35509737c8f958944e059d501255a0bf18361ba0 upstream. The PL310 Auxiliary Control Register shouldn't have the "Full line of zero" optimization bit being set before L2 cache is enabled. The L2X0 driver takes care of enabling the optimization by itself. This patch fixes a noisy error message on Tegra20 and Tegra30 telling that cache optimization is erroneously enabled without enabling it for the CPU: L2C-310: enabling full line of zeros but not enabled in Cortex-A9 Cc: Signed-off-by: Dmitry Osipenko Tested-by: Nicolas Chauvet Signed-off-by: Thierry Reding Signed-off-by: Greg Kroah-Hartman --- arch/arm/mach-tegra/tegra.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c index e01cbca196b5..a67fcf7a5643 100644 --- a/arch/arm/mach-tegra/tegra.c +++ b/arch/arm/mach-tegra/tegra.c @@ -137,8 +137,8 @@ static const char * const tegra_dt_board_compat[] = { }; DT_MACHINE_START(TEGRA_DT, "NVIDIA Tegra SoC (Flattened Device Tree)") - .l2c_aux_val = 0x3c400001, - .l2c_aux_mask = 0xc20fc3fe, + .l2c_aux_val = 0x3c400000, + .l2c_aux_mask = 0xc20fc3ff, .smp = smp_ops(tegra_smp_ops), .map_io = tegra_map_common_io, .init_early = tegra_init_early, From 3255c2685239b9c165935f5d72562777631c735a Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 23 Apr 2020 16:00:38 +1000 Subject: [PATCH 378/387] drivers/macintosh: Fix memleak in windfarm_pm112 driver commit 93900337b9ac2f4eca427eff6d187be2dc3b5551 upstream. create_cpu_loop() calls smu_sat_get_sdb_partition() which does kmalloc() and returns the allocated buffer. In fact it's called twice, and neither buffer is freed. This results in a memory leak as reported by Erhard: unreferenced object 0xc00000047081f840 (size 32): comm "kwindfarm", pid 203, jiffies 4294880630 (age 5552.877s) hex dump (first 32 bytes): c8 06 02 7f ff 02 ff 01 fb bf 00 41 00 20 00 00 ...........A. .. 00 07 89 37 00 a0 00 00 00 00 00 00 00 00 00 00 ...7............ backtrace: [<0000000083f0a65c>] .smu_sat_get_sdb_partition+0xc4/0x2d0 [windfarm_smu_sat] [<000000003010fcb7>] .pm112_wf_notify+0x104c/0x13bc [windfarm_pm112] [<00000000b958b2dd>] .notifier_call_chain+0xa8/0x180 [<0000000070490868>] .blocking_notifier_call_chain+0x64/0x90 [<00000000131d8149>] .wf_thread_func+0x114/0x1a0 [<000000000d54838d>] .kthread+0x13c/0x190 [<00000000669b72bc>] .ret_from_kernel_thread+0x58/0x64 unreferenced object 0xc0000004737089f0 (size 16): comm "kwindfarm", pid 203, jiffies 4294880879 (age 5552.050s) hex dump (first 16 bytes): c4 04 01 7f 22 11 e0 e6 ff 55 7b 12 ec 11 00 00 ...."....U{..... backtrace: [<0000000083f0a65c>] .smu_sat_get_sdb_partition+0xc4/0x2d0 [windfarm_smu_sat] [<00000000b94ef7e1>] .pm112_wf_notify+0x1294/0x13bc [windfarm_pm112] [<00000000b958b2dd>] .notifier_call_chain+0xa8/0x180 [<0000000070490868>] .blocking_notifier_call_chain+0x64/0x90 [<00000000131d8149>] .wf_thread_func+0x114/0x1a0 [<000000000d54838d>] .kthread+0x13c/0x190 [<00000000669b72bc>] .ret_from_kernel_thread+0x58/0x64 Fix it by rearranging the logic so we deal with each buffer separately, which then makes it easy to free the buffer once we're done with it. Fixes: ac171c46667c ("[PATCH] powerpc: Thermal control for dual core G5s") Cc: stable@vger.kernel.org # v2.6.16+ Reported-by: Erhard F. Signed-off-by: Michael Ellerman Tested-by: Erhard F. Link: https://lore.kernel.org/r/20200423060038.3308530-1-mpe@ellerman.id.au Signed-off-by: Greg Kroah-Hartman --- drivers/macintosh/windfarm_pm112.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/macintosh/windfarm_pm112.c b/drivers/macintosh/windfarm_pm112.c index 96d16fca68b2..24e7152cd2bf 100644 --- a/drivers/macintosh/windfarm_pm112.c +++ b/drivers/macintosh/windfarm_pm112.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -133,14 +134,6 @@ static int create_cpu_loop(int cpu) s32 tmax; int fmin; - /* Get PID params from the appropriate SAT */ - hdr = smu_sat_get_sdb_partition(chip, 0xC8 + core, NULL); - if (hdr == NULL) { - printk(KERN_WARNING"windfarm: can't get CPU PID fan config\n"); - return -EINVAL; - } - piddata = (struct smu_sdbp_cpupiddata *)&hdr[1]; - /* Get FVT params to get Tmax; if not found, assume default */ hdr = smu_sat_get_sdb_partition(chip, 0xC4 + core, NULL); if (hdr) { @@ -153,6 +146,16 @@ static int create_cpu_loop(int cpu) if (tmax < cpu_all_tmax) cpu_all_tmax = tmax; + kfree(hdr); + + /* Get PID params from the appropriate SAT */ + hdr = smu_sat_get_sdb_partition(chip, 0xC8 + core, NULL); + if (hdr == NULL) { + printk(KERN_WARNING"windfarm: can't get CPU PID fan config\n"); + return -EINVAL; + } + piddata = (struct smu_sdbp_cpupiddata *)&hdr[1]; + /* * Darwin has a minimum fan speed of 1000 rpm for the 4-way and * 515 for the 2-way. That appears to be overkill, so for now, @@ -175,6 +178,9 @@ static int create_cpu_loop(int cpu) pid.min = fmin; wf_cpu_pid_init(&cpu_pid[cpu], &pid); + + kfree(hdr); + return 0; } From 5295e74327da34f6925036675ee85ffac654f1f9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 31 May 2020 17:47:06 +0900 Subject: [PATCH 379/387] kbuild: force to build vmlinux if CONFIG_MODVERSION=y commit 4b50c8c4eaf06a825d1c005c0b1b4a8307087b83 upstream. This code does not work as stated in the comment. $(CONFIG_MODVERSIONS) is always empty because it is expanded before include/config/auto.conf is included. Hence, 'make modules' with CONFIG_MODVERSION=y cannot record the version CRCs. This has been broken since 2003, commit ("kbuild: Enable modules to be build using the "make dir/" syntax"). [1] [1]: https://git.kernel.org/pub/scm/linux/kernel/git/history/history.git/commit/?id=15c6240cdc44bbeef3c4797ec860f9765ef4f1a7 Cc: linux-stable # v2.5.71+ Signed-off-by: Masahiro Yamada Signed-off-by: Greg Kroah-Hartman --- Makefile | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 6c3c6e193621..561659ab5f00 100644 --- a/Makefile +++ b/Makefile @@ -313,12 +313,8 @@ KBUILD_MODULES := KBUILD_BUILTIN := 1 # If we have only "make modules", don't compile built-in objects. -# When we're building modules with modversions, we need to consider -# the built-in objects during the descend as well, in order to -# make sure the checksums are up to date before we record them. - ifeq ($(MAKECMDGOALS),modules) - KBUILD_BUILTIN := $(if $(CONFIG_MODVERSIONS),1) + KBUILD_BUILTIN := endif # If we have "make modules", compile modules @@ -1237,6 +1233,13 @@ ifdef CONFIG_MODULES all: modules +# When we're building modules with modversions, we need to consider +# the built-in objects during the descend as well, in order to +# make sure the checksums are up to date before we record them. +ifdef CONFIG_MODVERSIONS + KBUILD_BUILTIN := 1 +endif + # Build modules # # A module can be listed more than once in obj-m resulting in From 59b68cab2edd319095dede47acf349855a7176c6 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 22 May 2020 12:01:33 +1000 Subject: [PATCH 380/387] sunrpc: svcauth_gss_register_pseudoflavor must reject duplicate registrations. commit d47a5dc2888fd1b94adf1553068b8dad76cec96c upstream. There is no valid case for supporting duplicate pseudoflavor registrations. Currently the silent acceptance of such registrations is hiding a bug. The rpcsec_gss_krb5 module registers 2 flavours but does not unregister them, so if you load, unload, reload the module, it will happily continue to use the old registration which now has pointers to the memory were the module was originally loaded. This could lead to unexpected results. So disallow duplicate registrations. Link: https://bugzilla.kernel.org/show_bug.cgi?id=206651 Cc: stable@vger.kernel.org (v2.6.12+) Signed-off-by: NeilBrown Signed-off-by: J. Bruce Fields Signed-off-by: Greg Kroah-Hartman --- net/sunrpc/auth_gss/svcauth_gss.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index d7775ca2fbb9..25a972a236a7 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c @@ -796,9 +796,11 @@ svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name) new->h.flavour = &svcauthops_gss; new->pseudoflavor = pseudoflavor; - stat = 0; test = auth_domain_lookup(name, &new->h); - if (test != &new->h) { /* Duplicate registration */ + if (test != &new->h) { + pr_warn("svc: duplicate registration of gss pseudo flavour %s.\n", + name); + stat = -EADDRINUSE; auth_domain_put(test); kfree(new->h.name); goto out_free_dom; From d32887e72c6a51c60f4f10b22c6c5c227814d091 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 22 May 2020 12:01:33 +1000 Subject: [PATCH 381/387] sunrpc: clean up properly in gss_mech_unregister() commit 24c5efe41c29ee3e55bcf5a1c9f61ca8709622e8 upstream. gss_mech_register() calls svcauth_gss_register_pseudoflavor() for each flavour, but gss_mech_unregister() does not call auth_domain_put(). This is unbalanced and makes it impossible to reload the module. Change svcauth_gss_register_pseudoflavor() to return the registered auth_domain, and save it for later release. Cc: stable@vger.kernel.org (v2.6.12+) Link: https://bugzilla.kernel.org/show_bug.cgi?id=206651 Signed-off-by: NeilBrown Signed-off-by: J. Bruce Fields Signed-off-by: Greg Kroah-Hartman --- include/linux/sunrpc/gss_api.h | 1 + include/linux/sunrpc/svcauth_gss.h | 3 ++- net/sunrpc/auth_gss/gss_mech_switch.c | 12 +++++++++--- net/sunrpc/auth_gss/svcauth_gss.c | 12 ++++++------ 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/include/linux/sunrpc/gss_api.h b/include/linux/sunrpc/gss_api.h index 68ec78c1aa48..bd8480ae82e9 100644 --- a/include/linux/sunrpc/gss_api.h +++ b/include/linux/sunrpc/gss_api.h @@ -82,6 +82,7 @@ struct pf_desc { u32 service; char *name; char *auth_domain_name; + struct auth_domain *domain; bool datatouch; }; diff --git a/include/linux/sunrpc/svcauth_gss.h b/include/linux/sunrpc/svcauth_gss.h index 726aff1a5201..213fa12f56fc 100644 --- a/include/linux/sunrpc/svcauth_gss.h +++ b/include/linux/sunrpc/svcauth_gss.h @@ -20,7 +20,8 @@ int gss_svc_init(void); void gss_svc_shutdown(void); int gss_svc_init_net(struct net *net); void gss_svc_shutdown_net(struct net *net); -int svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name); +struct auth_domain *svcauth_gss_register_pseudoflavor(u32 pseudoflavor, + char *name); u32 svcauth_gss_flavor(struct auth_domain *dom); #endif /* __KERNEL__ */ diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c index 5fec3abbe19b..c7d88f979c56 100644 --- a/net/sunrpc/auth_gss/gss_mech_switch.c +++ b/net/sunrpc/auth_gss/gss_mech_switch.c @@ -61,6 +61,8 @@ gss_mech_free(struct gss_api_mech *gm) for (i = 0; i < gm->gm_pf_num; i++) { pf = &gm->gm_pfs[i]; + if (pf->domain) + auth_domain_put(pf->domain); kfree(pf->auth_domain_name); pf->auth_domain_name = NULL; } @@ -83,6 +85,7 @@ make_auth_domain_name(char *name) static int gss_mech_svc_setup(struct gss_api_mech *gm) { + struct auth_domain *dom; struct pf_desc *pf; int i, status; @@ -92,10 +95,13 @@ gss_mech_svc_setup(struct gss_api_mech *gm) status = -ENOMEM; if (pf->auth_domain_name == NULL) goto out; - status = svcauth_gss_register_pseudoflavor(pf->pseudoflavor, - pf->auth_domain_name); - if (status) + dom = svcauth_gss_register_pseudoflavor( + pf->pseudoflavor, pf->auth_domain_name); + if (IS_ERR(dom)) { + status = PTR_ERR(dom); goto out; + } + pf->domain = dom; } return 0; out: diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 25a972a236a7..fd897d900d12 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c @@ -779,7 +779,7 @@ u32 svcauth_gss_flavor(struct auth_domain *dom) EXPORT_SYMBOL_GPL(svcauth_gss_flavor); -int +struct auth_domain * svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name) { struct gss_domain *new; @@ -802,17 +802,17 @@ svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name) name); stat = -EADDRINUSE; auth_domain_put(test); - kfree(new->h.name); - goto out_free_dom; + goto out_free_name; } - return 0; + return test; +out_free_name: + kfree(new->h.name); out_free_dom: kfree(new); out: - return stat; + return ERR_PTR(stat); } - EXPORT_SYMBOL_GPL(svcauth_gss_register_pseudoflavor); static inline int From 4b5e5d10a422033c2eddb80c9c0e63d872709da5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Tue, 12 May 2020 09:57:32 +0200 Subject: [PATCH 382/387] mtd: rawnand: brcmnand: fix hamming oob layout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 130bbde4809b011faf64f99dddc14b4b01f440c3 upstream. First 2 bytes are used in large-page nand. Fixes: ef5eeea6e911 ("mtd: nand: brcm: switch to mtd_ooblayout_ops") Cc: stable@vger.kernel.org Signed-off-by: Álvaro Fernández Rojas Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20200512075733.745374-2-noltari@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/nand/brcmnand/brcmnand.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c index ef9a6b22c9fa..1291492a1cef 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/brcmnand/brcmnand.c @@ -911,11 +911,14 @@ static int brcmnand_hamming_ooblayout_free(struct mtd_info *mtd, int section, if (!section) { /* * Small-page NAND use byte 6 for BBI while large-page - * NAND use byte 0. + * NAND use bytes 0 and 1. */ - if (cfg->page_size > 512) - oobregion->offset++; - oobregion->length--; + if (cfg->page_size > 512) { + oobregion->offset += 2; + oobregion->length -= 2; + } else { + oobregion->length--; + } } } From 07725316c9a4003781973c2e8937f01c86cdd601 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Tue, 19 May 2020 15:00:13 +0200 Subject: [PATCH 383/387] mtd: rawnand: pasemi: Fix the probe error path commit f51466901c07e6930435d30b02a21f0841174f61 upstream. nand_cleanup() is supposed to be called on error after a successful call to nand_scan() to free all NAND resources. There is no real Fixes tag applying here as the use of nand_release() in this driver predates by far the introduction of nand_cleanup() in commit d44154f969a4 ("mtd: nand: Provide nand_cleanup() function to free NAND related resources") which makes this change possible, hence pointing it as the commit to fix for backporting purposes, even if this commit is not introducing any bug. Fixes: d44154f969a4 ("mtd: nand: Provide nand_cleanup() function to free NAND related resources") Signed-off-by: Miquel Raynal Cc: stable@vger.kernel.org Link: https://lore.kernel.org/linux-mtd/20200519130035.1883-41-miquel.raynal@bootlin.com Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/nand/pasemi_nand.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c index 5de7591b0510..80c98eef44d9 100644 --- a/drivers/mtd/nand/pasemi_nand.c +++ b/drivers/mtd/nand/pasemi_nand.c @@ -164,7 +164,7 @@ static int pasemi_nand_probe(struct platform_device *ofdev) if (mtd_device_register(pasemi_nand_mtd, NULL, 0)) { dev_err(dev, "Unable to register MTD device\n"); err = -ENODEV; - goto out_lpc; + goto out_cleanup_nand; } dev_info(dev, "PA Semi NAND flash at %pR, control at I/O %x\n", &res, @@ -172,6 +172,8 @@ static int pasemi_nand_probe(struct platform_device *ofdev) return 0; + out_cleanup_nand: + nand_cleanup(chip); out_lpc: release_region(lpcctl, 4); out_ior: From 05f3752fd72a975f5568db0631cb102b9a9f5dde Mon Sep 17 00:00:00 2001 From: "H. Nikolaus Schaller" Date: Sat, 23 May 2020 19:32:54 +0200 Subject: [PATCH 384/387] w1: omap-hdq: cleanup to add missing newline for some dev_dbg commit 5e02f3b31704e24537697bce54f8156bdb72b7a6 upstream. Otherwise it will corrupt the console log during debugging. Fixes: 7b5362a603a1 ("w1: omap_hdq: Fix some error/debug handling.") Cc: stable@vger.kernel.org Acked-by: Tony Lindgren Signed-off-by: H. Nikolaus Schaller Link: https://lore.kernel.org/r/cd0d55749a091214106575f6e1d363c6db56622f.1590255176.git.hns@goldelico.com Signed-off-by: Greg Kroah-Hartman --- drivers/w1/masters/omap_hdq.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c index 86637fec4eaa..6bc6823f81fa 100644 --- a/drivers/w1/masters/omap_hdq.c +++ b/drivers/w1/masters/omap_hdq.c @@ -204,7 +204,7 @@ static int hdq_write_byte(struct hdq_data *hdq_data, u8 val, u8 *status) /* check irqstatus */ if (!(*status & OMAP_HDQ_INT_STATUS_TXCOMPLETE)) { dev_dbg(hdq_data->dev, "timeout waiting for" - " TXCOMPLETE/RXCOMPLETE, %x", *status); + " TXCOMPLETE/RXCOMPLETE, %x\n", *status); ret = -ETIMEDOUT; goto out; } @@ -215,7 +215,7 @@ static int hdq_write_byte(struct hdq_data *hdq_data, u8 val, u8 *status) OMAP_HDQ_FLAG_CLEAR, &tmp_status); if (ret) { dev_dbg(hdq_data->dev, "timeout waiting GO bit" - " return to zero, %x", tmp_status); + " return to zero, %x\n", tmp_status); } out: @@ -231,7 +231,7 @@ static irqreturn_t hdq_isr(int irq, void *_hdq) spin_lock_irqsave(&hdq_data->hdq_spinlock, irqflags); hdq_data->hdq_irqstatus = hdq_reg_in(hdq_data, OMAP_HDQ_INT_STATUS); spin_unlock_irqrestore(&hdq_data->hdq_spinlock, irqflags); - dev_dbg(hdq_data->dev, "hdq_isr: %x", hdq_data->hdq_irqstatus); + dev_dbg(hdq_data->dev, "hdq_isr: %x\n", hdq_data->hdq_irqstatus); if (hdq_data->hdq_irqstatus & (OMAP_HDQ_INT_STATUS_TXCOMPLETE | OMAP_HDQ_INT_STATUS_RXCOMPLETE @@ -339,7 +339,7 @@ static int omap_hdq_break(struct hdq_data *hdq_data) tmp_status = hdq_data->hdq_irqstatus; /* check irqstatus */ if (!(tmp_status & OMAP_HDQ_INT_STATUS_TIMEOUT)) { - dev_dbg(hdq_data->dev, "timeout waiting for TIMEOUT, %x", + dev_dbg(hdq_data->dev, "timeout waiting for TIMEOUT, %x\n", tmp_status); ret = -ETIMEDOUT; goto out; @@ -366,7 +366,7 @@ static int omap_hdq_break(struct hdq_data *hdq_data) &tmp_status); if (ret) dev_dbg(hdq_data->dev, "timeout waiting INIT&GO bits" - " return to zero, %x", tmp_status); + " return to zero, %x\n", tmp_status); out: mutex_unlock(&hdq_data->hdq_mutex); From a1d8696eff0619f2a36adbc62260fa8330a0f165 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Thu, 23 Apr 2020 20:01:22 +0900 Subject: [PATCH 385/387] perf probe: Do not show the skipped events commit f41ebe9defacddeae96a872a33f0f22ced0bfcef upstream. When a probe point is expanded to several places (like inlined) and if some of them are skipped because of blacklisted or __init function, those trace_events has no event name. It must be skipped while showing results. Without this fix, you can see "(null):(null)" on the list, # ./perf probe request_resource reserve_setup is out of .text, skip it. Added new events: (null):(null) (on request_resource) probe:request_resource (on request_resource) You can now use it in all perf tools, such as: perf record -e probe:request_resource -aR sleep 1 # With this fix, it is ignored: # ./perf probe request_resource reserve_setup is out of .text, skip it. Added new events: probe:request_resource (on request_resource) You can now use it in all perf tools, such as: perf record -e probe:request_resource -aR sleep 1 # Fixes: 5a51fcd1f30c ("perf probe: Skip kernel symbols which is out of .text") Signed-off-by: Masami Hiramatsu Tested-by: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Namhyung Kim Cc: stable@vger.kernel.org Link: http://lore.kernel.org/lkml/158763968263.30755.12800484151476026340.stgit@devnote2 Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Greg Kroah-Hartman --- tools/perf/builtin-probe.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index 2b420e7a92c0..929f0d0ea9da 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c @@ -344,6 +344,9 @@ static int perf_add_probe_events(struct perf_probe_event *pevs, int npevs) for (k = 0; k < pev->ntevs; k++) { struct probe_trace_event *tev = &pev->tevs[k]; + /* Skipped events have no event name */ + if (!tev->event) + continue; /* We use tev's name for showing new events */ show_perf_probe_event(tev->group, tev->event, pev, From 74c9406e6c1041b9c0e6658b8b4b601fcc581f71 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 26 May 2020 18:52:07 +0300 Subject: [PATCH 386/387] perf symbols: Fix debuginfo search for Ubuntu commit 85afd35575a3c1a3a905722dde5ee70b49282e70 upstream. Reportedly, from 19.10 Ubuntu has begun mixing up the location of some debug symbol files, putting files expected to be in /usr/lib/debug/usr/lib into /usr/lib/debug/lib instead. Fix by adding another dso_binary_type. Example on Ubuntu 20.04 Before: $ perf record -e intel_pt//u uname Linux [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.030 MB perf.data ] $ perf script --call-trace | head -5 uname 14003 [005] 15321.764958566: cbr: 42 freq: 4219 MHz (156%) uname 14003 [005] 15321.764958566: (/usr/lib/x86_64-linux-gnu/ld-2.31.so ) 7f1e71cc4100 uname 14003 [005] 15321.764961566: (/usr/lib/x86_64-linux-gnu/ld-2.31.so ) 7f1e71cc4df0 uname 14003 [005] 15321.764961900: (/usr/lib/x86_64-linux-gnu/ld-2.31.so ) 7f1e71cc4e18 uname 14003 [005] 15321.764963233: (/usr/lib/x86_64-linux-gnu/ld-2.31.so ) 7f1e71cc5128 After: $ perf script --call-trace | head -5 uname 14003 [005] 15321.764958566: cbr: 42 freq: 4219 MHz (156%) uname 14003 [005] 15321.764958566: (/usr/lib/x86_64-linux-gnu/ld-2.31.so ) _start uname 14003 [005] 15321.764961566: (/usr/lib/x86_64-linux-gnu/ld-2.31.so ) _dl_start uname 14003 [005] 15321.764961900: (/usr/lib/x86_64-linux-gnu/ld-2.31.so ) _dl_start uname 14003 [005] 15321.764963233: (/usr/lib/x86_64-linux-gnu/ld-2.31.so ) _dl_start Reported-by: Travis Downs Signed-off-by: Adrian Hunter Cc: Jiri Olsa Cc: stable@vger.kernel.org Link: http://lore.kernel.org/lkml/20200526155207.9172-1-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Greg Kroah-Hartman --- tools/perf/util/dso.c | 16 ++++++++++++++++ tools/perf/util/dso.h | 1 + tools/perf/util/probe-finder.c | 1 + tools/perf/util/symbol.c | 2 ++ 4 files changed, 20 insertions(+) diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 8bec05365aae..9be7c95bd1e1 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -19,6 +19,7 @@ char dso__symtab_origin(const struct dso *dso) [DSO_BINARY_TYPE__BUILD_ID_CACHE] = 'B', [DSO_BINARY_TYPE__FEDORA_DEBUGINFO] = 'f', [DSO_BINARY_TYPE__UBUNTU_DEBUGINFO] = 'u', + [DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO] = 'x', [DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO] = 'o', [DSO_BINARY_TYPE__BUILDID_DEBUGINFO] = 'b', [DSO_BINARY_TYPE__SYSTEM_PATH_DSO] = 'd', @@ -77,6 +78,21 @@ int dso__read_binary_type_filename(const struct dso *dso, snprintf(filename + len, size - len, "%s", dso->long_name); break; + case DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO: + /* + * Ubuntu can mixup /usr/lib with /lib, putting debuginfo in + * /usr/lib/debug/lib when it is expected to be in + * /usr/lib/debug/usr/lib + */ + if (strlen(dso->long_name) < 9 || + strncmp(dso->long_name, "/usr/lib/", 9)) { + ret = -1; + break; + } + len = __symbol__join_symfs(filename, size, "/usr/lib/debug"); + snprintf(filename + len, size - len, "%s", dso->long_name + 4); + break; + case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO: { const char *last_slash; diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index ecc4bbd3f82e..b886720ffea0 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -22,6 +22,7 @@ enum dso_binary_type { DSO_BINARY_TYPE__BUILD_ID_CACHE, DSO_BINARY_TYPE__FEDORA_DEBUGINFO, DSO_BINARY_TYPE__UBUNTU_DEBUGINFO, + DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO, DSO_BINARY_TYPE__BUILDID_DEBUGINFO, DSO_BINARY_TYPE__SYSTEM_PATH_DSO, DSO_BINARY_TYPE__GUEST_KMODULE, diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 82e4f158c88e..7d0d44b4f3d5 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -111,6 +111,7 @@ enum dso_binary_type distro_dwarf_types[] = { DSO_BINARY_TYPE__UBUNTU_DEBUGINFO, DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO, DSO_BINARY_TYPE__BUILDID_DEBUGINFO, + DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO, DSO_BINARY_TYPE__NOT_FOUND, }; diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index acde8e489352..4e27b868f774 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -58,6 +58,7 @@ static enum dso_binary_type binary_type_symtab[] = { DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE, DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP, DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO, + DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO, DSO_BINARY_TYPE__NOT_FOUND, }; @@ -1361,6 +1362,7 @@ static bool dso__is_compatible_symtab_type(struct dso *dso, bool kmod, case DSO_BINARY_TYPE__SYSTEM_PATH_DSO: case DSO_BINARY_TYPE__FEDORA_DEBUGINFO: case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO: + case DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO: case DSO_BINARY_TYPE__BUILDID_DEBUGINFO: case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO: return !kmod && dso->kernel == DSO_TYPE_USER; From 45b83c1819d408f46ef4ac3d07b92ba61c86d1e9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 20 Jun 2020 10:24:22 +0200 Subject: [PATCH 387/387] Linux 4.9.228 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 561659ab5f00..af23d7b67442 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 4 PATCHLEVEL = 9 -SUBLEVEL = 227 +SUBLEVEL = 228 EXTRAVERSION = NAME = Roaring Lionus