From: Greg Kroah-Hartman Date: Mon, 9 May 2022 10:37:21 +0000 (+0200) Subject: 4.14-stable patches X-Git-Tag: v4.9.313~71 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=531b215e2701eac96c30aca98f03af5ab75c4fd8;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: asoc-dmaengine-restore-null-prepare_slave_config-callback.patch hwmon-adt7470-fix-warning-on-module-removal.patch nfc-netlink-fix-sleep-in-atomic-bug-when-firmware-download-timeout.patch nfc-nfcmrvl-main-reorder-destructive-operations-in-nfcmrvl_nci_unregister_dev-to-avoid-bugs.patch nfc-replace-improper-check-device_is_registered-in-netlink-related-functions.patch --- diff --git a/queue-4.14/asoc-dmaengine-restore-null-prepare_slave_config-callback.patch b/queue-4.14/asoc-dmaengine-restore-null-prepare_slave_config-callback.patch new file mode 100644 index 00000000000..7a682b52d31 --- /dev/null +++ b/queue-4.14/asoc-dmaengine-restore-null-prepare_slave_config-callback.patch @@ -0,0 +1,49 @@ +From 660564fc9a92a893a14f255be434f7ea0b967901 Mon Sep 17 00:00:00 2001 +From: Codrin Ciubotariu +Date: Thu, 21 Apr 2022 15:54:02 +0300 +Subject: ASoC: dmaengine: Restore NULL prepare_slave_config() callback + +From: Codrin Ciubotariu + +commit 660564fc9a92a893a14f255be434f7ea0b967901 upstream. + +As pointed out by Sascha Hauer, this patch changes: +if (pmc->config && !pcm->config->prepare_slave_config) + +to: +if (pmc->config && !pcm->config->prepare_slave_config) + snd_dmaengine_pcm_prepare_slave_config() + +This breaks the drivers that do not need a call to +dmaengine_slave_config(). Drivers that still need to call +snd_dmaengine_pcm_prepare_slave_config(), but have a NULL +pcm->config->prepare_slave_config should use +snd_dmaengine_pcm_prepare_slave_config() as their prepare_slave_config +callback. + +Fixes: 9a1e13440a4f ("ASoC: dmaengine: do not use a NULL prepare_slave_config() callback") +Reported-by: Sascha Hauer +Signed-off-by: Codrin Ciubotariu +Link: https://lore.kernel.org/r/20220421125403.2180824-1-codrin.ciubotariu@microchip.com +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + sound/soc/soc-generic-dmaengine-pcm.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/sound/soc/soc-generic-dmaengine-pcm.c ++++ b/sound/soc/soc-generic-dmaengine-pcm.c +@@ -98,10 +98,10 @@ static int dmaengine_pcm_hw_params(struc + + memset(&slave_config, 0, sizeof(slave_config)); + +- if (pcm->config && pcm->config->prepare_slave_config) +- prepare_slave_config = pcm->config->prepare_slave_config; +- else ++ if (!pcm->config) + prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config; ++ else ++ prepare_slave_config = pcm->config->prepare_slave_config; + + if (prepare_slave_config) { + ret = prepare_slave_config(substream, params, &slave_config); diff --git a/queue-4.14/hwmon-adt7470-fix-warning-on-module-removal.patch b/queue-4.14/hwmon-adt7470-fix-warning-on-module-removal.patch new file mode 100644 index 00000000000..f6cb0434039 --- /dev/null +++ b/queue-4.14/hwmon-adt7470-fix-warning-on-module-removal.patch @@ -0,0 +1,57 @@ +From 7b2666ce445c700b8dcee994da44ddcf050a0842 Mon Sep 17 00:00:00 2001 +From: Armin Wolf +Date: Thu, 7 Apr 2022 12:13:12 +0200 +Subject: hwmon: (adt7470) Fix warning on module removal + +From: Armin Wolf + +commit 7b2666ce445c700b8dcee994da44ddcf050a0842 upstream. + +When removing the adt7470 module, a warning might be printed: + +do not call blocking ops when !TASK_RUNNING; state=1 +set at [] adt7470_update_thread+0x7b/0x130 [adt7470] + +This happens because adt7470_update_thread() can leave the kthread in +TASK_INTERRUPTIBLE state when the kthread is being stopped before +the call of set_current_state(). Since kthread_exit() might sleep in +exit_signals(), the warning is printed. +Fix that by using schedule_timeout_interruptible() and removing +the call of set_current_state(). +This causes TASK_INTERRUPTIBLE to be set after kthread_should_stop() +which might cause the kthread to exit. + +Reported-by: Zheyu Ma +Fixes: 93cacfd41f82 (hwmon: (adt7470) Allow faster removal) +Signed-off-by: Armin Wolf +Tested-by: Zheyu Ma +Link: https://lore.kernel.org/r/20220407101312.13331-1-W_Armin@gmx.de +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hwmon/adt7470.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/hwmon/adt7470.c ++++ b/drivers/hwmon/adt7470.c +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + + /* Addresses to scan */ + static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END }; +@@ -273,11 +274,10 @@ static int adt7470_update_thread(void *p + adt7470_read_temperatures(client, data); + mutex_unlock(&data->lock); + +- set_current_state(TASK_INTERRUPTIBLE); + if (kthread_should_stop()) + break; + +- schedule_timeout(msecs_to_jiffies(data->auto_update_interval)); ++ schedule_timeout_interruptible(msecs_to_jiffies(data->auto_update_interval)); + } + + return 0; diff --git a/queue-4.14/nfc-netlink-fix-sleep-in-atomic-bug-when-firmware-download-timeout.patch b/queue-4.14/nfc-netlink-fix-sleep-in-atomic-bug-when-firmware-download-timeout.patch new file mode 100644 index 00000000000..ad79f33d12f --- /dev/null +++ b/queue-4.14/nfc-netlink-fix-sleep-in-atomic-bug-when-firmware-download-timeout.patch @@ -0,0 +1,65 @@ +From 4071bf121d59944d5cd2238de0642f3d7995a997 Mon Sep 17 00:00:00 2001 +From: Duoming Zhou +Date: Wed, 4 May 2022 13:58:47 +0800 +Subject: NFC: netlink: fix sleep in atomic bug when firmware download timeout + +From: Duoming Zhou + +commit 4071bf121d59944d5cd2238de0642f3d7995a997 upstream. + +There are sleep in atomic bug that could cause kernel panic during +firmware download process. The root cause is that nlmsg_new with +GFP_KERNEL parameter is called in fw_dnld_timeout which is a timer +handler. The call trace is shown below: + +BUG: sleeping function called from invalid context at include/linux/sched/mm.h:265 +Call Trace: +kmem_cache_alloc_node +__alloc_skb +nfc_genl_fw_download_done +call_timer_fn +__run_timers.part.0 +run_timer_softirq +__do_softirq +... + +The nlmsg_new with GFP_KERNEL parameter may sleep during memory +allocation process, and the timer handler is run as the result of +a "software interrupt" that should not call any other function +that could sleep. + +This patch changes allocation mode of netlink message from GFP_KERNEL +to GFP_ATOMIC in order to prevent sleep in atomic bug. The GFP_ATOMIC +flag makes memory allocation operation could be used in atomic context. + +Fixes: 9674da8759df ("NFC: Add firmware upload netlink command") +Fixes: 9ea7187c53f6 ("NFC: netlink: Rename CMD_FW_UPLOAD to CMD_FW_DOWNLOAD") +Signed-off-by: Duoming Zhou +Reviewed-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/r/20220504055847.38026-1-duoming@zju.edu.cn +Signed-off-by: Paolo Abeni +Signed-off-by: Greg Kroah-Hartman +--- + net/nfc/netlink.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/nfc/netlink.c ++++ b/net/nfc/netlink.c +@@ -1251,7 +1251,7 @@ int nfc_genl_fw_download_done(struct nfc + struct sk_buff *msg; + void *hdr; + +- msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); ++ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); + if (!msg) + return -ENOMEM; + +@@ -1267,7 +1267,7 @@ int nfc_genl_fw_download_done(struct nfc + + genlmsg_end(msg, hdr); + +- genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL); ++ genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_ATOMIC); + + return 0; + diff --git a/queue-4.14/nfc-nfcmrvl-main-reorder-destructive-operations-in-nfcmrvl_nci_unregister_dev-to-avoid-bugs.patch b/queue-4.14/nfc-nfcmrvl-main-reorder-destructive-operations-in-nfcmrvl_nci_unregister_dev-to-avoid-bugs.patch new file mode 100644 index 00000000000..693358735b9 --- /dev/null +++ b/queue-4.14/nfc-nfcmrvl-main-reorder-destructive-operations-in-nfcmrvl_nci_unregister_dev-to-avoid-bugs.patch @@ -0,0 +1,113 @@ +From d270453a0d9ec10bb8a802a142fb1b3601a83098 Mon Sep 17 00:00:00 2001 +From: Duoming Zhou +Date: Fri, 29 Apr 2022 20:45:51 +0800 +Subject: nfc: nfcmrvl: main: reorder destructive operations in nfcmrvl_nci_unregister_dev to avoid bugs + +From: Duoming Zhou + +commit d270453a0d9ec10bb8a802a142fb1b3601a83098 upstream. + +There are destructive operations such as nfcmrvl_fw_dnld_abort and +gpio_free in nfcmrvl_nci_unregister_dev. The resources such as firmware, +gpio and so on could be destructed while the upper layer functions such as +nfcmrvl_fw_dnld_start and nfcmrvl_nci_recv_frame is executing, which leads +to double-free, use-after-free and null-ptr-deref bugs. + +There are three situations that could lead to double-free bugs. + +The first situation is shown below: + + (Thread 1) | (Thread 2) +nfcmrvl_fw_dnld_start | + ... | nfcmrvl_nci_unregister_dev + release_firmware() | nfcmrvl_fw_dnld_abort + kfree(fw) //(1) | fw_dnld_over + | release_firmware + ... | kfree(fw) //(2) + | ... + +The second situation is shown below: + + (Thread 1) | (Thread 2) +nfcmrvl_fw_dnld_start | + ... | + mod_timer | + (wait a time) | + fw_dnld_timeout | nfcmrvl_nci_unregister_dev + fw_dnld_over | nfcmrvl_fw_dnld_abort + release_firmware | fw_dnld_over + kfree(fw) //(1) | release_firmware + ... | kfree(fw) //(2) + +The third situation is shown below: + + (Thread 1) | (Thread 2) +nfcmrvl_nci_recv_frame | + if(..->fw_download_in_progress)| + nfcmrvl_fw_dnld_recv_frame | + queue_work | + | +fw_dnld_rx_work | nfcmrvl_nci_unregister_dev + fw_dnld_over | nfcmrvl_fw_dnld_abort + release_firmware | fw_dnld_over + kfree(fw) //(1) | release_firmware + | kfree(fw) //(2) + +The firmware struct is deallocated in position (1) and deallocated +in position (2) again. + +The crash trace triggered by POC is like below: + +BUG: KASAN: double-free or invalid-free in fw_dnld_over +Call Trace: + kfree + fw_dnld_over + nfcmrvl_nci_unregister_dev + nci_uart_tty_close + tty_ldisc_kill + tty_ldisc_hangup + __tty_hangup.part.0 + tty_release + ... + +What's more, there are also use-after-free and null-ptr-deref bugs +in nfcmrvl_fw_dnld_start. If we deallocate firmware struct, gpio or +set null to the members of priv->fw_dnld in nfcmrvl_nci_unregister_dev, +then, we dereference firmware, gpio or the members of priv->fw_dnld in +nfcmrvl_fw_dnld_start, the UAF or NPD bugs will happen. + +This patch reorders destructive operations after nci_unregister_device +in order to synchronize between cleanup routine and firmware download +routine. + +The nci_unregister_device is well synchronized. If the device is +detaching, the firmware download routine will goto error. If firmware +download routine is executing, nci_unregister_device will wait until +firmware download routine is finished. + +Fixes: 3194c6870158 ("NFC: nfcmrvl: add firmware download support") +Signed-off-by: Duoming Zhou +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nfc/nfcmrvl/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/nfc/nfcmrvl/main.c ++++ b/drivers/nfc/nfcmrvl/main.c +@@ -194,6 +194,7 @@ void nfcmrvl_nci_unregister_dev(struct n + { + struct nci_dev *ndev = priv->ndev; + ++ nci_unregister_device(ndev); + if (priv->ndev->nfc_dev->fw_download_in_progress) + nfcmrvl_fw_dnld_abort(priv); + +@@ -202,7 +203,6 @@ void nfcmrvl_nci_unregister_dev(struct n + if (gpio_is_valid(priv->config.reset_n_io)) + gpio_free(priv->config.reset_n_io); + +- nci_unregister_device(ndev); + nci_free_device(ndev); + kfree(priv); + } diff --git a/queue-4.14/nfc-replace-improper-check-device_is_registered-in-netlink-related-functions.patch b/queue-4.14/nfc-replace-improper-check-device_is_registered-in-netlink-related-functions.patch new file mode 100644 index 00000000000..5fba094a9ea --- /dev/null +++ b/queue-4.14/nfc-replace-improper-check-device_is_registered-in-netlink-related-functions.patch @@ -0,0 +1,172 @@ +From da5c0f119203ad9728920456a0f52a6d850c01cd Mon Sep 17 00:00:00 2001 +From: Duoming Zhou +Date: Fri, 29 Apr 2022 20:45:50 +0800 +Subject: nfc: replace improper check device_is_registered() in netlink related functions + +From: Duoming Zhou + +commit da5c0f119203ad9728920456a0f52a6d850c01cd upstream. + +The device_is_registered() in nfc core is used to check whether +nfc device is registered in netlink related functions such as +nfc_fw_download(), nfc_dev_up() and so on. Although device_is_registered() +is protected by device_lock, there is still a race condition between +device_del() and device_is_registered(). The root cause is that +kobject_del() in device_del() is not protected by device_lock. + + (cleanup task) | (netlink task) + | +nfc_unregister_device | nfc_fw_download + device_del | device_lock + ... | if (!device_is_registered)//(1) + kobject_del//(2) | ... + ... | device_unlock + +The device_is_registered() returns the value of state_in_sysfs and +the state_in_sysfs is set to zero in kobject_del(). If we pass check in +position (1), then set zero in position (2). As a result, the check +in position (1) is useless. + +This patch uses bool variable instead of device_is_registered() to judge +whether the nfc device is registered, which is well synchronized. + +Fixes: 3e256b8f8dfa ("NFC: add nfc subsystem core") +Signed-off-by: Duoming Zhou +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/nfc/core.c | 29 ++++++++++++++--------------- + 1 file changed, 14 insertions(+), 15 deletions(-) + +--- a/net/nfc/core.c ++++ b/net/nfc/core.c +@@ -50,7 +50,7 @@ int nfc_fw_download(struct nfc_dev *dev, + + device_lock(&dev->dev); + +- if (!device_is_registered(&dev->dev)) { ++ if (dev->shutting_down) { + rc = -ENODEV; + goto error; + } +@@ -106,7 +106,7 @@ int nfc_dev_up(struct nfc_dev *dev) + + device_lock(&dev->dev); + +- if (!device_is_registered(&dev->dev)) { ++ if (dev->shutting_down) { + rc = -ENODEV; + goto error; + } +@@ -154,7 +154,7 @@ int nfc_dev_down(struct nfc_dev *dev) + + device_lock(&dev->dev); + +- if (!device_is_registered(&dev->dev)) { ++ if (dev->shutting_down) { + rc = -ENODEV; + goto error; + } +@@ -218,7 +218,7 @@ int nfc_start_poll(struct nfc_dev *dev, + + device_lock(&dev->dev); + +- if (!device_is_registered(&dev->dev)) { ++ if (dev->shutting_down) { + rc = -ENODEV; + goto error; + } +@@ -257,7 +257,7 @@ int nfc_stop_poll(struct nfc_dev *dev) + + device_lock(&dev->dev); + +- if (!device_is_registered(&dev->dev)) { ++ if (dev->shutting_down) { + rc = -ENODEV; + goto error; + } +@@ -302,7 +302,7 @@ int nfc_dep_link_up(struct nfc_dev *dev, + + device_lock(&dev->dev); + +- if (!device_is_registered(&dev->dev)) { ++ if (dev->shutting_down) { + rc = -ENODEV; + goto error; + } +@@ -346,7 +346,7 @@ int nfc_dep_link_down(struct nfc_dev *de + + device_lock(&dev->dev); + +- if (!device_is_registered(&dev->dev)) { ++ if (dev->shutting_down) { + rc = -ENODEV; + goto error; + } +@@ -412,7 +412,7 @@ int nfc_activate_target(struct nfc_dev * + + device_lock(&dev->dev); + +- if (!device_is_registered(&dev->dev)) { ++ if (dev->shutting_down) { + rc = -ENODEV; + goto error; + } +@@ -458,7 +458,7 @@ int nfc_deactivate_target(struct nfc_dev + + device_lock(&dev->dev); + +- if (!device_is_registered(&dev->dev)) { ++ if (dev->shutting_down) { + rc = -ENODEV; + goto error; + } +@@ -505,7 +505,7 @@ int nfc_data_exchange(struct nfc_dev *de + + device_lock(&dev->dev); + +- if (!device_is_registered(&dev->dev)) { ++ if (dev->shutting_down) { + rc = -ENODEV; + kfree_skb(skb); + goto error; +@@ -562,7 +562,7 @@ int nfc_enable_se(struct nfc_dev *dev, u + + device_lock(&dev->dev); + +- if (!device_is_registered(&dev->dev)) { ++ if (dev->shutting_down) { + rc = -ENODEV; + goto error; + } +@@ -611,7 +611,7 @@ int nfc_disable_se(struct nfc_dev *dev, + + device_lock(&dev->dev); + +- if (!device_is_registered(&dev->dev)) { ++ if (dev->shutting_down) { + rc = -ENODEV; + goto error; + } +@@ -1142,6 +1142,7 @@ int nfc_register_device(struct nfc_dev * + dev->rfkill = NULL; + } + } ++ dev->shutting_down = false; + device_unlock(&dev->dev); + + rc = nfc_genl_device_added(dev); +@@ -1174,12 +1175,10 @@ void nfc_unregister_device(struct nfc_de + rfkill_unregister(dev->rfkill); + rfkill_destroy(dev->rfkill); + } ++ dev->shutting_down = true; + device_unlock(&dev->dev); + + if (dev->ops->check_presence) { +- device_lock(&dev->dev); +- dev->shutting_down = true; +- device_unlock(&dev->dev); + del_timer_sync(&dev->check_pres_timer); + cancel_work_sync(&dev->check_pres_work); + } diff --git a/queue-4.14/series b/queue-4.14/series index f39206e4984..d813b710e2e 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -61,3 +61,8 @@ firewire-core-extend-card-lock-in-fw_core_handle_bus_reset.patch asoc-wm8958-fix-change-notifications-for-dsp-controls.patch can-grcan-grcan_close-fix-deadlock.patch can-grcan-use-ofdev-dev-when-allocating-dma-memory.patch +nfc-replace-improper-check-device_is_registered-in-netlink-related-functions.patch +nfc-nfcmrvl-main-reorder-destructive-operations-in-nfcmrvl_nci_unregister_dev-to-avoid-bugs.patch +nfc-netlink-fix-sleep-in-atomic-bug-when-firmware-download-timeout.patch +hwmon-adt7470-fix-warning-on-module-removal.patch +asoc-dmaengine-restore-null-prepare_slave_config-callback.patch