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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.