]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 12 Jan 2025 12:35:59 +0000 (13:35 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 12 Jan 2025 12:35:59 +0000 (13:35 +0100)
added patches:
md-raid5-fix-atomicity-violation-in-raid5_cache_count.patch
scripts-sorttable-fix-orc_sort_cmp-to-maintain-symmetry-and-transitivity.patch

queue-5.10/md-raid5-fix-atomicity-violation-in-raid5_cache_count.patch [new file with mode: 0644]
queue-5.10/scripts-sorttable-fix-orc_sort_cmp-to-maintain-symmetry-and-transitivity.patch [new file with mode: 0644]
queue-5.10/series

diff --git a/queue-5.10/md-raid5-fix-atomicity-violation-in-raid5_cache_count.patch b/queue-5.10/md-raid5-fix-atomicity-violation-in-raid5_cache_count.patch
new file mode 100644 (file)
index 0000000..f84cc5c
--- /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;
+ }
+@@ -6575,7 +6575,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))
+@@ -6587,7 +6587,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;
+               }
+@@ -7151,11 +7151,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.10/scripts-sorttable-fix-orc_sort_cmp-to-maintain-symmetry-and-transitivity.patch b/queue-5.10/scripts-sorttable-fix-orc_sort_cmp-to-maintain-symmetry-and-transitivity.patch
new file mode 100644 (file)
index 0000000..2c2b4ea
--- /dev/null
@@ -0,0 +1,68 @@
+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 |   10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+--- 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);
+@@ -120,8 +120,12 @@ static int orc_sort_cmp(const void *_a,
+        * These terminator entries exist to handle any gaps created by
+        * whitelisted .o files which didn't get objtool generation.
+        */
+-      orc_a = g_orc_table + (a - g_orc_ip_table);
+-      return orc_a->sp_reg == ORC_REG_UNDEFINED && !orc_a->end ? -1 : 1;
++      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;
+ }
+ static void *sort_orctable(void *arg)
index 78ee7d672e07fd11031640ca324c07e2394ab085..273276439c6caf11cd22781792f8312daa3240c3 100644 (file)
@@ -26,3 +26,5 @@ 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
+scripts-sorttable-fix-orc_sort_cmp-to-maintain-symmetry-and-transitivity.patch
+md-raid5-fix-atomicity-violation-in-raid5_cache_count.patch