]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
kconfig: Avoid prompting for transitional symbols
authorKees Cook <kees@kernel.org>
Tue, 30 Sep 2025 15:45:19 +0000 (08:45 -0700)
committerKees Cook <kees@kernel.org>
Tue, 7 Oct 2025 15:21:23 +0000 (08:21 -0700)
The "transitional" symbol keyword, while working with the "olddefconfig"
target, was prompting during "oldconfig". This occurred because these
symbols were not being marked as user-defined when they received values
from transitional symbols that had user values. The "olddefconfig" target
explicitly doesn't prompt for anything, so this deficiency wasn't noticed.

The issue manifested when a symbol's value came from a transitional
symbol's user value but the receiving symbol wasn't marked with
SYMBOL_DEF_USER. Thus the "oldconfig" logic would then prompt for these
symbols unnecessarily.

Check after value calculation whether a symbol without a user value
gets its value from a single transitional symbol that does have a user
value. In such cases, mark the receiving symbol as user-defined to
prevent prompting.

Update regression tests to verify that symbols with transitional defaults
are not prompted in "oldconfig", except when conditional defaults evaluate
to 'no' and should legitimately be prompted.

Build tested with "make testconfig".

Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
Closes: https://lore.kernel.org/lkml/CAHk-=wgZjUk4Cy2XgNkTrQoO8XCmNUHrTe5D519Fij1POK+3qw@mail.gmail.com/
Fixes: f9afce4f32e9 ("kconfig: Add transitional symbol attribute for migration support")
Cc: Vegard Nossum <vegard.nossum@oracle.com>
Link: https://lore.kernel.org/r/20250930154514.it.623-kees@kernel.org
Signed-off-by: Kees Cook <kees@kernel.org>
scripts/kconfig/symbol.c
scripts/kconfig/tests/transitional/Kconfig
scripts/kconfig/tests/transitional/__init__.py
scripts/kconfig/tests/transitional/expected_config
scripts/kconfig/tests/transitional/expected_stdout [new file with mode: 0644]
scripts/kconfig/tests/transitional/initial_config

index 760cac998381964efee0fc892bfcd8cea545f872..7e81b3676ee9449e93ce3e41a226484e7ca8c5a4 100644 (file)
@@ -411,7 +411,7 @@ bool sym_dep_errors(void)
 void sym_calc_value(struct symbol *sym)
 {
        struct symbol_value newval, oldval;
-       struct property *prop;
+       struct property *prop = NULL;
        struct menu *choice_menu;
 
        if (!sym)
@@ -520,6 +520,19 @@ void sym_calc_value(struct symbol *sym)
                ;
        }
 
+       /*
+        * If the symbol lacks a user value but its value comes from a
+        * single transitional symbol with an existing user value, mark
+        * this symbol as having a user value to avoid prompting.
+        */
+       if (prop && !sym_has_value(sym)) {
+               struct symbol *ds = prop_get_symbol(prop);
+               if (ds && (ds->flags & SYMBOL_TRANS) && sym_has_value(ds)) {
+                       sym->def[S_DEF_USER] = newval;
+                       sym->flags |= SYMBOL_DEF_USER;
+               }
+       }
+
        sym->curr = newval;
        sym_validate_range(sym);
 
index 62c3b24665b99245bbcb82dab787a586a9ecb319..faa4d396f82821733f67413bee7751f519842c0d 100644 (file)
@@ -96,5 +96,37 @@ config OLD_WITH_HELP
        help
          This transitional symbol has a help section to validate that help is allowed.
 
+# Test that we can set something to =n via transitional symbol
+config NEW_DISABLED
+       tristate "Check for setting to disabled"
+       default OLD_DISABLED
+
+config OLD_DISABLED
+       tristate
+       transitional
+
+# Test that a potential new value disappears if it lacks a prompt
+config NEW_DISABLED_UNSAVED
+       tristate
+       default OLD_DISABLED
+
+config OLD_DISABLED_UNSAVED
+       tristate
+       transitional
+
+# Test conditional default: transitional value should not prevent prompting
+# when default visibility makes the expression evaluate to 'no'
+config DEPENDENCY_TEST
+       bool "Dependency for testing"
+       default n
+
+config NEW_CONDITIONAL_DEFAULT
+       bool "New option with conditional default"
+       default OLD_CONDITIONAL_DEFAULT if DEPENDENCY_TEST
+
+config OLD_CONDITIONAL_DEFAULT
+       bool
+       transitional
+
 config REGULAR_OPTION
        bool "Regular option"
index 61937d10edf1ee40adf179a893429c07fbb6406e..b50ba239754850eba1412b14755ad92e7b8ccb33 100644 (file)
@@ -6,6 +6,7 @@ This tests that:
 - OLD_* options in existing .config cause NEW_* options to be set
 - OLD_* options are not written to the new .config file
 - NEW_* options appear in the new .config file with correct values
+- NEW_* options with defaults from transitional symbols are not prompted
 - All Kconfig types work correctly: bool, tristate, string, hex, int
 - User-set NEW values take precedence over conflicting OLD transitional values
 """
@@ -16,3 +17,9 @@ def test(conf):
 
     # Check that the configuration matches expected output
     assert conf.config_contains('expected_config')
+
+    # Test oldconfig to ensure symbols with transitional defaults are not prompted
+    assert conf.oldconfig(dot_config='initial_config', in_keys='n\n') == 0
+
+    # Except for when conditional default evaluates to 'no'
+    assert conf.stdout_contains('expected_stdout')
index 846e9ddcab9103991fbabc2ab1e08606e6bc365a..e01f5f070a262b0e00dc9214203ab99e73def305 100644 (file)
@@ -9,4 +9,7 @@ CONFIG_NEW_STRING_PRECEDENCE="user value"
 CONFIG_NEW_TRISTATE_PRECEDENCE=y
 CONFIG_NEW_HEX_PRECEDENCE=0xABCD
 CONFIG_NEW_INT_PRECEDENCE=100
+# CONFIG_NEW_DISABLED is not set
+# CONFIG_DEPENDENCY_TEST is not set
+# CONFIG_NEW_CONDITIONAL_DEFAULT is not set
 # CONFIG_REGULAR_OPTION is not set
diff --git a/scripts/kconfig/tests/transitional/expected_stdout b/scripts/kconfig/tests/transitional/expected_stdout
new file mode 100644 (file)
index 0000000..6f0b285
--- /dev/null
@@ -0,0 +1 @@
+New option with conditional default (NEW_CONDITIONAL_DEFAULT) [N/y/?] (NEW) n
index e648a65e504c0852179949cdbd306ce2dff23f69..68b7da672426ce381a62737152c6cfc81afbf5fd 100644 (file)
@@ -14,3 +14,7 @@ CONFIG_NEW_HEX_PRECEDENCE=0xABCD
 CONFIG_OLD_HEX_PRECEDENCE=0x5678
 CONFIG_NEW_INT_PRECEDENCE=100
 CONFIG_OLD_INT_PRECEDENCE=200
+# CONFIG_OLD_DISABLED is not set
+# CONFIG_OLD_DISABLED_UNSAVED is not set
+# CONFIG_DEPENDENCY_TEST is not set
+CONFIG_OLD_CONDITIONAL_DEFAULT=y