mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Julian Braha <julianbraha@gmail.com>
To: nathan@kernel.org, nsc@kernel.org
Cc: nico@fluxnic.net, rdunlap@infradead.org,
	grahamr@qti.qualcomm.com, kees@kernel.org, pengpeng@iscas.ac.cn,
	vegard.nossum@oracle.com, linux-kernel@vger.kernel.org,
	linux-kbuild@vger.kernel.org,
	Julian Braha <julianbraha@gmail.com>
Subject: [PATCH v2 5/5] kconfig: use unsigned integers for hex range checks
Date: Tue, 15 Sep 2026 22:15:08 +0100	[thread overview]
Message-ID: <20260915211508.291790-6-julianbraha@gmail.com> (raw)
In-Reply-To: <20260915211508.291790-1-julianbraha@gmail.com>

While 'hex' values should use the bounds of 64-bit unsigned integers, the
range values are treated as signed (checks use strtoll).

For example:

  config HEX_RANGE
    hex
    range 0 0xfffffffffffffffe
    default 0xffffffffffffffff

the default value should adjust down to the upper bound of
0xfffffffffffffffe, but since the check incorrectly parses both as
LLONG_MAX, the value stays at the out-of-range default of
0xffffffffffffffff.

To fix this, let's use a union of signed and unsigned integers to
represent both 'int' and 'hex' range values, then use both strtoll and
strtoull where appropriate.

Assisted-by: LLM
Signed-off-by: Julian Braha <julianbraha@gmail.com>
---
 scripts/kconfig/symbol.c                      | 41 ++++++++++++++-----
 .../kconfig/tests/warn_changed_input/Kconfig  |  5 +++
 .../tests/warn_changed_input/expected_config  |  1 +
 3 files changed, 36 insertions(+), 11 deletions(-)

diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 0b3d19af269f..14b029f9d6df 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -142,8 +142,15 @@ struct property *sym_get_range_prop(struct symbol *sym)
 	return NULL;
 }
 
-static long long sym_get_range_val(struct symbol *sym, int base)
+union range_value {
+	long long s;
+	unsigned long long u;
+};
+
+static union range_value sym_get_range_val(struct symbol *sym, int base)
 {
+	union range_value val;
+
 	sym_calc_value(sym);
 	switch (sym->type) {
 	case S_INT:
@@ -155,7 +162,12 @@ static long long sym_get_range_val(struct symbol *sym, int base)
 	default:
 		break;
 	}
-	return strtoll(sym->curr.val, NULL, base);
+	if (base == 10)
+		val.s = strtoll(sym->curr.val, NULL, base);
+	else
+		/* HEX */
+		val.u = strtoull(sym->curr.val, NULL, base);
+	return val;
 }
 
 static void sym_validate_range(struct symbol *sym)
@@ -163,7 +175,7 @@ static void sym_validate_range(struct symbol *sym)
 	struct property *prop;
 	struct symbol *range_sym;
 	int base;
