[PATCH] kconfig: fix infinite loop in sym_calc_choice()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Since commit f79dc03fe68c ("kconfig: refactor choice value calculation"),
Kconfig for ARCH=powerpc may result in an infinite loop. This occurs
because there are two entries for POWERPC64_CPU in a choice block.

If the same symbol appears twice in a choice block, the ->choice_link
node is added twice to ->choice_members, resulting a corrupted linked
list.

A simple test case is:

    choice
            prompt "choice"

    config X
            bool "X"

    config A
            bool "A prompt 1"

    config A
            bool "A prompt 2"

    endchoice

Running 'make defconfig' results in an infinite loop.

One solution is to replace the current two entries:

    config POWERPC64_CPU
            bool "Generic (POWER5 and PowerPC 970 and above)"
            depends on PPC_BOOK3S_64 && !CPU_LITTLE_ENDIAN
            select PPC_64S_HASH_MMU

    config POWERPC64_CPU
            bool "Generic (POWER8 and above)"
            depends on PPC_BOOK3S_64 && CPU_LITTLE_ENDIAN
            select ARCH_HAS_FAST_MULTIPLIER
            select PPC_64S_HASH_MMU
            select PPC_HAS_LBARX_LHARX

with the following single entry:

    config POWERPC64_CPU
            bool "Generic 64 bit powerpc"
            depends on PPC_BOOK3S_64
            select ARCH_HAS_FAST_MULTIPLIER if CPU_LITTLE_ENDIAN
            select PPC_64S_HASH_MMU
            select PPC_HAS_LBARX_LHARX if CPU_LITTLE_ENDIAN

In my opinion, the latter looks cleaner, but PowerPC maintainers may
prefer to display different prompts depending on CPU_LITTLE_ENDIAN.

For now, this commit fixes the issue in Kconfig, restoring the original
behavior. I will reconsider whether such a use case is worth supporting.

Fixes: f79dc03fe68c ("kconfig: refactor choice value calculation")
Reported-by: Marco Bonelli <marco@xxxxxxxxxx>
Closes: https://lore.kernel.org/all/1763151587.3581913.1727224126288@xxxxxxxxxxxxxxxx/
Signed-off-by: Masahiro Yamada <masahiroy@xxxxxxxxxx>
---

 scripts/kconfig/parser.y | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y
index 1ad60f9e164e..bc43fb67c7c4 100644
--- a/scripts/kconfig/parser.y
+++ b/scripts/kconfig/parser.y
@@ -159,8 +159,14 @@ config_stmt: config_entry_start config_option_list
 			yynerrs++;
 		}
 
-		list_add_tail(&current_entry->sym->choice_link,
-			      &current_choice->choice_members);
+		/*
+		 * If the same symbol appears twice in a choice block, the list
+		 * node would be added twice, leading to a broken linked list.
+		 * list_empty() ensures that this symbol has not yet added.
+		 */
+		if (list_empty(&current_entry->sym->choice_link))
+			list_add_tail(&current_entry->sym->choice_link,
+				      &current_choice->choice_members);
 	}
 
 	printd(DEBUG_PARSE, "%s:%d:endconfig\n", cur_filename, cur_lineno);
-- 
2.43.0





[Index of Archives]     [Linux&nblp;USB Development]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite Secrets]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux