From: Sasha Levin Date: Mon, 11 Dec 2023 18:11:25 +0000 (-0500) Subject: Fixes for 5.10 X-Git-Tag: v4.14.333~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c72896fc240e23a724277f7a8db8376996e2c376;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.10 Signed-off-by: Sasha Levin --- 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 index 00000000000..a56e2d8c460 --- /dev/null +++ b/queue-5.10/cifs-fix-non-availability-of-dedup-breaking-generic-.patch @@ -0,0 +1,56 @@ +From 792123092429804aefb33cd7b59ffdfd6d8b8ed1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Dec 2023 14:01:59 +0000 +Subject: cifs: Fix non-availability of dedup breaking generic/304 + +From: David Howells + +[ 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 +cc: Xiaoli Feng +cc: Shyam Prasad N +cc: Rohith Surabattula +cc: Jeff Layton +cc: Darrick Wong +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 +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..e84910106d8 --- /dev/null +++ b/queue-5.10/devcoredump-send-uevent-once-devcd-is-ready.patch @@ -0,0 +1,59 @@ +From 0520d39ce8407c99e14289643dc7a571e42b853e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Nov 2023 20:19:32 +0530 +Subject: devcoredump: Send uevent once devcd is ready + +From: Mukesh Ojha + +[ 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 +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 +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..704f295b1e7 --- /dev/null +++ b/queue-5.10/devcoredump-serialize-devcd_del-work.patch @@ -0,0 +1,208 @@ +From b341f435b18ed89c44aee5b8b95e07a5920785e8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 13 Sep 2022 18:20:24 +0530 +Subject: devcoredump : Serialize devcd_del work + +From: Mukesh Ojha + +[ 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 +Link: https://lore.kernel.org/r/1663073424-13663-1-git-send-email-quic_mojha@quicinc.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: af54d778a038 ("devcoredump: Send uevent once devcd is ready") +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..f9dc7dcf84d --- /dev/null +++ b/queue-5.10/r8169-fix-rtl8125b-pause-frames-blasting-when-suspen.patch @@ -0,0 +1,74 @@ +From 1c1575c8ec7937d3007b3ef03b756f59275fa9cd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Nov 2023 23:53:50 +0800 +Subject: r8169: fix rtl8125b PAUSE frames blasting when suspended + +From: ChunHao Lin + +[ 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 +Tested-by: Grant Grundler +Cc: stable@vger.kernel.org +Signed-off-by: ChunHao Lin +Reviewed-by: Jacob Keller +Reviewed-by: Heiner Kallweit +Link: https://lore.kernel.org/r/20231129155350.5843-1-hau@realtek.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.10/series b/queue-5.10/series index fed046385b0..10286bc88d1 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -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 index 00000000000..79edc9cff9c --- /dev/null +++ b/queue-5.10/smb-client-fix-potential-null-deref-in-parse_dfs_ref.patch @@ -0,0 +1,43 @@ +From 1dd48abfccf96d5e7a2ce733d1f43b50f5886543 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Dec 2023 21:49:29 -0300 +Subject: smb: client: fix potential NULL deref in parse_dfs_referrals() + +From: Paulo Alcantara + +[ 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 +Signed-off-by: Paulo Alcantara (SUSE) +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + 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 +