]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.10
authorSasha Levin <sashal@kernel.org>
Mon, 11 Dec 2023 18:11:25 +0000 (13:11 -0500)
committerSasha Levin <sashal@kernel.org>
Mon, 11 Dec 2023 18:11:25 +0000 (13:11 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-5.10/cifs-fix-non-availability-of-dedup-breaking-generic-.patch [new file with mode: 0644]
queue-5.10/devcoredump-send-uevent-once-devcd-is-ready.patch [new file with mode: 0644]
queue-5.10/devcoredump-serialize-devcd_del-work.patch [new file with mode: 0644]
queue-5.10/r8169-fix-rtl8125b-pause-frames-blasting-when-suspen.patch [new file with mode: 0644]
queue-5.10/series
queue-5.10/smb-client-fix-potential-null-deref-in-parse_dfs_ref.patch [new file with mode: 0644]

diff --git a/queue-5.10/cifs-fix-non-availability-of-dedup-breaking-generic-.patch b/queue-5.10/cifs-fix-non-availability-of-dedup-breaking-generic-.patch
new file mode 100644 (file)
index 0000000..a56e2d8
--- /dev/null
@@ -0,0 +1,56 @@
+From 792123092429804aefb33cd7b59ffdfd6d8b8ed1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Dec 2023 14:01:59 +0000
+Subject: cifs: Fix non-availability of dedup breaking generic/304
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 691a41d8da4b34fe72f09393505f55f28a8f34ec ]
+
+Deduplication isn't supported on cifs, but cifs doesn't reject it, instead
+treating it as extent duplication/cloning.  This can cause generic/304 to go
+silly and run for hours on end.
+
+Fix cifs to indicate EOPNOTSUPP if REMAP_FILE_DEDUP is set in
+->remap_file_range().
+
+Note that it's unclear whether or not commit b073a08016a1 is meant to cause
+cifs to return an error if REMAP_FILE_DEDUP.
+
+Fixes: b073a08016a1 ("cifs: fix that return -EINVAL when do dedupe operation")
+Cc: stable@vger.kernel.org
+Suggested-by: Dave Chinner <david@fromorbit.com>
+cc: Xiaoli Feng <fengxiaoli0714@gmail.com>
+cc: Shyam Prasad N <nspmangalore@gmail.com>
+cc: Rohith Surabattula <rohiths.msft@gmail.com>
+cc: Jeff Layton <jlayton@kernel.org>
+cc: Darrick Wong <darrick.wong@oracle.com>
+cc: fstests@vger.kernel.org
+cc: linux-cifs@vger.kernel.org
+cc: linux-fsdevel@vger.kernel.org
+Link: https://lore.kernel.org/r/3876191.1701555260@warthog.procyon.org.uk/
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/cifsfs.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
+index b87d6792b14ad..16155529e449f 100644
+--- a/fs/cifs/cifsfs.c
++++ b/fs/cifs/cifsfs.c
+@@ -1093,7 +1093,9 @@ static loff_t cifs_remap_file_range(struct file *src_file, loff_t off,
+       unsigned int xid;
+       int rc;
+-      if (remap_flags & ~(REMAP_FILE_DEDUP | REMAP_FILE_ADVISORY))
++      if (remap_flags & REMAP_FILE_DEDUP)
++              return -EOPNOTSUPP;
++      if (remap_flags & ~REMAP_FILE_ADVISORY)
+               return -EINVAL;
+       cifs_dbg(FYI, "clone range\n");
+-- 
+2.42.0
+
diff --git a/queue-5.10/devcoredump-send-uevent-once-devcd-is-ready.patch b/queue-5.10/devcoredump-send-uevent-once-devcd-is-ready.patch
new file mode 100644 (file)
index 0000000..e849101
--- /dev/null
@@ -0,0 +1,59 @@
+From 0520d39ce8407c99e14289643dc7a571e42b853e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Nov 2023 20:19:32 +0530
+Subject: devcoredump: Send uevent once devcd is ready
+
+From: Mukesh Ojha <quic_mojha@quicinc.com>
+
+[ Upstream commit af54d778a03853801d681c98c0c2a6c316ef9ca7 ]
+
+dev_coredumpm() creates a devcoredump device and adds it
+to the core kernel framework which eventually end up
+sending uevent to the user space and later creates a
+symbolic link to the failed device. An application
+running in userspace may be interested in this symbolic
+link to get the name of the failed device.
+
+In a issue scenario, once uevent sent to the user space
+it start reading '/sys/class/devcoredump/devcdX/failing_device'
+to get the actual name of the device which might not been
+created and it is in its path of creation.
+
+To fix this, suppress sending uevent till the failing device
+symbolic link gets created and send uevent once symbolic
+link is created successfully.
+
+Fixes: 833c95456a70 ("device coredump: add new device coredump class")
+Signed-off-by: Mukesh Ojha <quic_mojha@quicinc.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/1700232572-25823-1-git-send-email-quic_mojha@quicinc.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/devcoredump.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/base/devcoredump.c b/drivers/base/devcoredump.c
+index ef23c1c33eb2c..4d725d1fd61ae 100644
+--- a/drivers/base/devcoredump.c
++++ b/drivers/base/devcoredump.c
+@@ -367,6 +367,7 @@ void dev_coredumpm(struct device *dev, struct module *owner,
+       devcd->devcd_dev.class = &devcd_class;
+       mutex_lock(&devcd->mutex);
++      dev_set_uevent_suppress(&devcd->devcd_dev, true);
+       if (device_add(&devcd->devcd_dev))
+               goto put_device;
+@@ -378,6 +379,8 @@ void dev_coredumpm(struct device *dev, struct module *owner,
+                             "devcoredump"))
+               /* nothing - symlink will be missing */;
++      dev_set_uevent_suppress(&devcd->devcd_dev, false);
++      kobject_uevent(&devcd->devcd_dev.kobj, KOBJ_ADD);
+       INIT_DELAYED_WORK(&devcd->del_wk, devcd_del);
+       schedule_delayed_work(&devcd->del_wk, DEVCD_TIMEOUT);
+       mutex_unlock(&devcd->mutex);
+-- 
+2.42.0
+
diff --git a/queue-5.10/devcoredump-serialize-devcd_del-work.patch b/queue-5.10/devcoredump-serialize-devcd_del-work.patch
new file mode 100644 (file)
index 0000000..704f295
--- /dev/null
@@ -0,0 +1,208 @@
+From b341f435b18ed89c44aee5b8b95e07a5920785e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Sep 2022 18:20:24 +0530
+Subject: devcoredump : Serialize devcd_del work
+
+From: Mukesh Ojha <quic_mojha@quicinc.com>
+
+[ Upstream commit 01daccf748323dfc61112f474cf2ba81015446b0 ]
+
+In following scenario(diagram), when one thread X running dev_coredumpm()
+adds devcd device to the framework which sends uevent notification to
+userspace and another thread Y reads this uevent and call to
+devcd_data_write() which eventually try to delete the queued timer that
+is not initialized/queued yet.
+
+So, debug object reports some warning and in the meantime, timer is
+initialized and queued from X path. and from Y path, it gets reinitialized
+again and timer->entry.pprev=NULL and try_to_grab_pending() stucks.
+
+To fix this, introduce mutex and a boolean flag to serialize the behaviour.
+
+       cpu0(X)                                 cpu1(Y)
+
+    dev_coredump() uevent sent to user space
+    device_add()  ======================> user space process Y reads the
+                                          uevents writes to devcd fd
+                                          which results into writes to
+
+                                         devcd_data_write()
+                                           mod_delayed_work()
+                                             try_to_grab_pending()
+                                               del_timer()
+                                                 debug_assert_init()
+   INIT_DELAYED_WORK()
+   schedule_delayed_work()
+                                                   debug_object_fixup()
+                                                     timer_fixup_assert_init()
+                                                       timer_setup()
+                                                         do_init_timer()
+                                                       /*
+                                                        Above call reinitializes
+                                                        the timer to
+                                                        timer->entry.pprev=NULL
+                                                        and this will be checked
+                                                        later in timer_pending() call.
+                                                       */
+                                                 timer_pending()
+                                                  !hlist_unhashed_lockless(&timer->entry)
+                                                    !h->pprev
+                                                /*
+                                                  del_timer() checks h->pprev and finds
+                                                  it to be NULL due to which
+                                                  try_to_grab_pending() stucks.
+                                                */
+
+Link: https://lore.kernel.org/lkml/2e1f81e2-428c-f11f-ce92-eb11048cb271@quicinc.com/
+Signed-off-by: Mukesh Ojha <quic_mojha@quicinc.com>
+Link: https://lore.kernel.org/r/1663073424-13663-1-git-send-email-quic_mojha@quicinc.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: af54d778a038 ("devcoredump: Send uevent once devcd is ready")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/devcoredump.c | 83 +++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 81 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/base/devcoredump.c b/drivers/base/devcoredump.c
+index 9243468e2c99f..ef23c1c33eb2c 100644
+--- a/drivers/base/devcoredump.c
++++ b/drivers/base/devcoredump.c
+@@ -29,6 +29,47 @@ struct devcd_entry {
+       struct device devcd_dev;
+       void *data;
+       size_t datalen;
++      /*
++       * Here, mutex is required to serialize the calls to del_wk work between
++       * user/kernel space which happens when devcd is added with device_add()
++       * and that sends uevent to user space. User space reads the uevents,
++       * and calls to devcd_data_write() which try to modify the work which is
++       * not even initialized/queued from devcoredump.
++       *
++       *
++       *
++       *        cpu0(X)                                 cpu1(Y)
++       *
++       *        dev_coredump() uevent sent to user space
++       *        device_add()  ======================> user space process Y reads the
++       *                                              uevents writes to devcd fd
++       *                                              which results into writes to
++       *
++       *                                             devcd_data_write()
++       *                                               mod_delayed_work()
++       *                                                 try_to_grab_pending()
++       *                                                   del_timer()
++       *                                                     debug_assert_init()
++       *       INIT_DELAYED_WORK()
++       *       schedule_delayed_work()
++       *
++       *
++       * Also, mutex alone would not be enough to avoid scheduling of
++       * del_wk work after it get flush from a call to devcd_free()
++       * mentioned as below.
++       *
++       *      disabled_store()
++       *        devcd_free()
++       *          mutex_lock()             devcd_data_write()
++       *          flush_delayed_work()
++       *          mutex_unlock()
++       *                                   mutex_lock()
++       *                                   mod_delayed_work()
++       *                                   mutex_unlock()
++       * So, delete_work flag is required.
++       */
++      struct mutex mutex;
++      bool delete_work;
+       struct module *owner;
+       ssize_t (*read)(char *buffer, loff_t offset, size_t count,
+                       void *data, size_t datalen);
+@@ -88,7 +129,12 @@ static ssize_t devcd_data_write(struct file *filp, struct kobject *kobj,
+       struct device *dev = kobj_to_dev(kobj);
+       struct devcd_entry *devcd = dev_to_devcd(dev);
+-      mod_delayed_work(system_wq, &devcd->del_wk, 0);
++      mutex_lock(&devcd->mutex);
++      if (!devcd->delete_work) {
++              devcd->delete_work = true;
++              mod_delayed_work(system_wq, &devcd->del_wk, 0);
++      }
++      mutex_unlock(&devcd->mutex);
+       return count;
+ }
+@@ -116,7 +162,12 @@ static int devcd_free(struct device *dev, void *data)
+ {
+       struct devcd_entry *devcd = dev_to_devcd(dev);
++      mutex_lock(&devcd->mutex);
++      if (!devcd->delete_work)
++              devcd->delete_work = true;
++
+       flush_delayed_work(&devcd->del_wk);
++      mutex_unlock(&devcd->mutex);
+       return 0;
+ }
+@@ -126,6 +177,30 @@ static ssize_t disabled_show(struct class *class, struct class_attribute *attr,
+       return sysfs_emit(buf, "%d\n", devcd_disabled);
+ }
++/*
++ *
++ *    disabled_store()                                        worker()
++ *     class_for_each_device(&devcd_class,
++ *            NULL, NULL, devcd_free)
++ *         ...
++ *         ...
++ *       while ((dev = class_dev_iter_next(&iter))
++ *                                                             devcd_del()
++ *                                                               device_del()
++ *                                                                 put_device() <- last reference
++ *             error = fn(dev, data)                           devcd_dev_release()
++ *             devcd_free(dev, data)                           kfree(devcd)
++ *             mutex_lock(&devcd->mutex);
++ *
++ *
++ * In the above diagram, It looks like disabled_store() would be racing with parallely
++ * running devcd_del() and result in memory abort while acquiring devcd->mutex which
++ * is called after kfree of devcd memory  after dropping its last reference with
++ * put_device(). However, this will not happens as fn(dev, data) runs
++ * with its own reference to device via klist_node so it is not its last reference.
++ * so, above situation would not occur.
++ */
++
+ static ssize_t disabled_store(struct class *class, struct class_attribute *attr,
+                             const char *buf, size_t count)
+ {
+@@ -282,13 +357,16 @@ void dev_coredumpm(struct device *dev, struct module *owner,
+       devcd->read = read;
+       devcd->free = free;
+       devcd->failing_dev = get_device(dev);
++      devcd->delete_work = false;
++      mutex_init(&devcd->mutex);
+       device_initialize(&devcd->devcd_dev);
+       dev_set_name(&devcd->devcd_dev, "devcd%d",
+                    atomic_inc_return(&devcd_count));
+       devcd->devcd_dev.class = &devcd_class;
++      mutex_lock(&devcd->mutex);
+       if (device_add(&devcd->devcd_dev))
+               goto put_device;
+@@ -302,10 +380,11 @@ void dev_coredumpm(struct device *dev, struct module *owner,
+       INIT_DELAYED_WORK(&devcd->del_wk, devcd_del);
+       schedule_delayed_work(&devcd->del_wk, DEVCD_TIMEOUT);
+-
++      mutex_unlock(&devcd->mutex);
+       return;
+  put_device:
+       put_device(&devcd->devcd_dev);
++      mutex_unlock(&devcd->mutex);
+  put_module:
+       module_put(owner);
+  free:
+-- 
+2.42.0
+
diff --git a/queue-5.10/r8169-fix-rtl8125b-pause-frames-blasting-when-suspen.patch b/queue-5.10/r8169-fix-rtl8125b-pause-frames-blasting-when-suspen.patch
new file mode 100644 (file)
index 0000000..f9dc7dc
--- /dev/null
@@ -0,0 +1,74 @@
+From 1c1575c8ec7937d3007b3ef03b756f59275fa9cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Nov 2023 23:53:50 +0800
+Subject: r8169: fix rtl8125b PAUSE frames blasting when suspended
+
+From: ChunHao Lin <hau@realtek.com>
+
+[ Upstream commit 4b0768b6556af56ee9b7cf4e68452a2b6289ae45 ]
+
+When FIFO reaches near full state, device will issue pause frame.
+If pause slot is enabled(set to 1), in this time, device will issue
+pause frame only once. But if pause slot is disabled(set to 0), device
+will keep sending pause frames until FIFO reaches near empty state.
+
+When pause slot is disabled, if there is no one to handle receive
+packets, device FIFO will reach near full state and keep sending
+pause frames. That will impact entire local area network.
+
+This issue can be reproduced in Chromebox (not Chromebook) in
+developer mode running a test image (and v5.10 kernel):
+1) ping -f $CHROMEBOX (from workstation on same local network)
+2) run "powerd_dbus_suspend" from command line on the $CHROMEBOX
+3) ping $ROUTER (wait until ping fails from workstation)
+
+Takes about ~20-30 seconds after step 2 for the local network to
+stop working.
+
+Fix this issue by enabling pause slot to only send pause frame once
+when FIFO reaches near full state.
+
+Fixes: f1bce4ad2f1c ("r8169: add support for RTL8125")
+Reported-by: Grant Grundler <grundler@chromium.org>
+Tested-by: Grant Grundler <grundler@chromium.org>
+Cc: stable@vger.kernel.org
+Signed-off-by: ChunHao Lin <hau@realtek.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://lore.kernel.org/r/20231129155350.5843-1-hau@realtek.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c
+index 88253cedd9d96..c72ff0fd38c42 100644
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -205,6 +205,7 @@ enum rtl_registers {
+                                       /* No threshold before first PCI xfer */
+ #define       RX_FIFO_THRESH                  (7 << RXCFG_FIFO_SHIFT)
+ #define       RX_EARLY_OFF                    (1 << 11)
++#define       RX_PAUSE_SLOT_ON                (1 << 11)       /* 8125b and later */
+ #define       RXCFG_DMA_SHIFT                 8
+                                       /* Unlimited maximum PCI burst. */
+ #define       RX_DMA_BURST                    (7 << RXCFG_DMA_SHIFT)
+@@ -2318,9 +2319,13 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp)
+       case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_52:
+               RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF);
+               break;
+-      case RTL_GIGA_MAC_VER_60 ... RTL_GIGA_MAC_VER_63:
++      case RTL_GIGA_MAC_VER_61:
+               RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST);
+               break;
++      case RTL_GIGA_MAC_VER_63:
++              RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST |
++                      RX_PAUSE_SLOT_ON);
++              break;
+       default:
+               RTL_W32(tp, RxConfig, RX128_INT_EN | RX_DMA_BURST);
+               break;
+-- 
+2.42.0
+
index fed046385b04587b27b8f4961d6c9feafbb4ab10..10286bc88d1e103c1656555d3bcac15902763d98 100644 (file)
@@ -90,3 +90,8 @@ tools-headers-uapi-sync-linux-perf_event.h-with-the-kernel-sources.patch
 platform-x86-asus-wmi-document-the-dgpu_disable-sysfs-attribute.patch
 mmc-block-be-sure-to-wait-while-busy-in-cqe-error-recovery.patch
 revert-btrfs-add-dmesg-output-for-first-mount-and-last-unmount-of-a-filesystem.patch
