]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 May 2022 10:37:21 +0000 (12:37 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 May 2022 10:37:21 +0000 (12:37 +0200)
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

queue-4.14/asoc-dmaengine-restore-null-prepare_slave_config-callback.patch [new file with mode: 0644]
queue-4.14/hwmon-adt7470-fix-warning-on-module-removal.patch [new file with mode: 0644]
queue-4.14/nfc-netlink-fix-sleep-in-atomic-bug-when-firmware-download-timeout.patch [new file with mode: 0644]
queue-4.14/nfc-nfcmrvl-main-reorder-destructive-operations-in-nfcmrvl_nci_unregister_dev-to-avoid-bugs.patch [new file with mode: 0644]
queue-4.14/nfc-replace-improper-check-device_is_registered-in-netlink-related-functions.patch [new file with mode: 0644]
queue-4.14/series

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 (file)
index 0000000..7a682b5
--- /dev/null
@@ -0,0 +1,49 @@
+From 660564fc9a92a893a14f255be434f7ea0b967901 Mon Sep 17 00:00:00 2001
+From: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
+Date: Thu, 21 Apr 2022 15:54:02 +0300
+Subject: ASoC: dmaengine: Restore NULL prepare_slave_config() callback
+
+From: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
+
+commit 660564fc9a92a893a14f255be434f7ea0b967901 upstream.
+
+As pointed out by Sascha Hauer, this patch changes:
+if (pmc->config && !pcm->config->prepare_slave_config)
+        <do nothing>
+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 <sha@pengutronix.de>
+Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
+Link: https://lore.kernel.org/r/20220421125403.2180824-1-codrin.ciubotariu@microchip.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..f6cb043
--- /dev/null
@@ -0,0 +1,57 @@
+From 7b2666ce445c700b8dcee994da44ddcf050a0842 Mon Sep 17 00:00:00 2001
+From: Armin Wolf <W_Armin@gmx.de>
+Date: Thu, 7 Apr 2022 12:13:12 +0200
+Subject: hwmon: (adt7470) Fix warning on module removal
+
+From: Armin Wolf <W_Armin@gmx.de>
+
+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 [<ffffffffa006052b>] 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 <zheyuma97@gmail.com>
+Fixes: 93cacfd41f82 (hwmon: (adt7470) Allow faster removal)
+Signed-off-by: Armin Wolf <W_Armin@gmx.de>
+Tested-by: Zheyu Ma <zheyuma97@gmail.com>
+Link: https://lore.kernel.org/r/20220407101312.13331-1-W_Armin@gmx.de
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 <linux/kthread.h>
+ #include <linux/slab.h>
+ #include <linux/util_macros.h>
++#include <linux/sched.h>
+ /* 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 (file)
index 0000000..ad79f33
--- /dev/null
@@ -0,0 +1,65 @@
+From 4071bf121d59944d5cd2238de0642f3d7995a997 Mon Sep 17 00:00:00 2001
+From: Duoming Zhou <duoming@zju.edu.cn>
+Date: Wed, 4 May 2022 13:58:47 +0800
+Subject: NFC: netlink: fix sleep in atomic bug when firmware download timeout
+
+From: Duoming Zhou <duoming@zju.edu.cn>
+
+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 <duoming@zju.edu.cn>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20220504055847.38026-1-duoming@zju.edu.cn
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..6933587
--- /dev/null
@@ -0,0 +1,113 @@
+From d270453a0d9ec10bb8a802a142fb1b3601a83098 Mon Sep 17 00:00:00 2001
+From: Duoming Zhou <duoming@zju.edu.cn>
+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 <duoming@zju.edu.cn>
+
+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 <duoming@zju.edu.cn>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..5fba094
--- /dev/null
@@ -0,0 +1,172 @@
+From da5c0f119203ad9728920456a0f52a6d850c01cd Mon Sep 17 00:00:00 2001
+From: Duoming Zhou <duoming@zju.edu.cn>
+Date: Fri, 29 Apr 2022 20:45:50 +0800
+Subject: nfc: replace improper check device_is_registered() in netlink related functions
+
+From: Duoming Zhou <duoming@zju.edu.cn>
+
+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 <duoming@zju.edu.cn>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
+       }
index f39206e49840441a21b0161e8901475a5d906e5a..d813b710e2e01f9614ed83393d26fdf389b12f59 100644 (file)
@@ -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