]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 16 Jun 2026 07:30:53 +0000 (13:00 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 16 Jun 2026 07:30:53 +0000 (13:00 +0530)
added patches:
bluetooth-l2cap-use-chan-timer-to-close-channels-in-cleanup_listen.patch
iio-adc-npcm-fix-unbalanced-clk_disable_unprepare.patch
iio-chemical-scd30-fix-division-by-zero-in-write_raw.patch
iio-chemical-scd30-use-guard-mutex-to-allow-early-returns.patch
iio-dac-ad5686-acquire-lock-when-doing-powerdown-control.patch
iio-dac-ad5686-fix-ref-bit-initialization-for-single-channel-parts.patch
iio-gyro-adis16260-fix-division-by-zero-in-write_raw.patch
net-skbuff-fix-missing-zerocopy-reference-in-pskb_carve-helpers.patch
serial-samsung_tty-use-port-lock-wrappers.patch
tty-serial-samsung-remove-redundant-port-lock-acquisition-in-rx-helpers.patch
tty-serial-samsung-use-u32-for-register-interactions.patch
usb-cdns3-gadget-fix-request-skipping-after-clearing-halt.patch
usb-gadget-f_hid-fix-device-reference-leak-in-hidg_alloc.patch
usb-gadget-f_hid-tidy-error-handling-in-hidg_alloc.patch
xfrm-input-hold-netns-during-deferred-transport-reinjection.patch

16 files changed:
queue-5.10/bluetooth-l2cap-use-chan-timer-to-close-channels-in-cleanup_listen.patch [new file with mode: 0644]
queue-5.10/iio-adc-npcm-fix-unbalanced-clk_disable_unprepare.patch [new file with mode: 0644]
queue-5.10/iio-chemical-scd30-fix-division-by-zero-in-write_raw.patch [new file with mode: 0644]
queue-5.10/iio-chemical-scd30-use-guard-mutex-to-allow-early-returns.patch [new file with mode: 0644]
queue-5.10/iio-dac-ad5686-acquire-lock-when-doing-powerdown-control.patch [new file with mode: 0644]
queue-5.10/iio-dac-ad5686-fix-ref-bit-initialization-for-single-channel-parts.patch [new file with mode: 0644]
queue-5.10/iio-gyro-adis16260-fix-division-by-zero-in-write_raw.patch [new file with mode: 0644]
queue-5.10/net-skbuff-fix-missing-zerocopy-reference-in-pskb_carve-helpers.patch [new file with mode: 0644]
queue-5.10/serial-samsung_tty-use-port-lock-wrappers.patch [new file with mode: 0644]
queue-5.10/series
queue-5.10/tty-serial-samsung-remove-redundant-port-lock-acquisition-in-rx-helpers.patch [new file with mode: 0644]
queue-5.10/tty-serial-samsung-use-u32-for-register-interactions.patch [new file with mode: 0644]
queue-5.10/usb-cdns3-gadget-fix-request-skipping-after-clearing-halt.patch [new file with mode: 0644]
queue-5.10/usb-gadget-f_hid-fix-device-reference-leak-in-hidg_alloc.patch [new file with mode: 0644]
queue-5.10/usb-gadget-f_hid-tidy-error-handling-in-hidg_alloc.patch [new file with mode: 0644]
queue-5.10/xfrm-input-hold-netns-during-deferred-transport-reinjection.patch [new file with mode: 0644]

diff --git a/queue-5.10/bluetooth-l2cap-use-chan-timer-to-close-channels-in-cleanup_listen.patch b/queue-5.10/bluetooth-l2cap-use-chan-timer-to-close-channels-in-cleanup_listen.patch
new file mode 100644 (file)
index 0000000..ae49b5d
--- /dev/null
@@ -0,0 +1,73 @@
+From stable+bounces-260499-greg=kroah.com@vger.kernel.org Thu Jun  4 19:34:49 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu,  4 Jun 2026 09:45:38 -0400
+Subject: Bluetooth: L2CAP: use chan timer to close channels in cleanup_listen()
+To: stable@vger.kernel.org
+Cc: Siwei Zhang <oss@fourdim.xyz>, Luiz Augusto von Dentz <luiz.von.dentz@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260604134538.3463737-2-sashal@kernel.org>
+
+From: Siwei Zhang <oss@fourdim.xyz>
+
+[ Upstream commit 8c8e620467a7b51562dbcefbd1f09f288d7d710d ]
+
+l2cap_chan_close() removes the channel from conn->chan_l, which
+must be done under conn->lock.  cleanup_listen() runs under the
+parent sk_lock, so acquiring conn->lock would invert the
+established conn->lock -> chan->lock -> sk_lock order.
+
+Instead of calling l2cap_chan_close() directly, schedule
+l2cap_chan_timeout with delay 0 to close the channel
+asynchronously.  The timeout handler already acquires conn->lock
+and chan->lock in the correct order.
+
+The timer is only armed when chan->conn is still set: if it is
+already NULL, l2cap_conn_del() has already processed this channel
+(l2cap_chan_del + l2cap_sock_teardown_cb + l2cap_sock_close_cb),
+so there is nothing left to do.  If l2cap_conn_del() races in
+after the timer is armed, __clear_chan_timer() inside
+l2cap_chan_del() cancels it; if the timer has already fired, the
+handler returns harmlessly because chan->conn was cleared.
+
+Fixes: 3df91ea20e74 ("Bluetooth: Revert to mutexes from RCU list")
+Cc: <stable@vger.kernel.org> # 0b58004: Bluetooth: fix UAF in l2cap_sock_cleanup_listen() vs l2cap_conn_del()
+Signed-off-by: Siwei Zhang <oss@fourdim.xyz>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bluetooth/l2cap_sock.c |   16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+--- a/net/bluetooth/l2cap_sock.c
++++ b/net/bluetooth/l2cap_sock.c
+@@ -1437,6 +1437,10 @@ static void l2cap_sock_cleanup_listen(st
+        * pin it (hold_unless_zero() additionally skips a chan already past
+        * its last reference).  We then drop the sk lock before taking
+        * chan->lock, so sk and chan locks are never held together.
++       *
++       * Since we cannot call l2cap_chan_close() without conn->lock,
++       * schedule l2cap_chan_timeout to close the channel; it already
++       * acquires conn->lock -> chan->lock in the correct order.
+        */
+       while ((sk = bt_accept_dequeue(parent, NULL))) {
+               struct l2cap_chan *chan;
+@@ -1454,14 +1458,12 @@ static void l2cap_sock_cleanup_listen(st
+                      state_to_string(chan->state));
+               l2cap_chan_lock(chan);
+-              __clear_chan_timer(chan);
+-              l2cap_chan_close(chan, ECONNRESET);
+-              /* l2cap_conn_del() may already have killed this socket
+-               * (it sets SOCK_DEAD); skip the duplicate to avoid a
+-               * double sock_put()/l2cap_chan_put().
++              /* Since we cannot call l2cap_chan_close() without
++               * conn->lock, schedule its timer to trigger the close
++               * and cleanup of this channel.
+                */
+-              if (!sock_flag(sk, SOCK_DEAD))
+-                      l2cap_sock_kill(sk);
++              if (chan->conn)
++                      __set_chan_timer(chan, 0);
+               l2cap_chan_unlock(chan);
+               l2cap_chan_put(chan);
diff --git a/queue-5.10/iio-adc-npcm-fix-unbalanced-clk_disable_unprepare.patch b/queue-5.10/iio-adc-npcm-fix-unbalanced-clk_disable_unprepare.patch
new file mode 100644 (file)
index 0000000..980aa36
--- /dev/null
@@ -0,0 +1,120 @@
+From stable+bounces-260546-greg=kroah.com@vger.kernel.org Thu Jun  4 22:52:12 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu,  4 Jun 2026 13:11:57 -0400
+Subject: iio: adc: npcm: fix unbalanced clk_disable_unprepare()
+To: stable@vger.kernel.org
+Cc: David Carlier <devnexen@gmail.com>, Andy Shevchenko <andriy.shevchenko@intel.com>, Stable@vger.kernel.org, Jonathan Cameron <jic23@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260604171157.4039872-1-sashal@kernel.org>
+
+From: David Carlier <devnexen@gmail.com>
+
+[ Upstream commit 0d42e2c0bd6ceb89e44c6e065f9bdf9b1df3ef0c ]
+
+The driver acquired the ADC clock with devm_clk_get() and read its
+rate, but never called clk_prepare_enable(). The probe error path and
+npcm_adc_remove() both called clk_disable_unprepare() unconditionally,
+causing the clk framework's enable/prepare counts to underflow on
+probe failure or module unbind.
+
+The issue went unnoticed because NPCM BMC firmware leaves the ADC
+clock enabled at boot, so the driver happened to work in practice.
+
+Switch to devm_clk_get_enabled() so the clock is properly enabled
+during probe and automatically released by the device-managed
+cleanup, and drop the now-redundant clk_disable_unprepare() from
+both the probe error path and remove().
+
+While at it, drop the duplicate error message on devm_request_irq()
+failure since the IRQ core already logs it.
+
+Fixes: 9bf85fbc9d8f ("iio: adc: add NPCM ADC driver")
+Signed-off-by: David Carlier <devnexen@gmail.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/adc/npcm_adc.c |   26 ++++++++------------------
+ 1 file changed, 8 insertions(+), 18 deletions(-)
+
+--- a/drivers/iio/adc/npcm_adc.c
++++ b/drivers/iio/adc/npcm_adc.c
+@@ -180,7 +180,6 @@ static int npcm_adc_probe(struct platfor
+       u32 reg_con;
+       struct npcm_adc *info;
+       struct iio_dev *indio_dev;
+-      struct device *dev = &pdev->dev;
+       indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
+       if (!indio_dev)
+@@ -197,7 +196,7 @@ static int npcm_adc_probe(struct platfor
+       if (IS_ERR(info->reset))
+               return PTR_ERR(info->reset);
+-      info->adc_clk = devm_clk_get(&pdev->dev, NULL);
++      info->adc_clk = devm_clk_get_enabled(&pdev->dev, NULL);
+       if (IS_ERR(info->adc_clk)) {
+               dev_warn(&pdev->dev, "ADC clock failed: can't read clk\n");
+               return PTR_ERR(info->adc_clk);
+@@ -210,17 +209,13 @@ static int npcm_adc_probe(struct platfor
+       info->adc_sample_hz = clk_get_rate(info->adc_clk) / ((div + 1) * 2);
+       irq = platform_get_irq(pdev, 0);
+-      if (irq <= 0) {
+-              ret = -EINVAL;
+-              goto err_disable_clk;
+-      }
++      if (irq <= 0)
++              return -EINVAL;
+       ret = devm_request_irq(&pdev->dev, irq, npcm_adc_isr, 0,
+                              "NPCM_ADC", indio_dev);
+-      if (ret < 0) {
+-              dev_err(dev, "failed requesting interrupt\n");
+-              goto err_disable_clk;
+-      }
++      if (ret < 0)
++              return ret;
+       reg_con = ioread32(info->regs + NPCM_ADCCON);
+       info->vref = devm_regulator_get_optional(&pdev->dev, "vref");
+@@ -228,7 +223,7 @@ static int npcm_adc_probe(struct platfor
+               ret = regulator_enable(info->vref);
+               if (ret) {
+                       dev_err(&pdev->dev, "Can't enable ADC reference voltage\n");
+-                      goto err_disable_clk;
++                      return ret;
+               }
+               iowrite32(reg_con & ~NPCM_ADCCON_REFSEL,
+@@ -238,10 +233,8 @@ static int npcm_adc_probe(struct platfor
+                * Any error which is not ENODEV indicates the regulator
+                * has been specified and so is a failure case.
+                */
+-              if (PTR_ERR(info->vref) != -ENODEV) {
+-                      ret = PTR_ERR(info->vref);
+-                      goto err_disable_clk;
+-              }
++              if (PTR_ERR(info->vref) != -ENODEV)
++                      return PTR_ERR(info->vref);
+               /* Use internal reference */
+               iowrite32(reg_con | NPCM_ADCCON_REFSEL,
+@@ -280,8 +273,6 @@ err_iio_register:
+       iowrite32(reg_con & ~NPCM_ADCCON_ADC_EN, info->regs + NPCM_ADCCON);
+       if (!IS_ERR(info->vref))
+               regulator_disable(info->vref);
+-err_disable_clk:
+-      clk_disable_unprepare(info->adc_clk);
+       return ret;
+ }
+@@ -298,7 +289,6 @@ static int npcm_adc_remove(struct platfo
+       iowrite32(regtemp & ~NPCM_ADCCON_ADC_EN, info->regs + NPCM_ADCCON);
+       if (!IS_ERR(info->vref))
+               regulator_disable(info->vref);
+-      clk_disable_unprepare(info->adc_clk);
+       return 0;
+ }
diff --git a/queue-5.10/iio-chemical-scd30-fix-division-by-zero-in-write_raw.patch b/queue-5.10/iio-chemical-scd30-fix-division-by-zero-in-write_raw.patch
new file mode 100644 (file)
index 0000000..3025e88
--- /dev/null
@@ -0,0 +1,38 @@
+From stable+bounces-260587-greg=kroah.com@vger.kernel.org Fri Jun  5 05:19:07 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu,  4 Jun 2026 19:49:00 -0400
+Subject: iio: chemical: scd30: fix division by zero in write_raw
+To: stable@vger.kernel.org
+Cc: Antoniu Miclaus <antoniu.miclaus@analog.com>, Stable@vger.kernel.org, Jonathan Cameron <jic23@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260604234900.2467781-2-sashal@kernel.org>
+
+From: Antoniu Miclaus <antoniu.miclaus@analog.com>
+
+[ Upstream commit 5aba4f94b225617a55fed442a70329b2ee19c0a5 ]
+
+Add a zero check for val2 before using it as a divisor when setting the
+sampling frequency. A user writing a zero fractional part to the
+sampling_frequency sysfs attribute triggers a division by zero in the
+kernel.
+
+Fixes: 64b3d8b1b0f5 ("iio: chemical: scd30: add core driver")
+Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/chemical/scd30_core.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/chemical/scd30_core.c
++++ b/drivers/iio/chemical/scd30_core.c
+@@ -257,7 +257,7 @@ static int scd30_write_raw(struct iio_de
+       guard(mutex)(&state->lock);
+       switch (mask) {
+       case IIO_CHAN_INFO_SAMP_FREQ:
+-              if (val)
++              if (val || !val2)
+                       return -EINVAL;
+               val = 1000000000 / val2;
diff --git a/queue-5.10/iio-chemical-scd30-use-guard-mutex-to-allow-early-returns.patch b/queue-5.10/iio-chemical-scd30-use-guard-mutex-to-allow-early-returns.patch
new file mode 100644 (file)
index 0000000..399b420
--- /dev/null
@@ -0,0 +1,178 @@
+From stable+bounces-260586-greg=kroah.com@vger.kernel.org Fri Jun  5 05:20:48 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu,  4 Jun 2026 19:48:59 -0400
+Subject: iio: chemical: scd30: Use guard(mutex) to allow early returns
+To: stable@vger.kernel.org
+Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>, David Lechner <dlechner@baylibre.com>, Tomasz Duszynski <tomasz.duszynski@octakon.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260604234900.2467781-1-sashal@kernel.org>
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 5feb5532870fbced5d6f450b8061a33f461b88ca ]
+
+Auto cleanup based release of the lock allows for simpler code flow in a
+few functions with large multiplexing style switch statements and no
+common operations following the switch.
+
+Suggested-by: David Lechner <dlechner@baylibre.com>
+Cc: Tomasz Duszynski <tomasz.duszynski@octakon.com>
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Link: https://patch.msgid.link/20250209180624.701140-3-jic23@kernel.org
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: 5aba4f94b225 ("iio: chemical: scd30: fix division by zero in write_raw")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/chemical/scd30_core.c |   63 ++++++++++++++++----------------------
+ 1 file changed, 28 insertions(+), 35 deletions(-)
+
+--- a/drivers/iio/chemical/scd30_core.c
++++ b/drivers/iio/chemical/scd30_core.c
+@@ -5,6 +5,7 @@
+  * Copyright (c) 2020 Tomasz Duszynski <tomasz.duszynski@octakon.com>
+  */
+ #include <linux/bits.h>
++#include <linux/cleanup.h>
+ #include <linux/completion.h>
+ #include <linux/delay.h>
+ #include <linux/device.h>
+@@ -198,112 +199,104 @@ static int scd30_read_raw(struct iio_dev
+                         int *val, int *val2, long mask)
+ {
+       struct scd30_state *state = iio_priv(indio_dev);
+-      int ret = -EINVAL;
++      int ret;
+       u16 tmp;
+-      mutex_lock(&state->lock);
++      guard(mutex)(&state->lock);
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+       case IIO_CHAN_INFO_PROCESSED:
+               if (chan->output) {
+                       *val = state->pressure_comp;
+-                      ret = IIO_VAL_INT;
+-                      break;
++                      return IIO_VAL_INT;
+               }
+               ret = iio_device_claim_direct_mode(indio_dev);
+               if (ret)
+-                      break;
++                      return ret;
+               ret = scd30_read(state);
+               if (ret) {
+                       iio_device_release_direct_mode(indio_dev);
+-                      break;
++                      return ret;
+               }
+               *val = state->meas[chan->address];
+               iio_device_release_direct_mode(indio_dev);
+-              ret = IIO_VAL_INT;
+-              break;
++              return IIO_VAL_INT;
+       case IIO_CHAN_INFO_SCALE:
+               *val = 0;
+               *val2 = 1;
+-              ret = IIO_VAL_INT_PLUS_MICRO;
+-              break;
++              return IIO_VAL_INT_PLUS_MICRO;
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               ret = scd30_command_read(state, CMD_MEAS_INTERVAL, &tmp);
+               if (ret)
+-                      break;
++                      return ret;
+               *val = 0;
+               *val2 = 1000000000 / tmp;
+-              ret = IIO_VAL_INT_PLUS_NANO;
+-              break;
++              return IIO_VAL_INT_PLUS_NANO;
+       case IIO_CHAN_INFO_CALIBBIAS:
+               ret = scd30_command_read(state, CMD_TEMP_OFFSET, &tmp);
+               if (ret)
+-                      break;
++                      return ret;
+               *val = tmp;
+-              ret = IIO_VAL_INT;
+-              break;
++              return IIO_VAL_INT;
++      default:
++              return -EINVAL;
+       }
+-      mutex_unlock(&state->lock);
+-
+-      return ret;
+ }
+ static int scd30_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan,
+                          int val, int val2, long mask)
+ {
+       struct scd30_state *state = iio_priv(indio_dev);
+-      int ret = -EINVAL;
++      int ret;
+-      mutex_lock(&state->lock);
++      guard(mutex)(&state->lock);
+       switch (mask) {
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               if (val)
+-                      break;
++                      return -EINVAL;
+               val = 1000000000 / val2;
+               if (val < SCD30_MEAS_INTERVAL_MIN_S || val > SCD30_MEAS_INTERVAL_MAX_S)
+-                      break;
++                      return -EINVAL;
+               ret = scd30_command_write(state, CMD_MEAS_INTERVAL, val);
+               if (ret)
+-                      break;
++                      return ret;
+               state->meas_interval = val;
+-              break;
++              return 0;
+       case IIO_CHAN_INFO_RAW:
+               switch (chan->type) {
+               case IIO_PRESSURE:
+                       if (val < SCD30_PRESSURE_COMP_MIN_MBAR ||
+                           val > SCD30_PRESSURE_COMP_MAX_MBAR)
+-                              break;
++                              return -EINVAL;
+                       ret = scd30_command_write(state, CMD_START_MEAS, val);
+                       if (ret)
+-                              break;
++                              return ret;
+                       state->pressure_comp = val;
+-                      break;
++                      return 0;
+               default:
+-                      break;
++                      return -EINVAL;
+               }
+-              break;
+       case IIO_CHAN_INFO_CALIBBIAS:
+               if (val < 0 || val > SCD30_TEMP_OFFSET_MAX)
+-                      break;
++                      return -EINVAL;
+               /*
+                * Manufacturer does not explicitly specify min/max sensible
+                * values hence check is omitted for simplicity.
+                */
+-              ret = scd30_command_write(state, CMD_TEMP_OFFSET / 10, val);
++              return scd30_command_write(state, CMD_TEMP_OFFSET / 10, val);
++      default:
++              return -EINVAL;
+       }
+-      mutex_unlock(&state->lock);
+-
+-      return ret;
+ }
+ static int scd30_write_raw_get_fmt(struct iio_dev *indio_dev, struct iio_chan_spec const *chan,
diff --git a/queue-5.10/iio-dac-ad5686-acquire-lock-when-doing-powerdown-control.patch b/queue-5.10/iio-dac-ad5686-acquire-lock-when-doing-powerdown-control.patch
new file mode 100644 (file)
index 0000000..6efeeb9
--- /dev/null
@@ -0,0 +1,69 @@
+From stable+bounces-260533-greg=kroah.com@vger.kernel.org Thu Jun  4 21:26:20 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu,  4 Jun 2026 11:49:19 -0400
+Subject: iio: dac: ad5686: acquire lock when doing powerdown control
+To: stable@vger.kernel.org
+Cc: Rodrigo Alencar <rodrigo.alencar@analog.com>, Stable@vger.kernel.org, Jonathan Cameron <jic23@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260604154919.3732423-1-sashal@kernel.org>
+
+From: Rodrigo Alencar <rodrigo.alencar@analog.com>
+
+[ Upstream commit 5237c3175cae5ab05f18878cec3301a04403859e ]
+
+Protect access of pwr_down_mode and pwr_down_mask fields with existing
+mutex lock. Each channel exposes their own attributes for controlling
+powerdown modes and powerdown state. This fixes potential race conditions
+as those the write functions perform non-atomic read-modify-write
+operations to those pwr_down_* fields. This issue exists since the ad5686
+driver was first introduced.
+
+Fixes: c2f37c8dcadc ("iio: dac: New driver for AD5686R, AD5685R, AD5684R Digital to analog converters")
+Signed-off-by: Rodrigo Alencar <rodrigo.alencar@analog.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/dac/ad5686.c |   10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/drivers/iio/dac/ad5686.c
++++ b/drivers/iio/dac/ad5686.c
+@@ -30,6 +30,8 @@ static int ad5686_get_powerdown_mode(str
+ {
+       struct ad5686_state *st = iio_priv(indio_dev);
++      guard(mutex)(&st->lock);
++
+       return ((st->pwr_down_mode >> (chan->channel * 2)) & 0x3) - 1;
+ }
+@@ -39,6 +41,8 @@ static int ad5686_set_powerdown_mode(str
+ {
+       struct ad5686_state *st = iio_priv(indio_dev);
++      guard(mutex)(&st->lock);
++
+       st->pwr_down_mode &= ~(0x3 << (chan->channel * 2));
+       st->pwr_down_mode |= ((mode + 1) << (chan->channel * 2));
+@@ -57,7 +61,9 @@ static ssize_t ad5686_read_dac_powerdown
+ {
+       struct ad5686_state *st = iio_priv(indio_dev);
+-      return sprintf(buf, "%d\n", !!(st->pwr_down_mask &
++      guard(mutex)(&st->lock);
++
++      return sysfs_emit(buf, "%d\n", !!(st->pwr_down_mask &
+                                      (0x3 << (chan->channel * 2))));
+ }
+@@ -77,6 +83,8 @@ static ssize_t ad5686_write_dac_powerdow
+       if (ret)
+               return ret;
++      guard(mutex)(&st->lock);
++
+       if (readin)
+               st->pwr_down_mask |= (0x3 << (chan->channel * 2));
+       else
diff --git a/queue-5.10/iio-dac-ad5686-fix-ref-bit-initialization-for-single-channel-parts.patch b/queue-5.10/iio-dac-ad5686-fix-ref-bit-initialization-for-single-channel-parts.patch
new file mode 100644 (file)
index 0000000..d34c4b9
--- /dev/null
@@ -0,0 +1,65 @@
+From stable+bounces-260609-greg=kroah.com@vger.kernel.org Fri Jun  5 07:22:06 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu,  4 Jun 2026 21:51:51 -0400
+Subject: iio: dac: ad5686: fix ref bit initialization for single-channel parts
+To: stable@vger.kernel.org
+Cc: Rodrigo Alencar <rodrigo.alencar@analog.com>, Andy Shevchenko <andriy.shevchenko@intel.com>, Stable@vger.kernel.org, Jonathan Cameron <jic23@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605015151.3131582-1-sashal@kernel.org>
+
+From: Rodrigo Alencar <rodrigo.alencar@analog.com>
+
+[ Upstream commit ecae2ae606d493cf11457946436335bd0e726663 ]
+
+The reference bit position was ignored when writing the register at the
+probe() function (!!val was used). When such bit is 1, internal voltage
+reference is disabled so that an external one can be used. For
+multi-channel devices, bit 0 of the Internal Reference Setup command
+behaves the same way, so AD5686_REF_BIT_MSK is created. The issue exists
+since support for single-channel devices were first introduced.
+
+Fixes: be1b24d24541 ("iio:dac:ad5686: Add AD5691R/AD5692R/AD5693/AD5693R support")
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
+Signed-off-by: Rodrigo Alencar <rodrigo.alencar@analog.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+[ adapted `has_external_vref` to the in-tree equivalent `voltage_uv` variable in the `val =` computation ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/dac/ad5686.c |    6 +++---
+ drivers/iio/dac/ad5686.h |    1 +
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/iio/dac/ad5686.c
++++ b/drivers/iio/dac/ad5686.c
+@@ -496,7 +496,7 @@ int ad5686_probe(struct device *dev,
+               break;
+       case AD5686_REGMAP:
+               cmd = AD5686_CMD_INTERNAL_REFER_SETUP;
+-              ref_bit_msk = 0;
++              ref_bit_msk = AD5686_REF_BIT_MSK;
+               break;
+       case AD5693_REGMAP:
+               cmd = AD5686_CMD_CONTROL_REG;
+@@ -508,9 +508,9 @@ int ad5686_probe(struct device *dev,
+               goto error_disable_reg;
+       }
+-      val = (voltage_uv | ref_bit_msk);
++      val = voltage_uv ? ref_bit_msk : 0;
+-      ret = st->write(st, cmd, 0, !!val);
++      ret = st->write(st, cmd, 0, val);
+       if (ret)
+               goto error_disable_reg;
+--- a/drivers/iio/dac/ad5686.h
++++ b/drivers/iio/dac/ad5686.h
+@@ -44,6 +44,7 @@
+ #define AD5310_REF_BIT_MSK                    BIT(8)
+ #define AD5683_REF_BIT_MSK                    BIT(12)
++#define AD5686_REF_BIT_MSK                    BIT(0)
+ #define AD5693_REF_BIT_MSK                    BIT(12)
+ /**
diff --git a/queue-5.10/iio-gyro-adis16260-fix-division-by-zero-in-write_raw.patch b/queue-5.10/iio-gyro-adis16260-fix-division-by-zero-in-write_raw.patch
new file mode 100644 (file)
index 0000000..8a72d99
--- /dev/null
@@ -0,0 +1,39 @@
+From stable+bounces-260590-greg=kroah.com@vger.kernel.org Fri Jun  5 05:19:45 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu,  4 Jun 2026 19:49:37 -0400
+Subject: iio: gyro: adis16260: fix division by zero in write_raw
+To: stable@vger.kernel.org
+Cc: "Antoniu Miclaus" <antoniu.miclaus@analog.com>, "Nuno Sá" <nuno.sa@analog.com>, Stable@vger.kernel.org, "Jonathan Cameron" <Jonathan.Cameron@huawei.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260604234937.2471947-1-sashal@kernel.org>
+
+From: Antoniu Miclaus <antoniu.miclaus@analog.com>
+
+[ Upstream commit 761e8b489e6cf166c574034b70637f8a7eadd0ee ]
+
+Add a validation check for the sampling frequency value before using it
+as a divisor. A user writing zero to the sampling_frequency sysfs
+attribute triggers a division by zero in the kernel.
+
+Fixes: 089a41985c6c ("staging: iio: adis16260 digital gyro driver")
+Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
+Reviewed-by: Nuno Sá <nuno.sa@analog.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/gyro/adis16260.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/iio/gyro/adis16260.c
++++ b/drivers/iio/gyro/adis16260.c
+@@ -293,6 +293,9 @@ static int adis16260_write_raw(struct ii
+               addr = adis16260_addresses[chan->scan_index][1];
+               return adis_write_reg_16(adis, addr, val);
+       case IIO_CHAN_INFO_SAMP_FREQ:
++              if (val <= 0)
++                      return -EINVAL;
++
+               mutex_lock(&adis->state_lock);
+               if (spi_get_device_id(adis->spi)->driver_data)
+                       t = 256 / val;
diff --git a/queue-5.10/net-skbuff-fix-missing-zerocopy-reference-in-pskb_carve-helpers.patch b/queue-5.10/net-skbuff-fix-missing-zerocopy-reference-in-pskb_carve-helpers.patch
new file mode 100644 (file)
index 0000000..81a3a1b
--- /dev/null
@@ -0,0 +1,92 @@
+From stable+bounces-260764-greg=kroah.com@vger.kernel.org Sat Jun  6 00:10:11 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  5 Jun 2026 14:31:31 -0400
+Subject: net: skbuff: fix missing zerocopy reference in pskb_carve helpers
+To: stable@vger.kernel.org
+Cc: Minh Nguyen <minhnguyen.080505@gmail.com>, Willem de Bruijn <willemb@google.com>, Paolo Abeni <pabeni@redhat.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605183131.2056525-1-sashal@kernel.org>
+
+From: Minh Nguyen <minhnguyen.080505@gmail.com>
+
+[ Upstream commit 98d0912e9f841e5529a5b89a972805f34cb1c69d ]
+
+pskb_carve_inside_header() and pskb_carve_inside_nonlinear() both copy
+the old skb_shared_info header into a new buffer via memcpy(), which
+includes the destructor_arg pointer (uarg) for MSG_ZEROCOPY skbs.
+Neither function calls net_zcopy_get() for the new shinfo, creating an
+unaccounted holder: every skb_shared_info with destructor_arg set will
+call skb_zcopy_clear() once when freed, but the corresponding
+net_zcopy_get() was never called for the new copy. Repeated calls
+drive uarg->refcnt to zero prematurely, freeing ubuf_info_msgzc while
+TX skbs still hold live destructor_arg pointers.
+
+KASAN reports use-after-free on a freed ubuf_info_msgzc:
+
+  BUG: KASAN: slab-use-after-free in skb_release_data+0x77b/0x810
+  Read of size 8 at addr ffff88801574d3e8 by task poc/220
+
+  Call Trace:
+   skb_release_data+0x77b/0x810
+   kfree_skb_list_reason+0x13e/0x610
+   skb_release_data+0x4cd/0x810
+   sk_skb_reason_drop+0xf3/0x340
+   skb_queue_purge_reason+0x282/0x440
+   rds_tcp_inc_free+0x1e/0x30
+   rds_recvmsg+0x354/0x1780
+   __sys_recvmsg+0xdf/0x180
+
+  Allocated by task 219:
+   msg_zerocopy_realloc+0x157/0x7b0
+   tcp_sendmsg_locked+0x2892/0x3ba0
+
+  Freed by task 219:
+   ip_recv_error+0x74a/0xb10
+   tcp_recvmsg+0x475/0x530
+
+The skb consuming the late access still referenced the same uarg via
+shinfo->destructor_arg copied by pskb_carve_inside_nonlinear() without
+a refcount bump. This has been verified to be reliably exploitable: a
+working proof-of-concept achieves full root privilege escalation from
+an unprivileged local user on a default kernel configuration.
+
+The fix follows the pattern of pskb_expand_head() which has the same
+memcpy/cloned structure. For pskb_carve_inside_header(), net_zcopy_get()
+is placed after skb_orphan_frags() succeeds, so the orphan error path
+needs no cleanup. For pskb_carve_inside_nonlinear(), net_zcopy_get() is
+placed after all failure points and just before skb_release_data(), so
+no error path needs cleanup at all -- matching pskb_expand_head() more
+closely and avoiding the need for a balancing net_zcopy_put().
+
+Fixes: 6fa01ccd8830 ("skbuff: Add pskb_extract() helper function")
+Cc: stable@vger.kernel.org
+Assisted-by: Claude:claude-sonnet-4-6
+Signed-off-by: Minh Nguyen <minhnguyen.080505@gmail.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260526041240.329462-1-minhnguyen.080505@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/skbuff.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -6058,6 +6058,8 @@ static int pskb_carve_inside_header(stru
+                       kfree(data);
+                       return -ENOMEM;
+               }
++              if (skb_zcopy(skb))
++                      refcount_inc(&skb_uarg(skb)->refcnt);
+               for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
+                       skb_frag_ref(skb, i);
+               if (skb_has_frag_list(skb))
+@@ -6210,6 +6212,8 @@ static int pskb_carve_inside_nonlinear(s
+               kfree(data);
+               return -ENOMEM;
+       }
++      if (skb_zcopy(skb))
++              refcount_inc(&skb_uarg(skb)->refcnt);
+       skb_release_data(skb);
+       skb->head = data;
diff --git a/queue-5.10/serial-samsung_tty-use-port-lock-wrappers.patch b/queue-5.10/serial-samsung_tty-use-port-lock-wrappers.patch
new file mode 100644 (file)
index 0000000..164d065
--- /dev/null
@@ -0,0 +1,204 @@
+From sashal@kernel.org Sat Jun  6 01:08:26 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  5 Jun 2026 15:38:21 -0400
+Subject: serial: samsung_tty: Use port lock wrappers
+To: stable@vger.kernel.org
+Cc: Thomas Gleixner <tglx@linutronix.de>, John Ogness <john.ogness@linutronix.de>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605193823.2169333-1-sashal@kernel.org>
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit 97d7a9aeba1d424c2359f1686d02c75d798ad184 ]
+
+When a serial port is used for kernel console output, then all
+modifications to the UART registers which are done from other contexts,
+e.g. getty, termios, are interference points for the kernel console.
+
+So far this has been ignored and the printk output is based on the
+principle of hope. The rework of the console infrastructure which aims to
+support threaded and atomic consoles, requires to mark sections which
+modify the UART registers as unsafe. This allows the atomic write function
+to make informed decisions and eventually to restore operational state. It
+also allows to prevent the regular UART code from modifying UART registers
+while printk output is in progress.
+
+All modifications of UART registers are guarded by the UART port lock,
+which provides an obvious synchronization point with the console
+infrastructure.
+
+To avoid adding this functionality to all UART drivers, wrap the
+spin_[un]lock*() invocations for uart_port::lock into helper functions
+which just contain the spin_[un]lock*() invocations for now. In a
+subsequent step these helpers will gain the console synchronization
+mechanisms.
+
+Converted with coccinelle. No functional change.
+
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: John Ogness <john.ogness@linutronix.de>
+Link: https://lore.kernel.org/r/20230914183831.587273-54-john.ogness@linutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: a3bb136bff5e ("tty: serial: samsung: Remove redundant port lock acquisition in rx helpers")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/samsung_tty.c |   36 ++++++++++++++++++------------------
+ 1 file changed, 18 insertions(+), 18 deletions(-)
+
+--- a/drivers/tty/serial/samsung_tty.c
++++ b/drivers/tty/serial/samsung_tty.c
+@@ -245,7 +245,7 @@ static void s3c24xx_serial_rx_enable(str
+       unsigned int ucon, ufcon;
+       int count = 10000;
+-      spin_lock_irqsave(&port->lock, flags);
++      uart_port_lock_irqsave(port, &flags);
+       while (--count && !s3c24xx_serial_txempty_nofifo(port))
+               udelay(100);
+@@ -259,7 +259,7 @@ static void s3c24xx_serial_rx_enable(str
+       wr_regl(port, S3C2410_UCON, ucon);
+       ourport->rx_enabled = 1;
+-      spin_unlock_irqrestore(&port->lock, flags);
++      uart_port_unlock_irqrestore(port, flags);
+ }
+ static void s3c24xx_serial_rx_disable(struct uart_port *port)
+@@ -268,14 +268,14 @@ static void s3c24xx_serial_rx_disable(st
+       unsigned long flags;
+       unsigned int ucon;
+-      spin_lock_irqsave(&port->lock, flags);
++      uart_port_lock_irqsave(port, &flags);
+       ucon = rd_regl(port, S3C2410_UCON);
+       ucon &= ~S3C2410_UCON_RXIRQMODE;
+       wr_regl(port, S3C2410_UCON, ucon);
+       ourport->rx_enabled = 0;
+-      spin_unlock_irqrestore(&port->lock, flags);
++      uart_port_unlock_irqrestore(port, flags);
+ }
+ static void s3c24xx_serial_stop_tx(struct uart_port *port)
+@@ -334,7 +334,7 @@ static void s3c24xx_serial_tx_dma_comple
+       dma_sync_single_for_cpu(ourport->port.dev, dma->tx_transfer_addr,
+                               dma->tx_size, DMA_TO_DEVICE);
+-      spin_lock_irqsave(&port->lock, flags);
++      uart_port_lock_irqsave(port, &flags);
+       xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1);
+       port->icount.tx += count;
+@@ -344,7 +344,7 @@ static void s3c24xx_serial_tx_dma_comple
+               uart_write_wakeup(port);
+       s3c24xx_serial_start_next_tx(ourport);
+-      spin_unlock_irqrestore(&port->lock, flags);
++      uart_port_unlock_irqrestore(port, flags);
+ }
+ static void enable_tx_dma(struct s3c24xx_uart_port *ourport)
+@@ -579,7 +579,7 @@ static void s3c24xx_serial_rx_dma_comple
+       received  = dma->rx_bytes_requested - state.residue;
+       async_tx_ack(dma->rx_desc);
+-      spin_lock_irqsave(&port->lock, flags);
++      uart_port_lock_irqsave(port, &flags);
+       if (received)
+               s3c24xx_uart_copy_rx_to_tty(ourport, t, received);
+@@ -591,7 +591,7 @@ static void s3c24xx_serial_rx_dma_comple
+       s3c64xx_start_rx_dma(ourport);
+-      spin_unlock_irqrestore(&port->lock, flags);
++      uart_port_unlock_irqrestore(port, flags);
+ }
+ static void s3c64xx_start_rx_dma(struct s3c24xx_uart_port *ourport)
+@@ -679,7 +679,7 @@ static irqreturn_t s3c24xx_serial_rx_cha
+       utrstat = rd_regl(port, S3C2410_UTRSTAT);
+       rd_regl(port, S3C2410_UFSTAT);
+-      spin_lock_irqsave(&port->lock, flags);
++      uart_port_lock_irqsave(port, &flags);
+       if (!(utrstat & S3C2410_UTRSTAT_TIMEOUT)) {
+               s3c64xx_start_rx_dma(ourport);
+@@ -708,7 +708,7 @@ static irqreturn_t s3c24xx_serial_rx_cha
+       wr_regl(port, S3C2410_UTRSTAT, S3C2410_UTRSTAT_TIMEOUT);
+ finish:
+-      spin_unlock_irqrestore(&port->lock, flags);
++      uart_port_unlock_irqrestore(port, flags);
+       return IRQ_HANDLED;
+ }
+@@ -806,9 +806,9 @@ static irqreturn_t s3c24xx_serial_rx_cha
+       struct uart_port *port = &ourport->port;
+       unsigned long flags;
+-      spin_lock_irqsave(&port->lock, flags);
++      uart_port_lock_irqsave(port, &flags);
+       s3c24xx_serial_rx_drain_fifo(ourport);
+-      spin_unlock_irqrestore(&port->lock, flags);
++      uart_port_unlock_irqrestore(port, flags);
+       return IRQ_HANDLED;
+ }
+@@ -956,7 +956,7 @@ static void s3c24xx_serial_break_ctl(str
+       unsigned long flags;
+       unsigned int ucon;
+-      spin_lock_irqsave(&port->lock, flags);
++      uart_port_lock_irqsave(port, &flags);
+       ucon = rd_regl(port, S3C2410_UCON);
+@@ -967,7 +967,7 @@ static void s3c24xx_serial_break_ctl(str
+       wr_regl(port, S3C2410_UCON, ucon);
+-      spin_unlock_irqrestore(&port->lock, flags);
++      uart_port_unlock_irqrestore(port, flags);
+ }
+ static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p)
+@@ -1192,7 +1192,7 @@ static int s3c64xx_serial_startup(struct
+       ourport->tx_enabled = 0;
+       ourport->tx_claimed = 1;
+-      spin_lock_irqsave(&port->lock, flags);
++      uart_port_lock_irqsave(port, &flags);
+       ufcon = rd_regl(port, S3C2410_UFCON);
+       ufcon |= S3C2410_UFCON_RESETRX | S5PV210_UFCON_RXTRIG8;
+@@ -1202,7 +1202,7 @@ static int s3c64xx_serial_startup(struct
+       enable_rx_pio(ourport);
+-      spin_unlock_irqrestore(&port->lock, flags);
++      uart_port_unlock_irqrestore(port, flags);
+       /* Enable Rx Interrupt */
+       s3c24xx_clear_bit(port, S3C64XX_UINTM_RXD, S3C64XX_UINTM);
+@@ -1479,7 +1479,7 @@ static void s3c24xx_serial_set_termios(s
+               ulcon |= S3C2410_LCON_PNONE;
+       }
+-      spin_lock_irqsave(&port->lock, flags);
++      uart_port_lock_irqsave(port, &flags);
+       dev_dbg(port->dev,
+               "setting ulcon to %08x, brddiv to %d, udivslot %08x\n",
+@@ -1537,7 +1537,7 @@ static void s3c24xx_serial_set_termios(s
+       if ((termios->c_cflag & CREAD) == 0)
+               port->ignore_status_mask |= RXSTAT_DUMMY_READ;
+-      spin_unlock_irqrestore(&port->lock, flags);
++      uart_port_unlock_irqrestore(port, flags);
+ }
+ static const char *s3c24xx_serial_type(struct uart_port *port)
index 076feaadec0bc82c1005f23f4769aa3724c71b5c..17f9652966a415b70c1162b61354ab854073eae1 100644 (file)
@@ -314,3 +314,18 @@ mm-huge_memory-update-file-pmd-counter-before-folio_put.patch
 rdma-umem-fix-kernel-doc-warnings.patch
 rdma-move-dma-block-iterator-logic-into-dedicated-files.patch
 rdma-umem-fix-truncation-for-block-sizes-4g.patch
+bluetooth-l2cap-use-chan-timer-to-close-channels-in-cleanup_listen.patch
+iio-dac-ad5686-acquire-lock-when-doing-powerdown-control.patch
+iio-adc-npcm-fix-unbalanced-clk_disable_unprepare.patch
+usb-cdns3-gadget-fix-request-skipping-after-clearing-halt.patch
+iio-chemical-scd30-use-guard-mutex-to-allow-early-returns.patch
+iio-chemical-scd30-fix-division-by-zero-in-write_raw.patch
+iio-gyro-adis16260-fix-division-by-zero-in-write_raw.patch
+iio-dac-ad5686-fix-ref-bit-initialization-for-single-channel-parts.patch
+xfrm-input-hold-netns-during-deferred-transport-reinjection.patch
+net-skbuff-fix-missing-zerocopy-reference-in-pskb_carve-helpers.patch
+serial-samsung_tty-use-port-lock-wrappers.patch
+tty-serial-samsung-use-u32-for-register-interactions.patch
+tty-serial-samsung-remove-redundant-port-lock-acquisition-in-rx-helpers.patch
+usb-gadget-f_hid-tidy-error-handling-in-hidg_alloc.patch
+usb-gadget-f_hid-fix-device-reference-leak-in-hidg_alloc.patch
diff --git a/queue-5.10/tty-serial-samsung-remove-redundant-port-lock-acquisition-in-rx-helpers.patch b/queue-5.10/tty-serial-samsung-remove-redundant-port-lock-acquisition-in-rx-helpers.patch
new file mode 100644 (file)
index 0000000..c3ee56d
--- /dev/null
@@ -0,0 +1,85 @@
+From stable+bounces-260807-greg=kroah.com@vger.kernel.org Sat Jun  6 01:08:30 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  5 Jun 2026 15:38:23 -0400
+Subject: tty: serial: samsung: Remove redundant port lock acquisition in rx helpers
+To: stable@vger.kernel.org
+Cc: Tudor Ambarus <tudor.ambarus@linaro.org>, stable <stable@kernel.org>, John Ogness <john.ogness@linutronix.de>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605193823.2169333-3-sashal@kernel.org>
+
+From: Tudor Ambarus <tudor.ambarus@linaro.org>
+
+[ Upstream commit a3bb136bff5e6a5e48cdd813246c9c4686feaaa9 ]
+
+Sashiko identified a deadlock when the console flow is engaged [1].
+
+When console flow control is enabled (UPF_CONS_FLOW),
+s3c24xx_serial_stop_tx() calls s3c24xx_serial_rx_enable() and
+s3c24xx_serial_start_tx() calls s3c24xx_serial_rx_disable().
+
+The serial core framework invokes the .stop_tx() and .start_tx()
+callbacks with the port->lock spinlock already held. Furthermore, all
+internal driver paths that invoke stop_tx (such as the DMA TX
+completion handler s3c24xx_serial_tx_dma_complete() or the PIO TX IRQ
+handler s3c24xx_serial_tx_irq()) also acquire port->lock prior to
+calling it. (Note that s3c24xx_serial_start_tx() is only invoked by the
+serial core).
+
+However, s3c24xx_serial_rx_enable() and s3c24xx_serial_rx_disable()
+unconditionally attempt to acquire port->lock again using
+uart_port_lock_irqsave(). Since spinlocks are not recursive, this
+causes a deadlock on the same CPU when console flow control is engaged.
+
+Remove the redundant lock acquisition from both rx helper functions.
+
+Cc: stable <stable@kernel.org>
+Fixes: b497549a035c ("[ARM] S3C24XX: Split serial driver into core and per-cpu drivers")
+Reported-by: John Ogness <john.ogness@linutronix.de>
+Closes: https://sashiko.dev/#/patchset/20260506121606.5805-1-john.ogness%40linutronix.de [1]
+Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
+Link: https://patch.msgid.link/20260515-samsung-tty-flow-control-deadlock-v1-1-93255edbc9bc@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/samsung_tty.c |    8 --------
+ 1 file changed, 8 deletions(-)
+
+--- a/drivers/tty/serial/samsung_tty.c
++++ b/drivers/tty/serial/samsung_tty.c
+@@ -241,12 +241,9 @@ static int s3c24xx_serial_has_interrupt_
+ static void s3c24xx_serial_rx_enable(struct uart_port *port)
+ {
+       struct s3c24xx_uart_port *ourport = to_ourport(port);
+-      unsigned long flags;
+       int count = 10000;
+       u32 ucon, ufcon;
+-      uart_port_lock_irqsave(port, &flags);
+-
+       while (--count && !s3c24xx_serial_txempty_nofifo(port))
+               udelay(100);
+@@ -259,23 +256,18 @@ static void s3c24xx_serial_rx_enable(str
+       wr_regl(port, S3C2410_UCON, ucon);
+       ourport->rx_enabled = 1;
+-      uart_port_unlock_irqrestore(port, flags);
+ }
+ static void s3c24xx_serial_rx_disable(struct uart_port *port)
+ {
+       struct s3c24xx_uart_port *ourport = to_ourport(port);
+-      unsigned long flags;
+       u32 ucon;
+-      uart_port_lock_irqsave(port, &flags);
+-
+       ucon = rd_regl(port, S3C2410_UCON);
+       ucon &= ~S3C2410_UCON_RXIRQMODE;
+       wr_regl(port, S3C2410_UCON, ucon);
+       ourport->rx_enabled = 0;
+-      uart_port_unlock_irqrestore(port, flags);
+ }
+ static void s3c24xx_serial_stop_tx(struct uart_port *port)
diff --git a/queue-5.10/tty-serial-samsung-use-u32-for-register-interactions.patch b/queue-5.10/tty-serial-samsung-use-u32-for-register-interactions.patch
new file mode 100644 (file)
index 0000000..3e0e312
--- /dev/null
@@ -0,0 +1,314 @@
+From stable+bounces-260806-greg=kroah.com@vger.kernel.org Sat Jun  6 01:08:30 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  5 Jun 2026 15:38:22 -0400
+Subject: tty: serial: samsung: use u32 for register interactions
+To: stable@vger.kernel.org
+Cc: Tudor Ambarus <tudor.ambarus@linaro.org>, Sam Protsenko <semen.protsenko@linaro.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605193823.2169333-2-sashal@kernel.org>
+
+From: Tudor Ambarus <tudor.ambarus@linaro.org>
+
+[ Upstream commit 032a725c16add79332d774348d7ad7d0d4b86479 ]
+
+All registers of the IP have 32 bits. Use u32 variables when reading
+or writing from/to the registers. The purpose of those variables becomes
+clearer.
+
+Reviewed-by: Sam Protsenko <semen.protsenko@linaro.org>
+Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
+Link: https://lore.kernel.org/r/20240119104526.1221243-9-tudor.ambarus@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: a3bb136bff5e ("tty: serial: samsung: Remove redundant port lock acquisition in rx helpers")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/samsung_tty.c |   67 +++++++++++++++++++--------------------
+ 1 file changed, 34 insertions(+), 33 deletions(-)
+
+--- a/drivers/tty/serial/samsung_tty.c
++++ b/drivers/tty/serial/samsung_tty.c
+@@ -186,7 +186,7 @@ static void wr_reg(struct uart_port *por
+ /* Byte-order aware bit setting/clearing functions. */
+ static inline void s3c24xx_set_bit(struct uart_port *port, int idx,
+-                                 unsigned int reg)
++                                 u32 reg)
+ {
+       unsigned long flags;
+       u32 val;
+@@ -199,7 +199,7 @@ static inline void s3c24xx_set_bit(struc
+ }
+ static inline void s3c24xx_clear_bit(struct uart_port *port, int idx,
+-                                   unsigned int reg)
++                                   u32 reg)
+ {
+       unsigned long flags;
+       u32 val;
+@@ -242,8 +242,8 @@ static void s3c24xx_serial_rx_enable(str
+ {
+       struct s3c24xx_uart_port *ourport = to_ourport(port);
+       unsigned long flags;
+-      unsigned int ucon, ufcon;
+       int count = 10000;
++      u32 ucon, ufcon;
+       uart_port_lock_irqsave(port, &flags);
+@@ -266,7 +266,7 @@ static void s3c24xx_serial_rx_disable(st
+ {
+       struct s3c24xx_uart_port *ourport = to_ourport(port);
+       unsigned long flags;
+-      unsigned int ucon;
++      u32 ucon;
+       uart_port_lock_irqsave(port, &flags);
+@@ -551,7 +551,7 @@ static inline struct s3c2410_uartcfg
+ }
+ static int s3c24xx_serial_rx_fifocnt(struct s3c24xx_uart_port *ourport,
+-                                   unsigned long ufstat)
++                                   u32 ufstat)
+ {
+       struct s3c24xx_uart_info *info = ourport->info;
+@@ -623,7 +623,7 @@ static void s3c64xx_start_rx_dma(struct
+ static void enable_rx_dma(struct s3c24xx_uart_port *ourport)
+ {
+       struct uart_port *port = &ourport->port;
+-      unsigned int ucon;
++      u32 ucon;
+       /* set Rx mode to DMA mode */
+       ucon = rd_regl(port, S3C2410_UCON);
+@@ -646,7 +646,7 @@ static void enable_rx_dma(struct s3c24xx
+ static void enable_rx_pio(struct s3c24xx_uart_port *ourport)
+ {
+       struct uart_port *port = &ourport->port;
+-      unsigned int ucon;
++      u32 ucon;
+       /* set Rx mode to DMA mode */
+       ucon = rd_regl(port, S3C2410_UCON);
+@@ -667,7 +667,6 @@ static void s3c24xx_serial_rx_drain_fifo
+ static irqreturn_t s3c24xx_serial_rx_chars_dma(void *dev_id)
+ {
+-      unsigned int utrstat, received;
+       struct s3c24xx_uart_port *ourport = dev_id;
+       struct uart_port *port = &ourport->port;
+       struct s3c24xx_uart_dma *dma = ourport->dma;
+@@ -675,6 +674,8 @@ static irqreturn_t s3c24xx_serial_rx_cha
+       struct tty_port *t = &port->state->port;
+       unsigned long flags;
+       struct dma_tx_state state;
++      unsigned int received;
++      u32 utrstat;
+       utrstat = rd_regl(port, S3C2410_UTRSTAT);
+       rd_regl(port, S3C2410_UFSTAT);
+@@ -716,9 +717,10 @@ finish:
+ static void s3c24xx_serial_rx_drain_fifo(struct s3c24xx_uart_port *ourport)
+ {
+       struct uart_port *port = &ourport->port;
+-      unsigned int ufcon, ch, flag, ufstat, uerstat;
++      unsigned int ch, flag;
+       unsigned int fifocnt = 0;
+       int max_count = port->fifosize;
++      u32 ufcon, ufstat, uerstat;
+       while (max_count-- > 0) {
+               /*
+@@ -898,7 +900,7 @@ static irqreturn_t s3c64xx_serial_handle
+ {
+       struct s3c24xx_uart_port *ourport = id;
+       struct uart_port *port = &ourport->port;
+-      unsigned int pend = rd_regl(port, S3C64XX_UINTP);
++      u32 pend = rd_regl(port, S3C64XX_UINTP);
+       irqreturn_t ret = IRQ_HANDLED;
+       if (pend & S3C64XX_UINTM_RXD_MSK) {
+@@ -915,8 +917,8 @@ static irqreturn_t s3c64xx_serial_handle
+ static unsigned int s3c24xx_serial_tx_empty(struct uart_port *port)
+ {
+       struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+-      unsigned long ufstat = rd_regl(port, S3C2410_UFSTAT);
+-      unsigned long ufcon = rd_regl(port, S3C2410_UFCON);
++      u32 ufstat = rd_regl(port, S3C2410_UFSTAT);
++      u32 ufcon = rd_regl(port, S3C2410_UFCON);
+       if (ufcon & S3C2410_UFCON_FIFOMODE) {
+               if ((ufstat & info->tx_fifomask) != 0 ||
+@@ -931,7 +933,7 @@ static unsigned int s3c24xx_serial_tx_em
+ /* no modem control lines */
+ static unsigned int s3c24xx_serial_get_mctrl(struct uart_port *port)
+ {
+-      unsigned int umstat = rd_reg(port, S3C2410_UMSTAT);
++      u32 umstat = rd_reg(port, S3C2410_UMSTAT);
+       if (umstat & S3C2410_UMSTAT_CTS)
+               return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
+@@ -941,7 +943,7 @@ static unsigned int s3c24xx_serial_get_m
+ static void s3c24xx_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
+ {
+-      unsigned int umcon = rd_regl(port, S3C2410_UMCON);
++      u32 umcon = rd_regl(port, S3C2410_UMCON);
+       if (mctrl & TIOCM_RTS)
+               umcon |= S3C2410_UMCOM_RTS_LOW;
+@@ -954,7 +956,7 @@ static void s3c24xx_serial_set_mctrl(str
+ static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state)
+ {
+       unsigned long flags;
+-      unsigned int ucon;
++      u32 ucon;
+       uart_port_lock_irqsave(port, &flags);
+@@ -1167,7 +1169,7 @@ static int s3c64xx_serial_startup(struct
+ {
+       struct s3c24xx_uart_port *ourport = to_ourport(port);
+       unsigned long flags;
+-      unsigned int ufcon;
++      u32 ufcon;
+       int ret;
+       wr_regl(port, S3C64XX_UINTM, 0xf);
+@@ -1210,6 +1212,7 @@ static int s3c64xx_serial_startup(struct
+       return ret;
+ }
++
+ /* power power management control */
+ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
+@@ -1261,7 +1264,7 @@ static void s3c24xx_serial_pm(struct uar
+ static inline int s3c24xx_serial_getsource(struct uart_port *port)
+ {
+       struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+-      unsigned int ucon;
++      u32 ucon;
+       if (info->num_clks == 1)
+               return 0;
+@@ -1275,7 +1278,7 @@ static void s3c24xx_serial_setsource(str
+                       unsigned int clk_sel)
+ {
+       struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+-      unsigned int ucon;
++      u32 ucon;
+       if (info->num_clks == 1)
+               return;
+@@ -1394,9 +1397,8 @@ static void s3c24xx_serial_set_termios(s
+       struct clk *clk = ERR_PTR(-EINVAL);
+       unsigned long flags;
+       unsigned int baud, quot, clk_sel = 0;
+-      unsigned int ulcon;
+-      unsigned int umcon;
+       unsigned int udivslot = 0;
++      u32 ulcon, umcon;
+       /*
+        * We don't support modem control lines.
+@@ -1712,7 +1714,7 @@ static void s3c24xx_serial_resetport(str
+                                  struct s3c2410_uartcfg *cfg)
+ {
+       struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+-      unsigned long ucon = rd_regl(port, S3C2410_UCON);
++      u32 ucon = rd_regl(port, S3C2410_UCON);
+       unsigned int ucon_mask;
+       ucon_mask = info->clksel_mask;
+@@ -2150,7 +2152,7 @@ static int s3c24xx_serial_resume_noirq(s
+       if (port) {
+               /* restore IRQ mask */
+               if (s3c24xx_serial_has_interrupt_mask(port)) {
+-                      unsigned int uintm = 0xf;
++                      u32 uintm = 0xf;
+                       if (ourport->tx_enabled)
+                               uintm &= ~S3C64XX_UINTM_TXD_MSK;
+@@ -2188,10 +2190,10 @@ static const struct dev_pm_ops s3c24xx_s
+ static struct uart_port *cons_uart;
+ static int
+-s3c24xx_serial_console_txrdy(struct uart_port *port, unsigned int ufcon)
++s3c24xx_serial_console_txrdy(struct uart_port *port, u32 ufcon)
+ {
+       struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+-      unsigned long ufstat, utrstat;
++      u32 ufstat, utrstat;
+       if (ufcon & S3C2410_UFCON_FIFOMODE) {
+               /* fifo mode - check amount of data in fifo registers... */
+@@ -2207,7 +2209,7 @@ s3c24xx_serial_console_txrdy(struct uart
+ }
+ static bool
+-s3c24xx_port_configured(unsigned int ucon)
++s3c24xx_port_configured(u32 ucon)
+ {
+       /* consider the serial port configured if the tx/rx mode set */
+       return (ucon & 0xf) != 0;
+@@ -2222,7 +2224,7 @@ s3c24xx_port_configured(unsigned int uco
+ static int s3c24xx_serial_get_poll_char(struct uart_port *port)
+ {
+       struct s3c24xx_uart_port *ourport = to_ourport(port);
+-      unsigned int ufstat;
++      u32 ufstat;
+       ufstat = rd_regl(port, S3C2410_UFSTAT);
+       if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0)
+@@ -2234,8 +2236,8 @@ static int s3c24xx_serial_get_poll_char(
+ static void s3c24xx_serial_put_poll_char(struct uart_port *port,
+               unsigned char c)
+ {
+-      unsigned int ufcon = rd_regl(port, S3C2410_UFCON);
+-      unsigned int ucon = rd_regl(port, S3C2410_UCON);
++      u32 ufcon = rd_regl(port, S3C2410_UFCON);
++      u32 ucon = rd_regl(port, S3C2410_UCON);
+       /* not possible to xmit on unconfigured port */
+       if (!s3c24xx_port_configured(ucon))
+@@ -2251,7 +2253,7 @@ static void s3c24xx_serial_put_poll_char
+ static void
+ s3c24xx_serial_console_putchar(struct uart_port *port, int ch)
+ {
+-      unsigned int ufcon = rd_regl(port, S3C2410_UFCON);
++      u32 ufcon = rd_regl(port, S3C2410_UFCON);
+       while (!s3c24xx_serial_console_txrdy(port, ufcon))
+               cpu_relax();
+@@ -2262,7 +2264,7 @@ static void
+ s3c24xx_serial_console_write(struct console *co, const char *s,
+                            unsigned int count)
+ {
+-      unsigned int ucon = rd_regl(cons_uart, S3C2410_UCON);
++      u32 ucon = rd_regl(cons_uart, S3C2410_UCON);
+       /* not possible to xmit on unconfigured port */
+       if (!s3c24xx_port_configured(ucon))
+@@ -2276,11 +2278,9 @@ s3c24xx_serial_get_options(struct uart_p
+                          int *parity, int *bits)
+ {
+       struct clk *clk;
+-      unsigned int ulcon;
+-      unsigned int ucon;
+-      unsigned int ubrdiv;
+       unsigned long rate;
+       unsigned int clk_sel;
++      u32 ulcon, ucon, ubrdiv;
+       char clk_name[MAX_CLK_NAME_LENGTH];
+       ulcon  = rd_regl(port, S3C2410_ULCON);
+@@ -2677,6 +2677,7 @@ static void samsung_early_write(struct c
+       uart_console_write(&dev->port, s, n, samsung_early_putc);
+ }
++
+ static int __init samsung_early_console_setup(struct earlycon_device *device,
+                                             const char *opt)
+ {
diff --git a/queue-5.10/usb-cdns3-gadget-fix-request-skipping-after-clearing-halt.patch b/queue-5.10/usb-cdns3-gadget-fix-request-skipping-after-clearing-halt.patch
new file mode 100644 (file)
index 0000000..ccea523
--- /dev/null
@@ -0,0 +1,71 @@
+From sashal@kernel.org Fri Jun  5 01:15:06 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu,  4 Jun 2026 15:45:00 -0400
+Subject: usb: cdns3: gadget: fix request skipping after clearing halt
+To: stable@vger.kernel.org
+Cc: Yongchao Wu <yongchao.wu@autochips.com>, stable <stable@kernel.org>, Peter Chen <peter.chen@kernel.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260604194501.920866-1-sashal@kernel.org>
+
+From: Yongchao Wu <yongchao.wu@autochips.com>
+
+[ Upstream commit c8778ff817a7047d6848fefba99dcb27b1bf01fe ]
+
+According to the cdns3 datasheet, the EPRST (Endpoint Reset) command
+causes the DMA engine to reposition its internal pointer to the next
+Transfer Descriptor (TD) if it was already processing one.
+
+This issue is consistently observed during the ADB identification
+process on macOS hosts, where the host issues a Clear_Halt. Although
+commit 4bf2dd65135a ("usb: cdns3: gadget: toggle cycle bit before reset
+endpoint") attempted to avoid DMA advance by toggling the cycle bit,
+trace logs show that on certain hosts like macOS, the DMA pointer
+(EP_TRADDR) still shifts after EPRST:
+
+  cdns3_ctrl_req: Clear Endpoint Feature(Halt ep1out)
+  cdns3_doorbell_epx: ep1out, ep_trbaddr f9c04030  <-- Should be f9c04000
+  cdns3_gadget_giveback: ep1out: req: ... length: 16384/16384
+
+As shown above, the DMA pointer jumped to the next TD, causing
+the controller to skip the initial TRBs of the request. This leads to
+data misalignment and ADB protocol hangs on macOS.
+
+Fix this by manually restoring the EP_TRADDR register to the starting
+physical address of the current request after the EPRST operation is
+complete.
+
+Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver")
+Cc: stable <stable@kernel.org>
+Cc: Peter Chen <peter.chen@kernel.org>
+Signed-off-by: Yongchao Wu <yongchao.wu@autochips.com>
+Acked-by: Peter Chen <peter.chen@kernel.org>
+Link: https://patch.msgid.link/20260513160012.2547894-1-yongchao.wu@autochips.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/cdns3/gadget.c |   12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/cdns3/gadget.c
++++ b/drivers/usb/cdns3/gadget.c
+@@ -2798,9 +2798,19 @@ int __cdns3_gadget_ep_clear_halt(struct
+       priv_ep->flags &= ~(EP_STALLED | EP_STALL_PENDING);
+       if (request) {
+-              if (trb)
++              if (trb) {
+                       *trb = trb_tmp;
++                      /*
++                       * Per datasheet, EPRST causes DMA to reposition to the next TD.
++                       * Manually reset EP_TRADDR to the current TRB to prevent
++                       * the hardware from skipping the interrupted request.
++                       */
++                      writel(EP_TRADDR_TRADDR(priv_ep->trb_pool_dma +
++                                              priv_req->start_trb * TRB_SIZE),
++                                              &priv_dev->regs->ep_traddr);
++              }
++
+               cdns3_rearm_transfer(priv_ep, 1);
+       }
diff --git a/queue-5.10/usb-gadget-f_hid-fix-device-reference-leak-in-hidg_alloc.patch b/queue-5.10/usb-gadget-f_hid-fix-device-reference-leak-in-hidg_alloc.patch
new file mode 100644 (file)
index 0000000..ff6267a
--- /dev/null
@@ -0,0 +1,58 @@
+From stable+bounces-260813-greg=kroah.com@vger.kernel.org Sat Jun  6 01:16:30 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  5 Jun 2026 15:46:20 -0400
+Subject: usb: gadget: f_hid: fix device reference leak in hidg_alloc()
+To: stable@vger.kernel.org
+Cc: Guangshuo Li <lgs201920130244@gmail.com>, stable <stable@kernel.org>, Johan Hovold <johan@kernel.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605194620.2186017-2-sashal@kernel.org>
+
+From: Guangshuo Li <lgs201920130244@gmail.com>
+
+[ Upstream commit 4f88d65def6f3c90121601b4f62a4c967f3063a6 ]
+
+hidg_alloc() initializes hidg->dev with device_initialize() before
+calling dev_set_name(). If dev_set_name() fails, the function currently
+jumps to err_unlock and returns without calling put_device().
+
+This leaves the device reference unbalanced and prevents hidg_release()
+from being called. Calling put_device() here is also safe, since
+hidg_release() only frees resources owned by hidg.
+
+The issue was identified by a static analysis tool I developed and
+confirmed by manual review.
+
+Route the dev_set_name() failure path through err_put_device so the
+device reference is dropped properly.
+
+Fixes: 89ff3dfac604 ("usb: gadget: f_hid: fix f_hidg lifetime vs cdev")
+Cc: stable <stable@kernel.org>
+Reviewed-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
+Reviewed-by: Johan Hovold johan@kernel.org
+Link: https://patch.msgid.link/20260413142119.2977716-1-lgs201920130244@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/f_hid.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/usb/gadget/function/f_hid.c
++++ b/drivers/usb/gadget/function/f_hid.c
+@@ -1278,7 +1278,7 @@ static struct usb_function *hidg_alloc(s
+       hidg->dev.devt = MKDEV(major, opts->minor);
+       ret = dev_set_name(&hidg->dev, "hidg%d", opts->minor);
+       if (ret)
+-              goto err_unlock;
++              goto err_put_device;
+       hidg->bInterfaceSubClass = opts->subclass;
+       hidg->bInterfaceProtocol = opts->protocol;
+@@ -1313,7 +1313,6 @@ static struct usb_function *hidg_alloc(s
+ err_put_device:
+       put_device(&hidg->dev);
+-err_unlock:
+       mutex_unlock(&opts->lock);
+       return ERR_PTR(ret);
+ }
diff --git a/queue-5.10/usb-gadget-f_hid-tidy-error-handling-in-hidg_alloc.patch b/queue-5.10/usb-gadget-f_hid-tidy-error-handling-in-hidg_alloc.patch
new file mode 100644 (file)
index 0000000..a241a19
--- /dev/null
@@ -0,0 +1,87 @@
+From stable+bounces-260812-greg=kroah.com@vger.kernel.org Sat Jun  6 01:16:31 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  5 Jun 2026 15:46:19 -0400
+Subject: usb: gadget: f_hid: tidy error handling in hidg_alloc
+To: stable@vger.kernel.org
+Cc: John Keeping <john@metanate.com>, Lee Jones <lee@kernel.org>, Andrzej Pietrasiewicz <andrzej.p@collabora.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605194620.2186017-1-sashal@kernel.org>
+
+From: John Keeping <john@metanate.com>
+
+[ Upstream commit 944fe915d00d3cb1bacb1e77cabfb6dc82e6f8b8 ]
+
+Unify error handling at the end of the function, reducing the risk of
+missing something on one of the error paths.
+
+Moving the increment of opts->refcnt later means there is no need to
+decrement it on the error path and is safe as this is guarded by
+opts->lock which is held for this entire section.
+
+Tested-by: Lee Jones <lee@kernel.org>
+Reviewed-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+Reviewed-by: Lee Jones <lee@kernel.org>
+Signed-off-by: John Keeping <john@metanate.com>
+Link: https://lore.kernel.org/r/20221122123523.3068034-4-john@metanate.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 4f88d65def6f ("usb: gadget: f_hid: fix device reference leak in hidg_alloc()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/f_hid.c |   21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+--- a/drivers/usb/gadget/function/f_hid.c
++++ b/drivers/usb/gadget/function/f_hid.c
+@@ -1265,7 +1265,6 @@ static struct usb_function *hidg_alloc(s
+       opts = container_of(fi, struct f_hid_opts, func_inst);
+       mutex_lock(&opts->lock);
+-      ++opts->refcnt;
+       spin_lock_init(&hidg->write_spinlock);
+       spin_lock_init(&hidg->read_spinlock);
+@@ -1278,11 +1277,8 @@ static struct usb_function *hidg_alloc(s
+       hidg->dev.class = hidg_class;
+       hidg->dev.devt = MKDEV(major, opts->minor);
+       ret = dev_set_name(&hidg->dev, "hidg%d", opts->minor);
+-      if (ret) {
+-              --opts->refcnt;
+-              mutex_unlock(&opts->lock);
+-              return ERR_PTR(ret);
+-      }
++      if (ret)
++              goto err_unlock;
+       hidg->bInterfaceSubClass = opts->subclass;
+       hidg->bInterfaceProtocol = opts->protocol;
+@@ -1293,14 +1289,13 @@ static struct usb_function *hidg_alloc(s
+                                           opts->report_desc_length,
+                                           GFP_KERNEL);
+               if (!hidg->report_desc) {
+-                      put_device(&hidg->dev);
+-                      --opts->refcnt;
+-                      mutex_unlock(&opts->lock);
+-                      return ERR_PTR(-ENOMEM);
++                      ret = -ENOMEM;
++                      goto err_put_device;
+               }
+       }
+       hidg->use_out_ep = !opts->no_out_endpoint;
++      ++opts->refcnt;
+       mutex_unlock(&opts->lock);
+       hidg->func.name    = "hid";
+@@ -1315,6 +1310,12 @@ static struct usb_function *hidg_alloc(s
+       hidg->qlen         = 4;
+       return &hidg->func;
++
++err_put_device:
++      put_device(&hidg->dev);
++err_unlock:
++      mutex_unlock(&opts->lock);
++      return ERR_PTR(ret);
+ }
+ DECLARE_USB_FUNCTION_INIT(hid, hidg_alloc_inst, hidg_alloc);
diff --git a/queue-5.10/xfrm-input-hold-netns-during-deferred-transport-reinjection.patch b/queue-5.10/xfrm-input-hold-netns-during-deferred-transport-reinjection.patch
new file mode 100644 (file)
index 0000000..e878960
--- /dev/null
@@ -0,0 +1,79 @@
+From stable+bounces-260691-greg=kroah.com@vger.kernel.org Fri Jun  5 18:36:41 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  5 Jun 2026 09:05:13 -0400
+Subject: xfrm: input: hold netns during deferred transport reinjection
+To: stable@vger.kernel.org
+Cc: Zhengchuan Liang <zcliangcn@gmail.com>, stable@kernel.org, Yuan Tan <yuantan098@gmail.com>, Xin Liu <bird@lzu.edu.cn>, Luxing Yin <tr0jan@lzu.edu.cn>, Ren Wei <n05ec@lzu.edu.cn>, Steffen Klassert <steffen.klassert@secunet.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605130513.410471-1-sashal@kernel.org>
+
+From: Zhengchuan Liang <zcliangcn@gmail.com>
+
+[ Upstream commit c16f74dc1d75d0e2e7670076d5375deda110ebeb ]
+
+Transport-mode reinjection stores a struct net pointer in skb->cb and
+uses it later from xfrm_trans_reinject(). That pointer must stay valid
+until the deferred callback runs.
+
+Take a netns reference when queueing deferred reinjection work and drop
+it after the callback completes. Use maybe_get_net() so the queueing
+path does not revive a namespace that is already being torn down.
+
+This keeps the existing workqueue design and fixes the netns lifetime
+handling in one place for all users of xfrm_trans_queue_net().
+
+Fixes: 7b3801927e52 ("xfrm: introduce xfrm_trans_queue_net")
+Cc: stable@kernel.org
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Co-developed-by: Luxing Yin <tr0jan@lzu.edu.cn>
+Signed-off-by: Luxing Yin <tr0jan@lzu.edu.cn>
+Signed-off-by: Zhengchuan Liang <zcliangcn@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Assisted-by: Codex:gpt-5.4
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/xfrm/xfrm_input.c |   16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+--- a/net/xfrm/xfrm_input.c
++++ b/net/xfrm/xfrm_input.c
+@@ -777,9 +777,12 @@ static void xfrm_trans_reinject(unsigned
+       __skb_queue_head_init(&queue);
+       skb_queue_splice_init(&trans->queue, &queue);
+-      while ((skb = __skb_dequeue(&queue)))
+-              XFRM_TRANS_SKB_CB(skb)->finish(XFRM_TRANS_SKB_CB(skb)->net,
+-                                             NULL, skb);
++      while ((skb = __skb_dequeue(&queue))) {
++              struct net *net = XFRM_TRANS_SKB_CB(skb)->net;
++
++              XFRM_TRANS_SKB_CB(skb)->finish(net, NULL, skb);
++              put_net(net);
++      }
+ }
+ int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
+@@ -787,6 +790,7 @@ int xfrm_trans_queue_net(struct net *net
+                                      struct sk_buff *))
+ {
+       struct xfrm_trans_tasklet *trans;
++      struct net *hold_net;
+       trans = this_cpu_ptr(&xfrm_trans_tasklet);
+@@ -795,8 +799,12 @@ int xfrm_trans_queue_net(struct net *net
+       BUILD_BUG_ON(sizeof(struct xfrm_trans_cb) > sizeof(skb->cb));
++      hold_net = maybe_get_net(net);
++      if (!hold_net)
++              return -ENODEV;
++
+       XFRM_TRANS_SKB_CB(skb)->finish = finish;
+-      XFRM_TRANS_SKB_CB(skb)->net = net;
++      XFRM_TRANS_SKB_CB(skb)->net = hold_net;
+       __skb_queue_tail(&trans->queue, skb);
+       tasklet_schedule(&trans->tasklet);
+       return 0;