From: Sasha Levin Date: Mon, 3 Feb 2025 16:25:51 +0000 (-0500) Subject: Fixes for 5.10 X-Git-Tag: v6.6.76~53 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=03b16c133bad13c30e62b5323994e24254f2d0b5;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.10 Signed-off-by: Sasha Levin --- diff --git a/queue-5.10/genksyms-fix-memory-leak-when-the-same-symbol-is-add.patch b/queue-5.10/genksyms-fix-memory-leak-when-the-same-symbol-is-add.patch new file mode 100644 index 0000000000..fd0ca8e22f --- /dev/null +++ b/queue-5.10/genksyms-fix-memory-leak-when-the-same-symbol-is-add.patch @@ -0,0 +1,149 @@ +From ae0d97c94282b8ba26a8442ad6392d2511876c00 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Jan 2025 16:30:38 +0900 +Subject: genksyms: fix memory leak when the same symbol is added from source + +From: Masahiro Yamada + +[ Upstream commit 45c9c4101d3d2fdfa00852274bbebba65fcc3cf2 ] + +When a symbol that is already registered is added again, __add_symbol() +returns without freeing the symbol definition, making it unreachable. + +The following test cases demonstrate different memory leak points. + +[Test Case 1] + +Forward declaration with exactly the same definition + + $ cat foo.c + #include + void foo(void); + void foo(void) {} + EXPORT_SYMBOL(foo); + +[Test Case 2] + +Forward declaration with a different definition (e.g. attribute) + + $ cat foo.c + #include + void foo(void); + __attribute__((__section__(".ref.text"))) void foo(void) {} + EXPORT_SYMBOL(foo); + +[Test Case 3] + +Preserving an overridden symbol (compile with KBUILD_PRESERVE=1) + + $ cat foo.c + #include + void foo(void); + void foo(void) { } + EXPORT_SYMBOL(foo); + + $ cat foo.symref + override foo void foo ( int ) + +The memory leaks in Test Case 1 and 2 have existed since the introduction +of genksyms into the kernel tree. [1] + +The memory leak in Test Case 3 was introduced by commit 5dae9a550a74 +("genksyms: allow to ignore symbol checksum changes"). + +When multiple init_declarators are reduced to an init_declarator_list, +the decl_spec must be duplicated. Otherwise, the following Test Case 4 +would result in a double-free bug. + +[Test Case 4] + + $ cat foo.c + #include + + extern int foo, bar; + + int foo, bar; + EXPORT_SYMBOL(foo); + +In this case, 'foo' and 'bar' share the same decl_spec, 'int'. It must +be unshared before being passed to add_symbol(). + +[1]: https://git.kernel.org/pub/scm/linux/kernel/git/history/history.git/commit/?id=46bd1da672d66ccd8a639d3c1f8a166048cca608 + +Fixes: 5dae9a550a74 ("genksyms: allow to ignore symbol checksum changes") +Signed-off-by: Masahiro Yamada +Signed-off-by: Sasha Levin +--- + scripts/genksyms/genksyms.c | 3 +++ + scripts/genksyms/parse.y | 14 ++++++++++++-- + 2 files changed, 15 insertions(+), 2 deletions(-) + +diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c +index 23eff234184f3..d74bad87ef1a7 100644 +--- a/scripts/genksyms/genksyms.c ++++ b/scripts/genksyms/genksyms.c +@@ -241,6 +241,7 @@ static struct symbol *__add_symbol(const char *name, enum symbol_type type, + "unchanged\n"); + } + sym->is_declared = 1; ++ free_list(defn, NULL); + return sym; + } else if (!sym->is_declared) { + if (sym->is_override && flag_preserve) { +@@ -249,6 +250,7 @@ static struct symbol *__add_symbol(const char *name, enum symbol_type type, + print_type_name(type, name); + fprintf(stderr, " modversion change\n"); + sym->is_declared = 1; ++ free_list(defn, NULL); + return sym; + } else { + status = is_unknown_symbol(sym) ? +@@ -256,6 +258,7 @@ static struct symbol *__add_symbol(const char *name, enum symbol_type type, + } + } else { + error_with_pos("redefinition of %s", name); ++ free_list(defn, NULL); + return sym; + } + break; +diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y +index e22b42245bcc2..7df3fe290d535 100644 +--- a/scripts/genksyms/parse.y ++++ b/scripts/genksyms/parse.y +@@ -149,14 +149,19 @@ simple_declaration: + ; + + init_declarator_list_opt: +- /* empty */ { $$ = NULL; } +- | init_declarator_list ++ /* empty */ { $$ = NULL; } ++ | init_declarator_list { free_list(decl_spec, NULL); $$ = $1; } + ; + + init_declarator_list: + init_declarator + { struct string_list *decl = *$1; + *$1 = NULL; ++ ++ /* avoid sharing among multiple init_declarators */ ++ if (decl_spec) ++ decl_spec = copy_list_range(decl_spec, NULL); ++ + add_symbol(current_name, + is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern); + current_name = NULL; +@@ -167,6 +172,11 @@ init_declarator_list: + *$3 = NULL; + free_list(*$2, NULL); + *$2 = decl_spec; ++ ++ /* avoid sharing among multiple init_declarators */ ++ if (decl_spec) ++ decl_spec = copy_list_range(decl_spec, NULL); ++ + add_symbol(current_name, + is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern); + current_name = NULL; +-- +2.39.5 + diff --git a/queue-5.10/genksyms-fix-memory-leak-when-the-same-symbol-is-rea.patch b/queue-5.10/genksyms-fix-memory-leak-when-the-same-symbol-is-rea.patch new file mode 100644 index 0000000000..d984141feb --- /dev/null +++ b/queue-5.10/genksyms-fix-memory-leak-when-the-same-symbol-is-rea.patch @@ -0,0 +1,108 @@ +From e53d587b7ace881bcbcba3a5785550dbf48f89fd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Jan 2025 16:30:39 +0900 +Subject: genksyms: fix memory leak when the same symbol is read from *.symref + file + +From: Masahiro Yamada + +[ Upstream commit be2fa44b5180a1f021efb40c55fdf63c249c3209 ] + +When a symbol that is already registered is read again from *.symref +file, __add_symbol() removes the previous one from the hash table without +freeing it. + +[Test Case] + + $ cat foo.c + #include + void foo(void); + void foo(void) {} + EXPORT_SYMBOL(foo); + + $ cat foo.symref + foo void foo ( void ) + foo void foo ( void ) + +When a symbol is removed from the hash table, it must be freed along +with its ->name and ->defn members. However, sym->name cannot be freed +because it is sometimes shared with node->string, but not always. If +sym->name and node->string share the same memory, free(sym->name) could +lead to a double-free bug. + +To resolve this issue, always assign a strdup'ed string to sym->name. + +Fixes: 64e6c1e12372 ("genksyms: track symbol checksum changes") +Signed-off-by: Masahiro Yamada +Signed-off-by: Sasha Levin +--- + scripts/genksyms/genksyms.c | 8 ++++++-- + scripts/genksyms/genksyms.h | 2 +- + scripts/genksyms/parse.y | 4 ++-- + 3 files changed, 9 insertions(+), 5 deletions(-) + +diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c +index d74bad87ef1a7..a87fafbbec268 100644 +--- a/scripts/genksyms/genksyms.c ++++ b/scripts/genksyms/genksyms.c +@@ -274,11 +274,15 @@ static struct symbol *__add_symbol(const char *name, enum symbol_type type, + break; + } + } ++ ++ free_list(sym->defn, NULL); ++ free(sym->name); ++ free(sym); + --nsyms; + } + + sym = xmalloc(sizeof(*sym)); +- sym->name = name; ++ sym->name = xstrdup(name); + sym->type = type; + sym->defn = defn; + sym->expansion_trail = NULL; +@@ -485,7 +489,7 @@ static void read_reference(FILE *f) + defn = def; + def = read_node(f); + } +- subsym = add_reference_symbol(xstrdup(sym->string), sym->tag, ++ subsym = add_reference_symbol(sym->string, sym->tag, + defn, is_extern); + subsym->is_override = is_override; + free_node(sym); +diff --git a/scripts/genksyms/genksyms.h b/scripts/genksyms/genksyms.h +index 2bcdb9bebab40..4ead4e0adb821 100644 +--- a/scripts/genksyms/genksyms.h ++++ b/scripts/genksyms/genksyms.h +@@ -32,7 +32,7 @@ struct string_list { + + struct symbol { + struct symbol *hash_next; +- const char *name; ++ char *name; + enum symbol_type type; + struct string_list *defn; + struct symbol *expansion_trail; +diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y +index 7df3fe290d535..84813ce54a2dd 100644 +--- a/scripts/genksyms/parse.y ++++ b/scripts/genksyms/parse.y +@@ -479,12 +479,12 @@ enumerator_list: + enumerator: + IDENT + { +- const char *name = strdup((*$1)->string); ++ const char *name = (*$1)->string; + add_symbol(name, SYM_ENUM_CONST, NULL, 0); + } + | IDENT '=' EXPRESSION_PHRASE + { +- const char *name = strdup((*$1)->string); ++ const char *name = (*$1)->string; + struct string_list *expr = copy_list_range(*$3, *$2); + add_symbol(name, SYM_ENUM_CONST, expr, 0); + } +-- +2.39.5 + diff --git a/queue-5.10/hexagon-fix-unbalanced-spinlock-in-die.patch b/queue-5.10/hexagon-fix-unbalanced-spinlock-in-die.patch new file mode 100644 index 0000000000..43e64e307f --- /dev/null +++ b/queue-5.10/hexagon-fix-unbalanced-spinlock-in-die.patch @@ -0,0 +1,45 @@ +From 89022055c0f8767abdd0e5736fea7f28231be532 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 May 2023 02:56:08 +0000 +Subject: hexagon: Fix unbalanced spinlock in die() + +From: Lin Yujun + +[ Upstream commit 03410e87563a122075c3721acc7d5510e41d8332 ] + +die executes holding the spinlock of &die.lock and unlock +it after printing the oops message. +However in the code if the notify_die() returns NOTIFY_STOP +, die() exit with returning 1 but never unlocked the spinlock. + +Fix this by adding spin_unlock_irq(&die.lock) before returning. + +Fixes: cf9750bae262 ("Hexagon: Provide basic debugging and system trap support.") +Signed-off-by: Lin Yujun +Link: https://lore.kernel.org/r/20230522025608.2515558-1-linyujun809@huawei.com +Signed-off-by: Brian Cain +Signed-off-by: Brian Cain +Signed-off-by: Sasha Levin +--- + arch/hexagon/kernel/traps.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/arch/hexagon/kernel/traps.c b/arch/hexagon/kernel/traps.c +index b334e80717099..653328606ef31 100644 +--- a/arch/hexagon/kernel/traps.c ++++ b/arch/hexagon/kernel/traps.c +@@ -199,8 +199,10 @@ int die(const char *str, struct pt_regs *regs, long err) + printk(KERN_EMERG "Oops: %s[#%d]:\n", str, ++die.counter); + + if (notify_die(DIE_OOPS, str, regs, err, pt_cause(regs), SIGSEGV) == +- NOTIFY_STOP) ++ NOTIFY_STOP) { ++ spin_unlock_irq(&die.lock); + return 1; ++ } + + print_modules(); + show_regs(regs); +-- +2.39.5 + diff --git a/queue-5.10/hexagon-fix-using-plain-integer-as-null-pointer-warn.patch b/queue-5.10/hexagon-fix-using-plain-integer-as-null-pointer-warn.patch new file mode 100644 index 0000000000..f842fb801e --- /dev/null +++ b/queue-5.10/hexagon-fix-using-plain-integer-as-null-pointer-warn.patch @@ -0,0 +1,61 @@ +From 4f57b80b5bb933f948feace23e048ad46c39dc83 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Dec 2024 17:17:34 -0500 +Subject: hexagon: fix using plain integer as NULL pointer warning in cmpxchg + +From: Willem de Bruijn + +[ Upstream commit 8a20030038742b9915c6d811a4e6c14b126cafb4 ] + +Sparse reports + + net/ipv4/inet_diag.c:1511:17: sparse: sparse: Using plain integer as NULL pointer + +Due to this code calling cmpxchg on a non-integer type +struct inet_diag_handler * + + return !cmpxchg((const struct inet_diag_handler**)&inet_diag_table[type], + NULL, h) ? 0 : -EEXIST; + +While hexagon's cmpxchg assigns an integer value to a variable of this +type. + + __typeof__(*(ptr)) __oldval = 0; + +Update this assignment to cast 0 to the correct type. + +The original issue is easily reproduced at head with the below block, +and is absent after this change. + + make LLVM=1 ARCH=hexagon defconfig + make C=1 LLVM=1 ARCH=hexagon net/ipv4/inet_diag.o + +Fixes: 99a70aa051d2 ("Hexagon: Add processor and system headers") +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202411091538.PGSTqUBi-lkp@intel.com/ +Signed-off-by: Willem de Bruijn +Tested-by: Christian Gmeiner +Link: https://lore.kernel.org/r/20241203221736.282020-1-willemdebruijn.kernel@gmail.com +Signed-off-by: Brian Cain +Signed-off-by: Brian Cain +Signed-off-by: Sasha Levin +--- + arch/hexagon/include/asm/cmpxchg.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/hexagon/include/asm/cmpxchg.h b/arch/hexagon/include/asm/cmpxchg.h +index 92b8a02e588ac..9c5f07749933e 100644 +--- a/arch/hexagon/include/asm/cmpxchg.h ++++ b/arch/hexagon/include/asm/cmpxchg.h +@@ -56,7 +56,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, + __typeof__(ptr) __ptr = (ptr); \ + __typeof__(*(ptr)) __old = (old); \ + __typeof__(*(ptr)) __new = (new); \ +- __typeof__(*(ptr)) __oldval = 0; \ ++ __typeof__(*(ptr)) __oldval = (__typeof__(*(ptr))) 0; \ + \ + asm volatile( \ + "1: %0 = memw_locked(%1);\n" \ +-- +2.39.5 + diff --git a/queue-5.10/series b/queue-5.10/series index d4295c0d5c..6e8cec81bb 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -123,3 +123,7 @@ vsock-allow-retrying-on-connect-failure.patch bgmac-reduce-max-frame-size-to-support-just-mtu-1500.patch net-sh_eth-fix-missing-rtnl-lock-in-suspend-resume-p.patch net-hsr-fix-fill_frame_info-regression-vs-vlan-packe.patch +genksyms-fix-memory-leak-when-the-same-symbol-is-add.patch +genksyms-fix-memory-leak-when-the-same-symbol-is-rea.patch +hexagon-fix-using-plain-integer-as-null-pointer-warn.patch +hexagon-fix-unbalanced-spinlock-in-die.patch