+cifs-fix-non-availability-of-dedup-breaking-generic-.patch
+smb-client-fix-potential-null-deref-in-parse_dfs_ref.patch
+devcoredump-serialize-devcd_del-work.patch
+devcoredump-send-uevent-once-devcd-is-ready.patch
+r8169-fix-rtl8125b-pause-frames-blasting-when-suspen.patch
diff --git a/queue-5.10/smb-client-fix-potential-null-deref-in-parse_dfs_ref.patch b/queue-5.10/smb-client-fix-potential-null-deref-in-parse_dfs_ref.patch
new file mode 100644 (file)
index 0000000..79edc9c
--- /dev/null
@@ -0,0 +1,43 @@
+From 1dd48abfccf96d5e7a2ce733d1f43b50f5886543 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Dec 2023 21:49:29 -0300
+Subject: smb: client: fix potential NULL deref in parse_dfs_referrals()
+
+From: Paulo Alcantara <pc@manguebit.com>
+
+[ Upstream commit 92414333eb375ed64f4ae92d34d579e826936480 ]
+
+If server returned no data for FSCTL_DFS_GET_REFERRALS, @dfs_rsp will
+remain NULL and then parse_dfs_referrals() will dereference it.
+
+Fix this by returning -EIO when no output data is returned.
+
+Besides, we can't fix it in SMB2_ioctl() as some FSCTLs are allowed to
+return no data as per MS-SMB2 2.2.32.
+
+Fixes: 9d49640a21bf ("CIFS: implement get_dfs_refer for SMB2+")
+Cc: stable@vger.kernel.org
+Reported-by: Robert Morris <rtm@csail.mit.edu>
+Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/smb2ops.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
+index 015b7b37edee5..e58525a958270 100644
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -2765,6 +2765,8 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses,
+                               (char **)&dfs_rsp, &dfs_rsp_size);
+       } while (rc == -EAGAIN);
++      if (!rc && !dfs_rsp)
++              rc = -EIO;
+       if (rc) {
+               if ((rc != -ENOENT) && (rc != -EOPNOTSUPP))
+                       cifs_tcon_dbg(VFS, "ioctl error in %s rc=%d\n", __func__, rc);
+-- 
+2.42.0
+