]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 12 Jan 2025 12:37:53 +0000 (13:37 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 12 Jan 2025 12:37:53 +0000 (13:37 +0100)
added patches:
drivers-block-zram-zram_drv.c-do-not-keep-dangling-zcomp-pointer-after-zram-reset.patch
md-raid5-fix-atomicity-violation-in-raid5_cache_count.patch
scripts-sorttable-fix-orc_sort_cmp-to-maintain-symmetry-and-transitivity.patch
zram-check-comp-is-non-null-before-calling-comp_destroy.patch
zram-fix-uninitialized-zram-not-releasing-backing-device.patch

queue-5.15/drivers-block-zram-zram_drv.c-do-not-keep-dangling-zcomp-pointer-after-zram-reset.patch [new file with mode: 0644]
queue-5.15/md-raid5-fix-atomicity-violation-in-raid5_cache_count.patch [new file with mode: 0644]
queue-5.15/scripts-sorttable-fix-orc_sort_cmp-to-maintain-symmetry-and-transitivity.patch [new file with mode: 0644]
queue-5.15/series
queue-5.15/zram-check-comp-is-non-null-before-calling-comp_destroy.patch [new file with mode: 0644]
queue-5.15/zram-fix-uninitialized-zram-not-releasing-backing-device.patch [new file with mode: 0644]

diff --git a/queue-5.15/drivers-block-zram-zram_drv.c-do-not-keep-dangling-zcomp-pointer-after-zram-reset.patch b/queue-5.15/drivers-block-zram-zram_drv.c-do-not-keep-dangling-zcomp-pointer-after-zram-reset.patch
new file mode 100644 (file)
index 0000000..e9a07be
--- /dev/null
@@ -0,0 +1,62 @@
+From 6d2453c3dbc5f70eafc1c866289a90a1fc57ce18 Mon Sep 17 00:00:00 2001
+From: Sergey Senozhatsky <senozhatsky@chromium.org>
+Date: Wed, 24 Aug 2022 12:51:00 +0900
+Subject: drivers/block/zram/zram_drv.c: do not keep dangling zcomp pointer after zram reset
+
+From: Sergey Senozhatsky <senozhatsky@chromium.org>
+
+commit 6d2453c3dbc5f70eafc1c866289a90a1fc57ce18 upstream.
+
+We do all reset operations under write lock, so we don't need to save
+->disksize and ->comp to stack variables.  Another thing is that ->comp is
+freed during zram reset, but comp pointer is not NULL-ed, so zram keeps
+the freed pointer value.
+
+Link: https://lkml.kernel.org/r/20220824035100.971816-1-senozhatsky@chromium.org
+Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
+Cc: Minchan Kim <minchan@kernel.org>
+Cc: Nitin Gupta <ngupta@vflare.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: 74363ec674cb ("zram: fix uninitialized ZRAM not releasing backing device")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Dominique Martinet <dominique.martinet@atmark-techno.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/block/zram/zram_drv.c |   13 ++++---------
+ 1 file changed, 4 insertions(+), 9 deletions(-)
+
+--- a/drivers/block/zram/zram_drv.c
++++ b/drivers/block/zram/zram_drv.c
+@@ -1695,9 +1695,6 @@ out:
+ static void zram_reset_device(struct zram *zram)
+ {
+-      struct zcomp *comp;
+-      u64 disksize;
+-
+       down_write(&zram->init_lock);
+       zram->limit_pages = 0;
+@@ -1707,18 +1704,16 @@ static void zram_reset_device(struct zra
+               return;
+       }
+-      comp = zram->comp;
+-      disksize = zram->disksize;
+-      zram->disksize = 0;
+-
+       set_capacity_and_notify(zram->disk, 0);
+       part_stat_set_all(zram->disk->part0, 0);
+       up_write(&zram->init_lock);
+       /* I/O operation under all of CPU are done so let's free */
+-      zram_meta_free(zram, disksize);
++      zram_meta_free(zram, zram->disksize);
++      zram->disksize = 0;
+       memset(&zram->stats, 0, sizeof(zram->stats));
+-      zcomp_destroy(comp);
++      zcomp_destroy(zram->comp);
++      zram->comp = NULL;
+       reset_bdev(zram);
+ }
diff --git a/queue-5.15/md-raid5-fix-atomicity-violation-in-raid5_cache_count.patch b/queue-5.15/md-raid5-fix-atomicity-violation-in-raid5_cache_count.patch
new file mode 100644 (file)
index 0000000..5624c12
--- /dev/null
@@ -0,0 +1,114 @@
+From dfd2bf436709b2bccb78c2dda550dde93700efa7 Mon Sep 17 00:00:00 2001
+From: Gui-Dong Han <2045gemini@gmail.com>
+Date: Fri, 12 Jan 2024 15:10:17 +0800
+Subject: md/raid5: fix atomicity violation in raid5_cache_count
+
+From: Gui-Dong Han <2045gemini@gmail.com>
+
+commit dfd2bf436709b2bccb78c2dda550dde93700efa7 upstream.
+
+In raid5_cache_count():
+    if (conf->max_nr_stripes < conf->min_nr_stripes)
+        return 0;
+    return conf->max_nr_stripes - conf->min_nr_stripes;
+The current check is ineffective, as the values could change immediately
+after being checked.
+
+In raid5_set_cache_size():
+    ...
+    conf->min_nr_stripes = size;
+    ...
+    while (size > conf->max_nr_stripes)
+        conf->min_nr_stripes = conf->max_nr_stripes;
+    ...
+
+Due to intermediate value updates in raid5_set_cache_size(), concurrent
+execution of raid5_cache_count() and raid5_set_cache_size() may lead to
+inconsistent reads of conf->max_nr_stripes and conf->min_nr_stripes.
+The current checks are ineffective as values could change immediately
+after being checked, raising the risk of conf->min_nr_stripes exceeding
+conf->max_nr_stripes and potentially causing an integer overflow.
+
+This possible bug is found by an experimental static analysis tool
+developed by our team. This tool analyzes the locking APIs to extract
+function pairs that can be concurrently executed, and then analyzes the
+instructions in the paired functions to identify possible concurrency bugs
+including data races and atomicity violations. The above possible bug is
+reported when our tool analyzes the source code of Linux 6.2.
+
+To resolve this issue, it is suggested to introduce local variables
+'min_stripes' and 'max_stripes' in raid5_cache_count() to ensure the
+values remain stable throughout the check. Adding locks in
+raid5_cache_count() fails to resolve atomicity violations, as
+raid5_set_cache_size() may hold intermediate values of
+conf->min_nr_stripes while unlocked. With this patch applied, our tool no
+longer reports the bug, with the kernel configuration allyesconfig for
+x86_64. Due to the lack of associated hardware, we cannot test the patch
+in runtime testing, and just verify it according to the code logic.
+
+Fixes: edbe83ab4c27 ("md/raid5: allow the stripe_cache to grow and shrink.")
+Cc: stable@vger.kernel.org
+Signed-off-by: Gui-Dong Han <2045gemini@gmail.com>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Song Liu <song@kernel.org>
+Link: https://lore.kernel.org/r/20240112071017.16313-1-2045gemini@gmail.com
+Signed-off-by: Song Liu <song@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/md/raid5.c |   14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+--- a/drivers/md/raid5.c
++++ b/drivers/md/raid5.c
+@@ -2349,7 +2349,7 @@ static int grow_one_stripe(struct r5conf
+       atomic_inc(&conf->active_stripes);
+       raid5_release_stripe(sh);
+-      conf->max_nr_stripes++;
++      WRITE_ONCE(conf->max_nr_stripes, conf->max_nr_stripes + 1);
+       return 1;
+ }
+@@ -2646,7 +2646,7 @@ static int drop_one_stripe(struct r5conf
+       shrink_buffers(sh);
+       free_stripe(conf->slab_cache, sh);
+       atomic_dec(&conf->active_stripes);
+-      conf->max_nr_stripes--;
++      WRITE_ONCE(conf->max_nr_stripes, conf->max_nr_stripes - 1);
+       return 1;
+ }
+@@ -6577,7 +6577,7 @@ raid5_set_cache_size(struct mddev *mddev
+       if (size <= 16 || size > 32768)
+               return -EINVAL;
+-      conf->min_nr_stripes = size;
++      WRITE_ONCE(conf->min_nr_stripes, size);
+       mutex_lock(&conf->cache_size_mutex);
+       while (size < conf->max_nr_stripes &&
+              drop_one_stripe(conf))
+@@ -6589,7 +6589,7 @@ raid5_set_cache_size(struct mddev *mddev
+       mutex_lock(&conf->cache_size_mutex);
+       while (size > conf->max_nr_stripes)
+               if (!grow_one_stripe(conf, GFP_KERNEL)) {
+-                      conf->min_nr_stripes = conf->max_nr_stripes;
++                      WRITE_ONCE(conf->min_nr_stripes, conf->max_nr_stripes);
+                       result = -ENOMEM;
+                       break;
+               }
+@@ -7153,11 +7153,13 @@ static unsigned long raid5_cache_count(s
+                                      struct shrink_control *sc)
+ {
+       struct r5conf *conf = container_of(shrink, struct r5conf, shrinker);
++      int max_stripes = READ_ONCE(conf->max_nr_stripes);
++      int min_stripes = READ_ONCE(conf->min_nr_stripes);
+-      if (conf->max_nr_stripes < conf->min_nr_stripes)
++      if (max_stripes < min_stripes)
+               /* unlikely, but not impossible */
+               return 0;
+-      return conf->max_nr_stripes - conf->min_nr_stripes;
++      return max_stripes - min_stripes;
+ }
+ static struct r5conf *setup_conf(struct mddev *mddev)
diff --git a/queue-5.15/scripts-sorttable-fix-orc_sort_cmp-to-maintain-symmetry-and-transitivity.patch b/queue-5.15/scripts-sorttable-fix-orc_sort_cmp-to-maintain-symmetry-and-transitivity.patch
new file mode 100644 (file)
index 0000000..53c1a97
--- /dev/null
@@ -0,0 +1,64 @@
+From 0210d251162f4033350a94a43f95b1c39ec84a90 Mon Sep 17 00:00:00 2001
+From: Kuan-Wei Chiu <visitorckw@gmail.com>
+Date: Thu, 26 Dec 2024 22:03:32 +0800
+Subject: scripts/sorttable: fix orc_sort_cmp() to maintain symmetry and transitivity
+
+From: Kuan-Wei Chiu <visitorckw@gmail.com>
+
+commit 0210d251162f4033350a94a43f95b1c39ec84a90 upstream.
+
+The orc_sort_cmp() function, used with qsort(), previously violated the
+symmetry and transitivity rules required by the C standard.  Specifically,
+when both entries are ORC_TYPE_UNDEFINED, it could result in both a < b
+and b < a, which breaks the required symmetry and transitivity.  This can
+lead to undefined behavior and incorrect sorting results, potentially
+causing memory corruption in glibc implementations [1].
+
+Symmetry: If x < y, then y > x.
+Transitivity: If x < y and y < z, then x < z.
+
+Fix the comparison logic to return 0 when both entries are
+ORC_TYPE_UNDEFINED, ensuring compliance with qsort() requirements.
+
+Link: https://www.qualys.com/2024/01/30/qsort.txt [1]
+Link: https://lkml.kernel.org/r/20241226140332.2670689-1-visitorckw@gmail.com
+Fixes: 57fa18994285 ("scripts/sorttable: Implement build-time ORC unwind table sorting")
+Fixes: fb799447ae29 ("x86,objtool: Split UNWIND_HINT_EMPTY in two")
+Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
+Cc: Ching-Chun (Jim) Huang <jserv@ccns.ncku.edu.tw>
+Cc: <chuang@cs.nycu.edu.tw>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Josh Poimboeuf <jpoimboe@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Shile Zhang <shile.zhang@linux.alibaba.com>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ scripts/sorttable.h |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/scripts/sorttable.h
++++ b/scripts/sorttable.h
+@@ -103,7 +103,7 @@ static inline unsigned long orc_ip(const
+ static int orc_sort_cmp(const void *_a, const void *_b)
+ {
+-      struct orc_entry *orc_a;
++      struct orc_entry *orc_a, *orc_b;
+       const int *a = g_orc_ip_table + *(int *)_a;
+       const int *b = g_orc_ip_table + *(int *)_b;
+       unsigned long a_val = orc_ip(a);
+@@ -121,6 +121,10 @@ static int orc_sort_cmp(const void *_a,
+        * whitelisted .o files which didn't get objtool generation.
+        */
+       orc_a = g_orc_table + (a - g_orc_ip_table);
++      orc_b = g_orc_table + (b - g_orc_ip_table);
++      if (orc_a->sp_reg == ORC_REG_UNDEFINED && !orc_a->end &&
++          orc_b->sp_reg == ORC_REG_UNDEFINED && !orc_b->end)
++              return 0;
+       return orc_a->sp_reg == ORC_REG_UNDEFINED && !orc_a->end ? -1 : 1;
+ }
index 4d0eb7839fd360693f2cbf0b00a18f568ce53222..3d4bda098e47633bf99c4876f5bb3eada6e682f9 100644 (file)
@@ -35,3 +35,8 @@ riscv-fix-sleeping-in-invalid-context-in-die.patch
 acpi-resource-add-tongfang-gm5hg0a-to-irq1_edge_low_force_override.patch
 acpi-resource-add-asus-vivobook-x1504vap-to-irq1_level_low_skip_override.patch
 drm-amd-display-increase-max_surfaces-to-the-value-supported-by-hw.patch
+drivers-block-zram-zram_drv.c-do-not-keep-dangling-zcomp-pointer-after-zram-reset.patch
+zram-check-comp-is-non-null-before-calling-comp_destroy.patch
+zram-fix-uninitialized-zram-not-releasing-backing-device.patch
+scripts-sorttable-fix-orc_sort_cmp-to-maintain-symmetry-and-transitivity.patch
+md-raid5-fix-atomicity-violation-in-raid5_cache_count.patch
diff --git a/queue-5.15/zram-check-comp-is-non-null-before-calling-comp_destroy.patch b/queue-5.15/zram-check-comp-is-non-null-before-calling-comp_destroy.patch
new file mode 100644 (file)
index 0000000..332395b
--- /dev/null
@@ -0,0 +1,38 @@
+From 677294e4da96547b9ea2955661a4bbf1d13552a3 Mon Sep 17 00:00:00 2001
+From: Dominique Martinet <dominique.martinet@atmark-techno.com>
+Date: Tue, 7 Jan 2025 16:16:04 +0900
+Subject: zram: check comp is non-NULL before calling comp_destroy
+
+From: Dominique Martinet <dominique.martinet@atmark-techno.com>
+
+commit 677294e4da96547b9ea2955661a4bbf1d13552a3 upstream.
+
+This is a pre-requisite for the backport of commit 74363ec674cb ("zram:
+fix uninitialized ZRAM not releasing backing device"), which has been
+implemented differently in commit 7ac07a26dea7 ("zram: preparation for
+multi-zcomp support") upstream.
+
+We only need to ensure that zcomp_destroy is not called with a NULL
+comp, so add this check as the other commit cannot be backported easily.
+
+Stable-dep-of: 74363ec674cb ("zram: fix uninitialized ZRAM not releasing backing device")
+Link: https://lore.kernel.org/Z3ytcILx4S1v_ueJ@codewreck.org
+Suggested-by: Kairui Song <kasong@tencent.com>
+Signed-off-by: Dominique Martinet <dominique.martinet@atmark-techno.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/block/zram/zram_drv.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/block/zram/zram_drv.c
++++ b/drivers/block/zram/zram_drv.c
+@@ -1712,7 +1712,8 @@ static void zram_reset_device(struct zra
+       zram_meta_free(zram, zram->disksize);
+       zram->disksize = 0;
+       memset(&zram->stats, 0, sizeof(zram->stats));
+-      zcomp_destroy(zram->comp);
++      if (zram->comp)
++              zcomp_destroy(zram->comp);
+       zram->comp = NULL;
+       reset_bdev(zram);
+ }
diff --git a/queue-5.15/zram-fix-uninitialized-zram-not-releasing-backing-device.patch b/queue-5.15/zram-fix-uninitialized-zram-not-releasing-backing-device.patch
new file mode 100644 (file)
index 0000000..39357e8
--- /dev/null
@@ -0,0 +1,61 @@
+From 74363ec674cb172d8856de25776c8f3103f05e2f Mon Sep 17 00:00:00 2001
+From: Kairui Song <kasong@tencent.com>
+Date: Tue, 10 Dec 2024 00:57:16 +0800
+Subject: zram: fix uninitialized ZRAM not releasing backing device
+
+From: Kairui Song <kasong@tencent.com>
+
+commit 74363ec674cb172d8856de25776c8f3103f05e2f upstream.
+
+Setting backing device is done before ZRAM initialization.  If we set the
+backing device, then remove the ZRAM module without initializing the
+device, the backing device reference will be leaked and the device will be
+hold forever.
+
+Fix this by always reset the ZRAM fully on rmmod or reset store.
+
+Link: https://lkml.kernel.org/r/20241209165717.94215-3-ryncsn@gmail.com
+Fixes: 013bf95a83ec ("zram: add interface to specif backing device")
+Signed-off-by: Kairui Song <kasong@tencent.com>
+Reported-by: Desheng Wu <deshengwu@tencent.com>
+Suggested-by: Sergey Senozhatsky <senozhatsky@chromium.org>
+Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Dominique Martinet <dominique.martinet@atmark-techno.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/block/zram/zram_drv.c |    9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+--- a/drivers/block/zram/zram_drv.c
++++ b/drivers/block/zram/zram_drv.c
+@@ -1150,12 +1150,16 @@ static void zram_meta_free(struct zram *
+       size_t num_pages = disksize >> PAGE_SHIFT;
+       size_t index;
++      if (!zram->table)
++              return;
++
+       /* Free all pages that are still in this zram device */
+       for (index = 0; index < num_pages; index++)
+               zram_free_page(zram, index);
+       zs_destroy_pool(zram->mem_pool);
+       vfree(zram->table);
++      zram->table = NULL;
+ }
+ static bool zram_meta_alloc(struct zram *zram, u64 disksize)
+@@ -1699,11 +1703,6 @@ static void zram_reset_device(struct zra
+       zram->limit_pages = 0;
+-      if (!init_done(zram)) {
+-              up_write(&zram->init_lock);
+-              return;
+-      }
+-
+       set_capacity_and_notify(zram->disk, 0);
+       part_stat_set_all(zram->disk->part0, 0);