From: sashiko-bot@kernel.org
To: "Jim Cromie" <jim.cromie@gmail.com>
Cc: bpf@vger.kernel.org
Subject: Re: [PATCH v2 1/3] kallsyms: Add test_kallsyms_perf module to benchmark lookup latency
Date: Tue, 22 Sep 2026 07:30:11 +0000 [thread overview]
Message-ID: <20260922073012.013F91F000FF@smtp.kernel.org> (raw)
In-Reply-To: <20260922-ksyms-tune-v2-1-a333ee31eac7@gmail.com>
Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
- [High] kallsyms: re-exporting iterators breaks security encapsulation
- [High] kallsyms: missing preemption in tight loops causes soft lockups
- [High] kallsyms: divide by zero in latency calculation via module parameter
- [High] kallsyms: direct 64-bit division breaks 32-bit builds
- [Medium] kallsyms: test module spuriously fails on kernels without IPv4
- [Low] kconfig: test module set to 'default m' pollutes builds
--
commit 6589e2eb779ca1b70f6d786ad47e1be731aba20e
Author: Jim Cromie <jim.cromie@gmail.com>
kallsyms: Add test_kallsyms_perf module to benchmark lookup latency
This commit adds a lightweight microbenchmark module in lib/ to evaluate
optimizations and measure performance regressions across kallsyms lookups.
> diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
> index aec2f06858afd..b9e573e9a10b9 100644
> --- a/kernel/kallsyms.c
> +++ b/kernel/kallsyms.c
> @@ -261,6 +261,7 @@ int kallsyms_on_each_symbol(int (*fn)(void *, const char *, unsigned long),
> }
> return 0;
> }
> +EXPORT_SYMBOL_GPL(kallsyms_on_each_symbol);
[Severity: High]
Does exporting this function directly reverse the security protection
introduced by commit 0bd476e6c6719 ("kallsyms: unexport
kallsyms_lookup_name() and kallsyms_on_each_symbol()")?
It appears this allows any GPL-compatible out-of-tree module to bypass
symbol exports and resolve unexported symbols by passing a custom match
function.
> int kallsyms_on_each_match_symbol(int (*fn)(void *, unsigned long),
> const char *name, void *data)
> @@ -279,6 +280,7 @@ int kallsyms_on_each_match_symbol(int (*fn)(void *, unsigned long),
>
> return ret;
> }
> +EXPORT_SYMBOL_GPL(kallsyms_on_each_match_symbol);
[Severity: High]
Can this export similarly be abused by loadable modules to circumvent the
EXPORT_SYMBOL mechanism and resolve unexported symbols natively?
> diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
> index 134b15a44625e..2a8b1aaee23b3 100644
> --- a/lib/Kconfig.debug
> +++ b/lib/Kconfig.debug
> @@ -3122,6 +3122,16 @@ config TEST_STATIC_KEYS
>
> If unsure, say N.
>
> +config TEST_KALLSYMS_PERF
> + tristate "kallsyms performance benchmark test module"
> + default m
[Severity: Low]
Is it intended to have this test module enabled by default? Setting this
to default m pollutes default configurations and slows down compilation.
[ ... ]
> diff --git a/lib/test_kallsyms_perf.c b/lib/test_kallsyms_perf.c
> new file mode 100644
> index 0000000000000..c649e55dae3b8
> --- /dev/null
> +++ b/lib/test_kallsyms_perf.c
> @@ -0,0 +1,228 @@
[ ... ]
> +static unsigned int num_iters = 100000;
> +module_param(num_iters, uint, 0644);
> +MODULE_PARM_DESC(num_iters, "Number of iterations per microbenchmark");
[Severity: High]
What happens if num_iters is set to 0 via sysfs?
Since this parameter is globally writable and unchecked, could a user
write 0 and instantly trigger a hardware divide-by-zero exception during
the latency calculations below?
> +static const char * const hit_symbols[] = {
> + "_printk",
> + "schedule",
> + "vfs_read",
> + "do_sys_openat2",
> + "kernel_clone",
> + "tcp_v4_rcv",
[Severity: Medium]
Is it guaranteed that tcp_v4_rcv will be present on all kernel
configurations?
If the kernel is built without IPv4 support (CONFIG_INET), won't this valid
symbol be missing, causing the correctness validation in
run_name_lookup_bench() to emit a false failure?
[ ... ]
> +static void run_name_lookup_bench(void)
> +{
> + u64 t0, t1, dt_hit, dt_miss;
[ ... ]
> + /* 2. Name search: Non-existent symbols (Misses - 17 bsearch probes) */
> + t0 = ktime_get_ns();
> + for (i = 0; i < num_iters; i++) {
> + const char *sym = miss_symbols[i % nr_misses];
> +
> + kallsyms_on_each_match_symbol(match_cb, sym, &addr);
> + OPTIMIZER_HIDE_VAR(addr);
> + }
[Severity: High]
Could large values of num_iters in this tight loop stall the CPU and
trigger soft lockups on CONFIG_PREEMPT_NONE or CONFIG_PREEMPT_VOLUNTARY
kernels, since cond_resched() is not invoked?
> + t1 = ktime_get_ns();
> + dt_miss = t1 - t0;
> +
> + pr_info("Name Search Hit: %llu ns/lookup (%llu ms total, %u iters)\n",
> + dt_hit / num_iters, dt_hit / 1000000, num_iters);
[Severity: High]
Does this direct 64-bit division of dt_hit (a u64) by num_iters break
32-bit builds?
This typically causes link-time failures due to an undefined reference to
__udivdi3 on 32-bit architectures. Even with a transition to div_u64() in
later commits, the divisor would still need to be checked against zero.
[ ... ]
> +static void run_address_lookup_bench(void)
> +{
> + u64 t0, t1, dt_sprint, dt_bldid;
[ ... ]
> + /* 1. Address-to-name resolution (sprint_symbol) */
> + t0 = ktime_get_ns();
> + for (i = 0; i < num_iters; i++) {
> + unsigned long addr = addrs[i % nr_addrs];
> +
> + sprint_symbol(symname, addr);
> + barrier_data(symname);
> + }
[Severity: High]
Similar to the name search loop, could this tight loop executing millions
of operations without yielding the CPU trigger soft lockup panics?
[ ... ]
> + pr_info("sprint_symbol: %llu ns/lookup (%llu ms total, %u iters)\n",
> + dt_sprint / num_iters, dt_sprint / 1000000, num_iters);
[Severity: High]
Could this also trigger a divide-by-zero hardware exception if num_iters
is set to 0?
[ ... ]
> +static void run_table_walk_bench(void)
> +{
> + u64 t0, t1, dt_walk;
> + unsigned long total_symbols = 0;
> + int iter = 50;
> + int i;
> +
> + t0 = ktime_get_ns();
> + for (i = 0; i < iter; i++) {
> + total_symbols = 0;
> + kallsyms_on_each_symbol(count_cb, &total_symbols);
> + }
> + t1 = ktime_get_ns();
> + dt_walk = t1 - t0;
> +
> + pr_info("Table Full Walk: %llu us/pass (%lu symbols scanned, %d passes)\n",
> + (dt_walk / iter) / 1000, total_symbols, iter);
> +}
[Severity: High]
Does the 64-bit division here (dt_walk / iter) also break 32-bit builds
with an undefined reference to __udivdi3?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260922-ksyms-tune-v2-0-a333ee31eac7@gmail.com?part=1
next prev parent reply other threads:[~2026-09-22 7:30 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-22 7:19 [PATCH v2 0/3] kallsyms: Accelerate symbol name lookups by ~19x Jim Cromie
2026-09-22 7:19 ` [PATCH v2 1/3] kallsyms: Add test_kallsyms_perf module to benchmark lookup latency Jim Cromie
2026-09-22 7:30 ` sashiko-bot [this message]
2026-09-22 7:19 ` [PATCH v2 2/3] kallsyms: Add dynamic lookup index for batch resolution Jim Cromie
2026-09-22 7:31 ` sashiko-bot
2026-09-22 7:19 ` [PATCH v2 3/3] kallsyms: Match compressed tokens on the fly during binary search Jim Cromie
2026-09-22 9:03 ` David Laight
2026-09-22 8:41 ` [PATCH v2 0/3] kallsyms: Accelerate symbol name lookups by ~19x David Laight
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=20260922073012.013F91F000FF@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=jim.cromie@gmail.com \
--cc=sashiko-reviews@lists.linux.dev \
/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