-	long long val, val2;
+	union range_value val, val2;
 
 	switch (sym->type) {
 	case S_INT:
@@ -178,13 +190,19 @@ static void sym_validate_range(struct symbol *sym)
 	prop = sym_get_range_prop(sym);
 	if (!prop)
 		return;
-	val = strtoll(sym->curr.val, NULL, base);
+	val = sym_get_range_val(sym, base);
 	range_sym = prop->expr->left.sym;
 	val2 = sym_get_range_val(range_sym, base);
-	if (val >= val2) {
+
+	if (base == 10 && val.s >= val2.s) {
+		range_sym = prop->expr->right.sym;
+		val2 = sym_get_range_val(range_sym, base);
+		if (val.s <= val2.s)
+			return;
+	} else if (base == 16 && val.u >= val2.u) {
 		range_sym = prop->expr->right.sym;
 		val2 = sym_get_range_val(range_sym, base);
-		if (val <= val2)
+		if (val.u <= val2.u)
 			return;
 	}
 	sym->curr.val = range_sym->curr.val;
@@ -731,6 +749,7 @@ bool sym_string_within_range(struct symbol *sym, const char *str)
 {
 	struct property *prop;
 	long long val;
+	unsigned long long uval;
 
 	switch (sym->type) {
 	case S_STRING:
@@ -744,8 +763,8 @@ bool sym_string_within_range(struct symbol *sym, const char *str)
 		if (!prop)
 			return true;
 		val = strtoll(str, NULL, 10);
-		return val >= sym_get_range_val(prop->expr->left.sym, 10) &&
-		       val <= sym_get_range_val(prop->expr->right.sym, 10);
+		return val >= sym_get_range_val(prop->expr->left.sym, 10).s &&
+		       val <= sym_get_range_val(prop->expr->right.sym, 10).s;
 	case S_HEX:
 		if (!sym_string_valid(sym, str))
 			return false;
@@ -754,9 +773,9 @@ bool sym_string_within_range(struct symbol *sym, const char *str)
 		prop = sym_get_range_prop(sym);
 		if (!prop)
 			return true;
-		val = strtoll(str, NULL, 16);
-		return val >= sym_get_range_val(prop->expr->left.sym, 16) &&
-		       val <= sym_get_range_val(prop->expr->right.sym, 16);
+		uval = strtoull(str, NULL, 16);
+		return uval >= sym_get_range_val(prop->expr->left.sym, 16).u &&
+		       uval <= sym_get_range_val(prop->expr->right.sym, 16).u;
 	case S_BOOLEAN:
 	case S_TRISTATE:
 		switch (str[0]) {
diff --git a/scripts/kconfig/tests/warn_changed_input/Kconfig b/scripts/kconfig/tests/warn_changed_input/Kconfig
index 69845e2f3fb3..df4183a08420 100644
--- a/scripts/kconfig/tests/warn_changed_input/Kconfig
+++ b/scripts/kconfig/tests/warn_changed_input/Kconfig
@@ -26,6 +26,11 @@ config NUM
 	  Kconfig resolves it to the constrained in-range value.
 	  The warning should report that adjustment.
 
+config HEX_RANGE
+	hex
+	range 0 0xfffffffffffffffe
+	default 0xffffffffffffffff
+
 config DUP
 	bool "DUP"
 	depends on DEP
diff --git a/scripts/kconfig/tests/warn_changed_input/expected_config b/scripts/kconfig/tests/warn_changed_input/expected_config
index fe8bbec66c53..6a8d98a69b7e 100644
--- a/scripts/kconfig/tests/warn_changed_input/expected_config
+++ b/scripts/kconfig/tests/warn_changed_input/expected_config
@@ -4,3 +4,4 @@
 #
 # CONFIG_DEP is not set
 CONFIG_NUM=20
+CONFIG_HEX_RANGE=0xfffffffffffffffe
-- 
2.55.0


  parent reply	other threads:[~2026-09-15 21:15 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-15 21:15 [PATCH v2 0/5] kconfig: improve input validation for numeric options Julian Braha
2026-09-15 21:15 ` [PATCH v2 1/5] kconfig: promote invalid numeric reference from warning to error Julian Braha
2026-09-17 10:54   ` Nicolas Schier
2026-09-15 21:15 ` [PATCH v2 2/5] kconfig: check for out-of-bounds numeric constants Julian Braha
2026-09-17 15:13   ` Nicolas Schier
2026-09-15 21:15 ` [PATCH v2 3/5] kconfig: check for hex and int mismatches Julian Braha
2026-09-17 15:57   ` Nicolas Schier
2026-09-15 21:15 ` [PATCH v2 4/5] kconfig: prevent out-of-bounds user input for numeric options Julian Braha
2026-09-17 16:13   ` Nicolas Schier
2026-09-15 21:15 ` Julian Braha [this message]
2026-09-17 16:36   ` [PATCH v2 5/5] kconfig: use unsigned integers for hex range checks Nicolas Schier
2026-09-17 23:48 ` [PATCH v2 0/5] kconfig: improve input validation for numeric options Nathan Chancellor

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260915211508.291790-6-julianbraha@gmail.com \
    --to=julianbraha@gmail.com \
    --cc=grahamr@qti.qualcomm.com \
    --cc=kees@kernel.org \
    --cc=linux-kbuild@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nathan@kernel.org \
    --cc=nico@fluxnic.net \
    --cc=nsc@kernel.org \
    --cc=pengpeng@iscas.ac.cn \
    --cc=rdunlap@infradead.org \
    --cc=vegard.nossum@oracle.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®