Skip to content

Commit 0902b3c

Browse files
committed
kconfig: Avoid prompting for transitional symbols
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: f9afce4 ("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>
1 parent fd94619 commit 0902b3c

6 files changed

Lines changed: 61 additions & 1 deletion

File tree

scripts/kconfig/symbol.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ bool sym_dep_errors(void)
411411
void sym_calc_value(struct symbol *sym)
412412
{
413413
struct symbol_value newval, oldval;
414-
struct property *prop;
414+
struct property *prop = NULL;
415415
struct menu *choice_menu;
416416

417417
if (!sym)
@@ -520,6 +520,19 @@ void sym_calc_value(struct symbol *sym)
520520
;
521521
}
522522

523+
/*
524+
* If the symbol lacks a user value but its value comes from a
525+
* single transitional symbol with an existing user value, mark
526+
* this symbol as having a user value to avoid prompting.
527+
*/
528+
if (prop && !sym_has_value(sym)) {
529+
struct symbol *ds = prop_get_symbol(prop);
530+
if (ds && (ds->flags & SYMBOL_TRANS) && sym_has_value(ds)) {
531+
sym->def[S_DEF_USER] = newval;
532+
sym->flags |= SYMBOL_DEF_USER;
533+
}
534+
}
535+
523536
sym->curr = newval;
524537
sym_validate_range(sym);
525538

scripts/kconfig/tests/transitional/Kconfig

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,5 +96,37 @@ config OLD_WITH_HELP
9696
help
9797
This transitional symbol has a help section to validate that help is allowed.
9898

99+
# Test that we can set something to =n via transitional symbol
100+
config NEW_DISABLED
101+
tristate "Check for setting to disabled"
102+
default OLD_DISABLED
103+
104+
config OLD_DISABLED
105+
tristate
106+
transitional
107+
108+
# Test that a potential new value disappears if it lacks a prompt
109+
config NEW_DISABLED_UNSAVED
110+
tristate
111+
default OLD_DISABLED
112+
113+
config OLD_DISABLED_UNSAVED
114+
tristate
115+
transitional
116+
117+
# Test conditional default: transitional value should not prevent prompting
118+
# when default visibility makes the expression evaluate to 'no'
119+
config DEPENDENCY_TEST
120+
bool "Dependency for testing"
121+
default n
122+
123+
config NEW_CONDITIONAL_DEFAULT
124+
bool "New option with conditional default"
125+
default OLD_CONDITIONAL_DEFAULT if DEPENDENCY_TEST
126+
127+
config OLD_CONDITIONAL_DEFAULT
128+
bool
129+
transitional
130+
99131
config REGULAR_OPTION
100132
bool "Regular option"

scripts/kconfig/tests/transitional/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
- OLD_* options in existing .config cause NEW_* options to be set
77
- OLD_* options are not written to the new .config file
88
- NEW_* options appear in the new .config file with correct values
9+
- NEW_* options with defaults from transitional symbols are not prompted
910
- All Kconfig types work correctly: bool, tristate, string, hex, int
1011
- User-set NEW values take precedence over conflicting OLD transitional values
1112
"""
@@ -16,3 +17,9 @@ def test(conf):
1617

1718
# Check that the configuration matches expected output
1819
assert conf.config_contains('expected_config')
20+
21+
# Test oldconfig to ensure symbols with transitional defaults are not prompted
22+
assert conf.oldconfig(dot_config='initial_config', in_keys='n\n') == 0
23+
24+
# Except for when conditional default evaluates to 'no'
25+
assert conf.stdout_contains('expected_stdout')

scripts/kconfig/tests/transitional/expected_config

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,7 @@ CONFIG_NEW_STRING_PRECEDENCE="user value"
99
CONFIG_NEW_TRISTATE_PRECEDENCE=y
1010
CONFIG_NEW_HEX_PRECEDENCE=0xABCD
1111
CONFIG_NEW_INT_PRECEDENCE=100
12+
# CONFIG_NEW_DISABLED is not set
13+
# CONFIG_DEPENDENCY_TEST is not set
14+
# CONFIG_NEW_CONDITIONAL_DEFAULT is not set
1215
# CONFIG_REGULAR_OPTION is not set
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
New option with conditional default (NEW_CONDITIONAL_DEFAULT) [N/y/?] (NEW) n

scripts/kconfig/tests/transitional/initial_config

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,7 @@ CONFIG_NEW_HEX_PRECEDENCE=0xABCD
1414
CONFIG_OLD_HEX_PRECEDENCE=0x5678
1515
CONFIG_NEW_INT_PRECEDENCE=100
1616
CONFIG_OLD_INT_PRECEDENCE=200
17+
# CONFIG_OLD_DISABLED is not set
18+
# CONFIG_OLD_DISABLED_UNSAVED is not set
19+
# CONFIG_DEPENDENCY_TEST is not set
20+
CONFIG_OLD_CONDITIONAL_DEFAULT=y

0 commit comments

Comments
 (0)