diff options
| author | Julian Braha <julianbraha@gmail.com> | 2026-09-15 22:15:07 +0100 |
|---|---|---|
| committer | Nathan Chancellor <nathan@kernel.org> | 2026-09-17 16:31:00 -0700 |
| commit | 54f11924e4854177b357af499ebc447dc8c3c590 (patch) | |
| tree | 6ea314db8eff33127e6a2826ad2b31f5cc6d7f74 /scripts | |
| parent | d13bad83d89d1022fee254c08f6e01084eb4395e (diff) | |
kconfig: prevent out-of-bounds user input for numeric options
Currently, user input of out-of-bounds values for 'int' and 'hex' options
is possible, leading to later silent failures in Kconfig if that value is
used in a comparison, or a warning by GCC or error by Clang if used in the
C code.
Let's factor out the out-of-bounds check on constants, so that it can be
reused for checking user input.
The frontend will now reject an attempted user input of an out-of-bounds
numeric value, similarly to how a value outside the active 'range' already
does.
For migration of existing configurations, a .config file with an
out-of-bounds numeric value will be allowed for now, but will warn the
user when read in by confdata.c
Assisted-by: LLM
Signed-off-by: Julian Braha <julianbraha@gmail.com>
Reviewed-by: Nicolas Schier <n.schier@fritz.com>
Link: https://patch.msgid.link/20260915211508.291790-5-julianbraha@gmail.com
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/kconfig/confdata.c | 6 | ||||
| -rw-r--r-- | scripts/kconfig/lkc_proto.h | 1 | ||||
| -rw-r--r-- | scripts/kconfig/menu.c | 19 | ||||
| -rw-r--r-- | scripts/kconfig/symbol.c | 20 | ||||
| -rw-r--r-- | scripts/kconfig/tests/err_num_bounds/expected_stderr | 20 | ||||
| -rw-r--r-- | scripts/kconfig/tests/warn_num_bounds/Kconfig | 24 | ||||
| -rw-r--r-- | scripts/kconfig/tests/warn_num_bounds/__init__.py | 25 | ||||
| -rw-r--r-- | scripts/kconfig/tests/warn_num_bounds/config | 7 | ||||
| -rw-r--r-- | scripts/kconfig/tests/warn_num_bounds/expected_config | 11 | ||||
| -rw-r--r-- | scripts/kconfig/tests/warn_num_bounds/expected_config_stderr | 3 | ||||
| -rw-r--r-- | scripts/kconfig/tests/warn_num_bounds/expected_frontend_config | 11 | ||||
| -rw-r--r-- | scripts/kconfig/tests/warn_num_bounds/expected_frontend_stderr | 0 |
12 files changed, 121 insertions, 26 deletions
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 4234a51d16fd..2227d89d6328 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -354,6 +354,12 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) case S_INT: case S_HEX: if (sym_string_valid(sym, p)) { + if (def != S_DEF_AUTO && + !sym_string_check_bounds(sym, p)) + /* hex uses 64-bit unsigned integer */ + conf_warning("value '%s' for %s is outside the 64-bit %s integer bounds", + p, sym->name, + sym->type == S_INT ? "signed" : "unsigned"); sym->def[def].val = xstrdup(p); sym->flags |= def_flags; } else { diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index 8914b4e8f2a8..8b436c87ba4a 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h @@ -31,6 +31,7 @@ bool sym_set_tristate_value(struct symbol *sym,tristate tri); void choice_set_value(struct menu *choice, struct symbol *sym); tristate sym_toggle_tristate_value(struct symbol *sym); bool sym_string_valid(struct symbol *sym, const char *newval); +bool sym_string_check_bounds(struct symbol *sym, const char *str); bool sym_string_within_range(struct symbol *sym, const char *str); bool sym_set_string_value(struct symbol *sym, const char *newval); bool sym_is_changeable(const struct symbol *sym); diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 2d8b0c65ce1e..6b9ef738ee71 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -4,7 +4,6 @@ */ #include <ctype.h> -#include <errno.h> #include <stdarg.h> #include <stdlib.h> #include <string.h> @@ -239,8 +238,6 @@ void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep) static int menu_validate_number(struct symbol *sym, struct symbol *sym2, const struct property *prop) { - const char *type_bounds; - if (sym->type != S_INT && sym->type != S_HEX) return 0; @@ -255,21 +252,11 @@ static int menu_validate_number(struct symbol *sym, struct symbol *sym2, return 1; } - errno = 0; - if (sym->type == S_INT) { - type_bounds = "64-bit signed integer"; - strtoll(sym2->name, NULL, 10); - } else { - /* hex */ - type_bounds = "64-bit unsigned integer"; - strtoull(sym2->name, NULL, 16); - } - - if (errno == ERANGE) { + if (!sym_string_check_bounds(sym, sym2->name)) { fprintf(stderr, - "%s:%d: error: %s constant '%s' is outside the %s bounds\n", + "%s:%d: error: %s constant '%s' is outside the 64-bit %s bounds\n", prop->filename, prop->lineno, sym_type_name(sym->type), - sym2->name, type_bounds); + sym2->name, sym->type == S_INT ? "signed" : "unsigned"); return 1; } diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 01aa58d92c3b..8ccd9e7e2cf0 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -5,6 +5,7 @@ #include <sys/types.h> #include <ctype.h> +#include <errno.h> #include <stdlib.h> #include <string.h> #include <regex.h> @@ -726,6 +727,21 @@ bool sym_string_valid(struct symbol *sym, const char *str) } } +bool sym_string_check_bounds(struct symbol *sym, const char *str) +{ + errno = 0; + + if (sym->type == S_INT) + strtoll(str, NULL, 10); + else if (sym->type == S_HEX) + strtoull(str, NULL, 16); + else + /* string */ + return true; + + return errno != ERANGE; +} + bool sym_string_within_range(struct symbol *sym, const char *str) { struct property *prop; @@ -737,6 +753,8 @@ bool sym_string_within_range(struct symbol *sym, const char *str) case S_INT: if (!sym_string_valid(sym, str)) return false; + if (!sym_string_check_bounds(sym, str)) + return false; prop = sym_get_range_prop(sym); if (!prop) return true; @@ -746,6 +764,8 @@ bool sym_string_within_range(struct symbol *sym, const char *str) case S_HEX: if (!sym_string_valid(sym, str)) return false; + if (!sym_string_check_bounds(sym, str)) + return false; prop = sym_get_range_prop(sym); if (!prop) return true; diff --git a/scripts/kconfig/tests/err_num_bounds/expected_stderr b/scripts/kconfig/tests/err_num_bounds/expected_stderr index 3f06e13359ef..5f89cf4afff8 100644 --- a/scripts/kconfig/tests/err_num_bounds/expected_stderr +++ b/scripts/kconfig/tests/err_num_bounds/expected_stderr @@ -1,10 +1,10 @@ -Kconfig:51: error: integer constant '10000000000000000000' is outside the 64-bit signed integer bounds -Kconfig:55: error: integer constant '-9223372036854775809' is outside the 64-bit signed integer bounds -Kconfig:59: error: integer constant '10000000000000000000' is outside the 64-bit signed integer bounds -Kconfig:63: error: integer constant '-10000000000000000000' is outside the 64-bit signed integer bounds -Kconfig:67: error: integer constant '-9223372036854775809' is outside the 64-bit signed integer bounds -Kconfig:67: error: integer constant '10000000000000000000' is outside the 64-bit signed integer bounds -Kconfig:71: error: hex constant '0x10000000000000000' is outside the 64-bit unsigned integer bounds -Kconfig:75: error: hex constant '0x10000000000000000' is outside the 64-bit unsigned integer bounds -Kconfig:79: error: hex constant '0x10000000000000000' is outside the 64-bit unsigned integer bounds -Kconfig:79: error: hex constant '0x20000000000000000' is outside the 64-bit unsigned integer bounds +Kconfig:51: error: integer constant '10000000000000000000' is outside the 64-bit signed bounds +Kconfig:55: error: integer constant '-9223372036854775809' is outside the 64-bit signed bounds +Kconfig:59: error: integer constant '10000000000000000000' is outside the 64-bit signed bounds +Kconfig:63: error: integer constant '-10000000000000000000' is outside the 64-bit signed bounds +Kconfig:67: error: integer constant '-9223372036854775809' is outside the 64-bit signed bounds +Kconfig:67: error: integer constant '10000000000000000000' is outside the 64-bit signed bounds +Kconfig:71: error: hex constant '0x10000000000000000' is outside the 64-bit unsigned bounds +Kconfig:75: error: hex constant '0x10000000000000000' is outside the 64-bit unsigned bounds +Kconfig:79: error: hex constant '0x10000000000000000' is outside the 64-bit unsigned bounds +Kconfig:79: error: hex constant '0x20000000000000000' is outside the 64-bit unsigned bounds diff --git a/scripts/kconfig/tests/warn_num_bounds/Kconfig b/scripts/kconfig/tests/warn_num_bounds/Kconfig new file mode 100644 index 000000000000..a810225a58a3 --- /dev/null +++ b/scripts/kconfig/tests/warn_num_bounds/Kconfig @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: GPL-2.0 + +mainmenu "Numeric bounds test" + +config INT_TOO_LOW + int "Integer below its type bounds" + +config INT_TOO_HIGH + int "Integer above its type bounds" + +config HEX_TOO_HIGH + hex "Hex value above its type bounds" + +config INT_MIN + int "Minimum valid integer" + +config INT_MAX + int "Maximum valid integer" + +config HEX_MIN + hex "Minimum valid hex value" + +config HEX_MAX + hex "Maximum valid hex value" diff --git a/scripts/kconfig/tests/warn_num_bounds/__init__.py b/scripts/kconfig/tests/warn_num_bounds/__init__.py new file mode 100644 index 000000000000..db7518258217 --- /dev/null +++ b/scripts/kconfig/tests/warn_num_bounds/__init__.py @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: GPL-2.0 +"""Test user values outside the numeric type bounds.""" + + +def test(conf): + in_keys = ( + '-9223372036854775809\n' + '-1\n' + '9223372036854775808\n' + '1\n' + '0x10000000000000000\n' + '0x1\n' + '-9223372036854775808\n' + '9223372036854775807\n' + '0x0\n' + '0xffffffffffffffff\n' + ) + + assert conf.oldaskconfig(in_keys=in_keys) == 0 + assert conf.stderr_matches('expected_frontend_stderr') + assert conf.config_matches('expected_frontend_config') + + assert conf.olddefconfig('config') == 0 + assert conf.stderr_matches('expected_config_stderr') + assert conf.config_matches('expected_config') diff --git a/scripts/kconfig/tests/warn_num_bounds/config b/scripts/kconfig/tests/warn_num_bounds/config new file mode 100644 index 000000000000..74bf263f99bf --- /dev/null +++ b/scripts/kconfig/tests/warn_num_bounds/config @@ -0,0 +1,7 @@ +CONFIG_INT_TOO_LOW=-9223372036854775809 +CONFIG_INT_TOO_HIGH=9223372036854775808 +CONFIG_HEX_TOO_HIGH=0x10000000000000000 +CONFIG_INT_MIN=-9223372036854775808 +CONFIG_INT_MAX=9223372036854775807 +CONFIG_HEX_MIN=0x0 +CONFIG_HEX_MAX=0xffffffffffffffff diff --git a/scripts/kconfig/tests/warn_num_bounds/expected_config b/scripts/kconfig/tests/warn_num_bounds/expected_config new file mode 100644 index 000000000000..8b1aef612bc6 --- /dev/null +++ b/scripts/kconfig/tests/warn_num_bounds/expected_config @@ -0,0 +1,11 @@ +# +# Automatically generated file; DO NOT EDIT. +# Numeric bounds test +# +CONFIG_INT_TOO_LOW=-9223372036854775809 +CONFIG_INT_TOO_HIGH=9223372036854775808 +CONFIG_HEX_TOO_HIGH=0x10000000000000000 +CONFIG_INT_MIN=-9223372036854775808 +CONFIG_INT_MAX=9223372036854775807 +CONFIG_HEX_MIN=0x0 +CONFIG_HEX_MAX=0xffffffffffffffff diff --git a/scripts/kconfig/tests/warn_num_bounds/expected_config_stderr b/scripts/kconfig/tests/warn_num_bounds/expected_config_stderr new file mode 100644 index 000000000000..be2ed7fbf648 --- /dev/null +++ b/scripts/kconfig/tests/warn_num_bounds/expected_config_stderr @@ -0,0 +1,3 @@ +.config:1:warning: value '-9223372036854775809' for INT_TOO_LOW is outside the 64-bit signed integer bounds +.config:2:warning: value '9223372036854775808' for INT_TOO_HIGH is outside the 64-bit signed integer bounds +.config:3:warning: value '0x10000000000000000' for HEX_TOO_HIGH is outside the 64-bit unsigned integer bounds diff --git a/scripts/kconfig/tests/warn_num_bounds/expected_frontend_config b/scripts/kconfig/tests/warn_num_bounds/expected_frontend_config new file mode 100644 index 000000000000..a7e842517026 --- /dev/null +++ b/scripts/kconfig/tests/warn_num_bounds/expected_frontend_config @@ -0,0 +1,11 @@ +# +# Automatically generated file; DO NOT EDIT. +# Numeric bounds test +# +CONFIG_INT_TOO_LOW=-1 +CONFIG_INT_TOO_HIGH=1 +CONFIG_HEX_TOO_HIGH=0x1 +CONFIG_INT_MIN=-9223372036854775808 +CONFIG_INT_MAX=9223372036854775807 +CONFIG_HEX_MIN=0x0 +CONFIG_HEX_MAX=0xffffffffffffffff diff --git a/scripts/kconfig/tests/warn_num_bounds/expected_frontend_stderr b/scripts/kconfig/tests/warn_num_bounds/expected_frontend_stderr new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/scripts/kconfig/tests/warn_num_bounds/expected_frontend_stderr |
