lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260112132140.156956-1-costa.shul@redhat.com>
Date: Mon, 12 Jan 2026 15:21:28 +0200
From: Costa Shulyupin <costa.shul@...hat.com>
To: Steven Rostedt <rostedt@...dmis.org>,
	Tomas Glozar <tglozar@...hat.com>,
	Wander Lairson Costa <wander@...hat.com>,
	Costa Shulyupin <costa.shul@...hat.com>,
	Ivan Pravdin <ipravdin.official@...il.com>,
	Tiezhu Yang <yangtiezhu@...ngson.cn>,
	linux-kernel@...r.kernel.org,
	linux-trace-kernel@...r.kernel.org
Subject: [PATCH v1] tools/rtla: Fix parse_cpu_set() and add unit test

The patch "Replace atoi() with a robust strtoi()" introduced a bug
in parse_cpu_set(), which relies on partial parsing of the input
string.

Restore the original use of atoi() in parse_cpu_set().

Add a unit test to prevent accidental regressions.

Fixes: 7e9dfccf8f11 ("rtla: Replace atoi() with a robust strtoi()")

Signed-off-by: Costa Shulyupin <costa.shul@...hat.com>
---
 tools/tracing/rtla/Makefile           |  3 ++
 tools/tracing/rtla/src/utils.c        | 10 ++--
 tools/tracing/rtla/tests/Makefile     | 12 +++++
 tools/tracing/rtla/tests/test_utils.c | 74 +++++++++++++++++++++++++++
 4 files changed, 93 insertions(+), 6 deletions(-)
 create mode 100644 tools/tracing/rtla/tests/Makefile
 create mode 100644 tools/tracing/rtla/tests/test_utils.c

diff --git a/tools/tracing/rtla/Makefile b/tools/tracing/rtla/Makefile
index 2701256abaf3..1805916c7dba 100644
--- a/tools/tracing/rtla/Makefile
+++ b/tools/tracing/rtla/Makefile
@@ -109,7 +109,10 @@ clean: doc_clean fixdep-clean
 	$(Q)rm -f rtla rtla-static fixdep FEATURE-DUMP rtla-*
 	$(Q)rm -rf feature
 	$(Q)rm -f src/timerlat.bpf.o src/timerlat.skel.h example/timerlat_bpf_action.o
+
 check: $(RTLA) tests/bpf/bpf_action_map.o
+	make -C tests/ check
 	RTLA=$(RTLA) BPFTOOL=$(SYSTEM_BPFTOOL) prove -o -f -v tests/
+
 examples: example/timerlat_bpf_action.o
 .PHONY: FORCE clean check
diff --git a/tools/tracing/rtla/src/utils.c b/tools/tracing/rtla/src/utils.c
index 18986a5aed3c..0da3b2470c31 100644
--- a/tools/tracing/rtla/src/utils.c
+++ b/tools/tracing/rtla/src/utils.c
@@ -128,18 +128,16 @@ int parse_cpu_set(char *cpu_list, cpu_set_t *set)
 	nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
 
 	for (p = cpu_list; *p; ) {
-		if (strtoi(p, &cpu))
-			goto err;
-		if (cpu < 0 || cpu >= nr_cpus)
+		cpu = atoi(p);
+		if (cpu < 0 || (!cpu && *p != '0') || cpu >= nr_cpus)
 			goto err;
 
 		while (isdigit(*p))
 			p++;
 		if (*p == '-') {
 			p++;
-			if (strtoi(p, &end_cpu))
-				goto err;
-			if (end_cpu < cpu || end_cpu >= nr_cpus)
+			end_cpu = atoi(p);
+			if (end_cpu < cpu || (!end_cpu && *p != '0') || end_cpu >= nr_cpus)
 				goto err;
 			while (isdigit(*p))
 				p++;
diff --git a/tools/tracing/rtla/tests/Makefile b/tools/tracing/rtla/tests/Makefile
new file mode 100644
index 000000000000..fe187306a404
--- /dev/null
+++ b/tools/tracing/rtla/tests/Makefile
@@ -0,0 +1,12 @@
+LIBS := -lcheck
+
+test_utils: test_utils.c ../src/utils.c
+	$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
+
+check: test_utils
+	./test_utils
+
+clean:
+	rm -f test_utils
+
+.PHONY: check clean
diff --git a/tools/tracing/rtla/tests/test_utils.c b/tools/tracing/rtla/tests/test_utils.c
new file mode 100644
index 000000000000..92ed49d60d33
--- /dev/null
+++ b/tools/tracing/rtla/tests/test_utils.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Unit tests for src/utils.c parsing functions
+ */
+
+#define _GNU_SOURCE
+#include <check.h>
+#include <unistd.h>
+
+#include "../src/utils.h"
+
+START_TEST(test_parse_cpu_set)
+{
+	cpu_set_t set;
+	int nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
+
+	ck_assert_int_eq(parse_cpu_set("0", &set), 0);
+	ck_assert(CPU_ISSET(0, &set));
+	ck_assert(!CPU_ISSET(1, &set));
+
+	if (nr_cpus > 2) {
+		ck_assert_int_eq(parse_cpu_set("0,2", &set), 0);
+		ck_assert(CPU_ISSET(0, &set));
+		ck_assert(CPU_ISSET(2, &set));
+	}
+
+	if (nr_cpus > 3) {
+		ck_assert_int_eq(parse_cpu_set("0-3", &set), 0);
+		ck_assert(CPU_ISSET(0, &set));
+		ck_assert(CPU_ISSET(1, &set));
+		ck_assert(CPU_ISSET(2, &set));
+		ck_assert(CPU_ISSET(3, &set));
+	}
+
+	if (nr_cpus > 5) {
+		ck_assert_int_eq(parse_cpu_set("1-3,5", &set), 0);
+		ck_assert(!CPU_ISSET(0, &set));
+		ck_assert(CPU_ISSET(1, &set));
+		ck_assert(CPU_ISSET(2, &set));
+		ck_assert(CPU_ISSET(3, &set));
+		ck_assert(!CPU_ISSET(4, &set));
+		ck_assert(CPU_ISSET(5, &set));
+	}
+
+	ck_assert_int_ne(parse_cpu_set("-1", &set), 0);
+	ck_assert_int_ne(parse_cpu_set("abc", &set), 0);
+	ck_assert_int_ne(parse_cpu_set("9999", &set), 0);
+}
+END_TEST
+
+Suite *utils_suite(void)
+{
+	Suite *s = suite_create("utils");
+	TCase *tc = tcase_create("core");
+
+	tcase_add_test(tc, test_parse_cpu_set);
+
+	suite_add_tcase(s, tc);
+	return s;
+}
+
+int main(void)
+{
+	int num_failed;
+	SRunner *sr;
+
+	sr = srunner_create(utils_suite());
+	srunner_run_all(sr, CK_NORMAL);
+	num_failed = srunner_ntests_failed(sr);
+
+	srunner_free(sr);
+
+	return (num_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
-- 
2.52.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