[PATCH 1/9] kconfig: fix NULL pointer dereference for defaults taken from choice members

From: lzhan011

Date: Mon Oct 05 2026 - 06:46:35 EST


From: lzhan011 <zhangleizhen645@xxxxxxxxx>

Since commit f79dc03fe68c ("kconfig: refactor choice value calculation"),
sym_calc_choice() marks the members of a choice SYMBOL_VALID but only
sets their curr.tri; curr.val is left NULL. If a string, int or hex
symbol takes its default from such a choice member, sym_calc_value() and
sym_get_string_default() copy ds->curr.val, so the symbol ends up with a
NULL string value. Depending on symbol order this crashes in conf_read()
(strcmp), sym_get_string_default() (str[0]) or ends up writing
CONFIG_X=(null).

Reproducer:

choice
prompt "choice"
config C1
bool "c1"
config C2
bool "c2"
endchoice

config FOO
bool
default C2

config BAR
string
default C1

$ touch .config
$ KCONFIG_CONFIG=.config scripts/kconfig/conf --olddefconfig Kconfig
Segmentation fault

Use sym_get_string_value() instead of reading curr.val directly. It
handles all symbol types and returns "y"/"m"/"n" for tristate and bool
symbols.

The resulting .config and savedefconfig output for defconfig,
allyesconfig, allnoconfig, allmodconfig and randconfig on x86_64, arm64,
riscv, powerpc, s390, arm and mips is unchanged.

Found by fuzzing Kconfig input with ASan/UBSan.

Fixes: f79dc03fe68c ("kconfig: refactor choice value calculation")
Assisted-by: Claude:claude-opus-5-5 ASan UBSan libFuzzer
Signed-off-by: lzhan011 <zhangleizhen645@xxxxxxxxx>
---
scripts/kconfig/symbol.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index dcb4b45e6..de88b13f5 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -546,7 +546,7 @@ void sym_calc_value(struct symbol *sym)
if (ds) {
sym->flags |= SYMBOL_WRITE;
sym_calc_value(ds);
- newval.val = ds->curr.val;
+ newval.val = (char *)sym_get_string_value(ds);
}
}
break;
@@ -887,7 +887,7 @@ const char *sym_get_string_default(struct symbol *sym)
ds = prop_get_symbol(prop);
if (ds != NULL) {
sym_calc_value(ds);
- str = (const char *)ds->curr.val;
+ str = sym_get_string_value(ds);
}
}
}
--
2.34.1