* [PATCH 1/6] module: Add helper function for reading module_buildid()
2025-11-05 14:23 [PATCH 0/6] kallsyms: Prevent invalid access when showing module buildid Petr Mladek
@ 2025-11-05 14:23 ` Petr Mladek
2025-11-06 8:52 ` Petr Pavlu
2025-11-06 12:54 ` Daniel Gomez
2025-11-05 14:23 ` [PATCH 2/6] kallsyms: Cleanup code for appending the module buildid Petr Mladek
` (4 subsequent siblings)
5 siblings, 2 replies; 22+ messages in thread
From: Petr Mladek @ 2025-11-05 14:23 UTC (permalink / raw)
To: Petr Pavlu, Steven Rostedt, Alexei Starovoitov, Andrew Morton,
Kees Cook
Cc: Daniel Borkmann, John Fastabend, Masami Hiramatsu, Mark Rutland,
Luis Chamberlain, Daniel Gomez, Sami Tolvanen, linux-kernel, bpf,
linux-modules, linux-trace-kernel, Petr Mladek
Add a helper function for reading the optional "build_id" member
of struct module. It is going to be used also in
ftrace_mod_address_lookup().
Use "#ifdef" instead of "#if IS_ENABLED()" to match the declaration
of the optional field in struct module.
Signed-off-by: Petr Mladek <pmladek@suse.com>
---
include/linux/module.h | 9 +++++++++
kernel/module/kallsyms.c | 9 ++-------
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/include/linux/module.h b/include/linux/module.h
index e135cc79acee..4decae2b1675 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -747,6 +747,15 @@ static inline void __module_get(struct module *module)
__mod ? __mod->name : "kernel"; \
})
+static inline const unsigned char *module_buildid(struct module *mod)
+{
+#ifdef CONFIG_STACKTRACE_BUILD_ID
+ return mod->build_id;
+#else
+ return NULL;
+#endif
+}
+
/* Dereference module function descriptor */
void *dereference_module_function_descriptor(struct module *mod, void *ptr);
diff --git a/kernel/module/kallsyms.c b/kernel/module/kallsyms.c
index 00a60796327c..0fc11e45df9b 100644
--- a/kernel/module/kallsyms.c
+++ b/kernel/module/kallsyms.c
@@ -334,13 +334,8 @@ int module_address_lookup(unsigned long addr,
if (mod) {
if (modname)
*modname = mod->name;
- if (modbuildid) {
-#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID)
- *modbuildid = mod->build_id;
-#else
- *modbuildid = NULL;
-#endif
- }
+ if (modbuildid)
+ *modbuildid = module_buildid(mod);
sym = find_kallsyms_symbol(mod, addr, size, offset);
--
2.51.1
^ permalink raw reply related [flat|nested] 22+ messages in thread* Re: [PATCH 1/6] module: Add helper function for reading module_buildid()
2025-11-05 14:23 ` [PATCH 1/6] module: Add helper function for reading module_buildid() Petr Mladek
@ 2025-11-06 8:52 ` Petr Pavlu
2025-11-06 12:54 ` Daniel Gomez
1 sibling, 0 replies; 22+ messages in thread
From: Petr Pavlu @ 2025-11-06 8:52 UTC (permalink / raw)
To: Petr Mladek
Cc: Steven Rostedt, Alexei Starovoitov, Andrew Morton, Kees Cook,
Daniel Borkmann, John Fastabend, Masami Hiramatsu, Mark Rutland,
Luis Chamberlain, Daniel Gomez, Sami Tolvanen, linux-kernel, bpf,
linux-modules, linux-trace-kernel
On 11/5/25 3:23 PM, Petr Mladek wrote:
> Add a helper function for reading the optional "build_id" member
> of struct module. It is going to be used also in
> ftrace_mod_address_lookup().
>
> Use "#ifdef" instead of "#if IS_ENABLED()" to match the declaration
> of the optional field in struct module.
>
> Signed-off-by: Petr Mladek <pmladek@suse.com>
Reviewed-by: Petr Pavlu <petr.pavlu@suse.com>
--
Thanks,
Petr
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 1/6] module: Add helper function for reading module_buildid()
2025-11-05 14:23 ` [PATCH 1/6] module: Add helper function for reading module_buildid() Petr Mladek
2025-11-06 8:52 ` Petr Pavlu
@ 2025-11-06 12:54 ` Daniel Gomez
1 sibling, 0 replies; 22+ messages in thread
From: Daniel Gomez @ 2025-11-06 12:54 UTC (permalink / raw)
To: Petr Mladek, Petr Pavlu, Steven Rostedt, Alexei Starovoitov,
Andrew Morton, Kees Cook
Cc: Daniel Borkmann, John Fastabend, Masami Hiramatsu, Mark Rutland,
Luis Chamberlain, Sami Tolvanen, linux-kernel, bpf, linux-modules,
linux-trace-kernel
On 05/11/2025 15.23, Petr Mladek wrote:
> Add a helper function for reading the optional "build_id" member
> of struct module. It is going to be used also in
> ftrace_mod_address_lookup().
>
> Use "#ifdef" instead of "#if IS_ENABLED()" to match the declaration
> of the optional field in struct module.
>
> Signed-off-by: Petr Mladek <pmladek@suse.com>
Reviewed-by: Daniel Gomez <da.gomez@samsung.com>
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 2/6] kallsyms: Cleanup code for appending the module buildid
2025-11-05 14:23 [PATCH 0/6] kallsyms: Prevent invalid access when showing module buildid Petr Mladek
2025-11-05 14:23 ` [PATCH 1/6] module: Add helper function for reading module_buildid() Petr Mladek
@ 2025-11-05 14:23 ` Petr Mladek
2025-11-05 14:59 ` bot+bpf-ci
2025-11-05 14:23 ` [PATCH 3/6] kallsyms/bpf: Set module buildid in bpf_address_lookup() Petr Mladek
` (3 subsequent siblings)
5 siblings, 1 reply; 22+ messages in thread
From: Petr Mladek @ 2025-11-05 14:23 UTC (permalink / raw)
To: Petr Pavlu, Steven Rostedt, Alexei Starovoitov, Andrew Morton,
Kees Cook
Cc: Daniel Borkmann, John Fastabend, Masami Hiramatsu, Mark Rutland,
Luis Chamberlain, Daniel Gomez, Sami Tolvanen, linux-kernel, bpf,
linux-modules, linux-trace-kernel, Petr Mladek
Put the code for appending the optional "buildid" into a helper
function, It makes __sprint_symbol() better readable.
Also print a warning when the "modname" is set and the "buildid" isn't.
It might catch a situation when some lookup function in
kallsyms_lookup_buildid() does not handle the "buildid".
Use pr_*_once() to avoid an infinite recursion when the function
is called from printk(). The recursion is rather theoretical but
better be on the safe side.
Signed-off-by: Petr Mladek <pmladek@suse.com>
---
kernel/kallsyms.c | 42 +++++++++++++++++++++++++++++++++---------
1 file changed, 33 insertions(+), 9 deletions(-)
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index 1e7635864124..9455e3bb07fc 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -423,6 +423,37 @@ int lookup_symbol_name(unsigned long addr, char *symname)
return lookup_module_symbol_name(addr, symname);
}
+#ifdef CONFIG_STACKTRACE_BUILD_ID
+
+static int append_buildid(char *buffer, const char *modname,
+ const unsigned char *buildid)
+{
+ if (!modname)
+ return 0;
+
+ if (!buildid) {
+ pr_warn_once("Undefined buildid for the module %s\n", modname);
+ return 0;
+ }
+
+ /* build ID should match length of sprintf */
+#ifdef CONFIG_MODULES
+ static_assert(sizeof(typeof_member(struct module, build_id)) == 20);
+#endif
+
+ return sprintf(buffer, " %20phN", buildid);
+}
+
+#else /* CONFIG_STACKTRACE_BUILD_ID */
+
+static int append_buildid(char *buffer, const char *modname,
+ const unsigned char *buildid)
+{
+ return 0;
+}
+
+#endif /* CONFIG_STACKTRACE_BUILD_ID */
+
/* Look up a kernel symbol and return it in a text buffer. */
static int __sprint_symbol(char *buffer, unsigned long address,
int symbol_offset, int add_offset, int add_buildid)
@@ -445,15 +476,8 @@ static int __sprint_symbol(char *buffer, unsigned long address,
if (modname) {
len += sprintf(buffer + len, " [%s", modname);
-#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID)
- if (add_buildid && buildid) {
- /* build ID should match length of sprintf */
-#if IS_ENABLED(CONFIG_MODULES)
- static_assert(sizeof(typeof_member(struct module, build_id)) == 20);
-#endif
- len += sprintf(buffer + len, " %20phN", buildid);
- }
-#endif
+ if (add_buildid)
+ len += append_buildid(buffer + len, modname, buildid);
len += sprintf(buffer + len, "]");
}
--
2.51.1
^ permalink raw reply related [flat|nested] 22+ messages in thread* Re: [PATCH 2/6] kallsyms: Cleanup code for appending the module buildid
2025-11-05 14:23 ` [PATCH 2/6] kallsyms: Cleanup code for appending the module buildid Petr Mladek
@ 2025-11-05 14:59 ` bot+bpf-ci
2025-11-07 13:14 ` Petr Mladek
0 siblings, 1 reply; 22+ messages in thread
From: bot+bpf-ci @ 2025-11-05 14:59 UTC (permalink / raw)
To: pmladek, petr.pavlu, rostedt, ast, akpm, kees
Cc: daniel, john.fastabend, mhiramat, mark.rutland, mcgrof, da.gomez,
samitolvanen, linux-kernel, bpf, linux-modules,
linux-trace-kernel, pmladek, ast, andrii, daniel, martin.lau,
eddyz87, yonghong.song, clm, ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 2442 bytes --]
> diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
> index 1e7635864..9455e3bb0 100644
> --- a/kernel/kallsyms.c
> +++ b/kernel/kallsyms.c
> @@ -423,6 +423,37 @@ int lookup_symbol_name(unsigned long addr, char *symname)
> return lookup_module_symbol_name(addr, symname);
> }
>
> +#ifdef CONFIG_STACKTRACE_BUILD_ID
> +
> +static int append_buildid(char *buffer, const char *modname,
> + const unsigned char *buildid)
> +{
> + if (!modname)
> + return 0;
> +
> + if (!buildid) {
> + pr_warn_once("Undefined buildid for the module %s\n", modname);
> + return 0;
> + }
When ftrace_mod_address_lookup() succeeds in kallsyms_lookup_buildid(),
it sets *modname but doesn't initialize *modbuildid. This leaves the
buildid variable uninitialized when __sprint_symbol() calls
append_buildid(). Can the check above read uninitialized memory?
Looking at kallsyms_lookup_buildid():
- module_address_lookup() properly initializes both modname and
modbuildid
- bpf_address_lookup() sets modname=NULL (so append_buildid isn't
called)
- ftrace_mod_address_lookup() sets modname=mod_map->mod->name but has
no modbuildid parameter
The commit message mentions wanting to catch when lookup functions don't
handle buildid, but shouldn't kallsyms_lookup_buildid() initialize
*modbuildid=NULL before calling the lookup functions to avoid undefined
behavior?
> +
> + /* build ID should match length of sprintf */
> +#ifdef CONFIG_MODULES
> + static_assert(sizeof(typeof_member(struct module, build_id)) == 20);
> +#endif
> +
> + return sprintf(buffer, " %20phN", buildid);
> +}
[ ... ]
> @@ -445,15 +476,8 @@ static int __sprint_symbol(char *buffer, unsigned long address,
>
> if (modname) {
> len += sprintf(buffer + len, " [%s", modname);
> -#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID)
> - if (add_buildid && buildid) {
> - /* build ID should match length of sprintf */
> -#if IS_ENABLED(CONFIG_MODULES)
> - static_assert(sizeof(typeof_member(struct module, build_id)) == 20);
> -#endif
> - len += sprintf(buffer + len, " %20phN", buildid);
> - }
> -#endif
> + if (add_buildid)
> + len += append_buildid(buffer + len, modname, buildid);
> len += sprintf(buffer + len, "]");
> }
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/19105560191
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH 2/6] kallsyms: Cleanup code for appending the module buildid
2025-11-05 14:59 ` bot+bpf-ci
@ 2025-11-07 13:14 ` Petr Mladek
2025-11-07 17:40 ` Alexei Starovoitov
0 siblings, 1 reply; 22+ messages in thread
From: Petr Mladek @ 2025-11-07 13:14 UTC (permalink / raw)
To: bot+bpf-ci
Cc: petr.pavlu, rostedt, ast, akpm, kees, daniel, john.fastabend,
mhiramat, mark.rutland, mcgrof, da.gomez, samitolvanen,
linux-kernel, bpf, linux-modules, linux-trace-kernel, andrii,
martin.lau, eddyz87, yonghong.song, clm, ihor.solodrai
On Wed 2025-11-05 14:59:53, bot+bpf-ci@kernel.org wrote:
> > diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
> > index 1e7635864..9455e3bb0 100644
> > --- a/kernel/kallsyms.c
> > +++ b/kernel/kallsyms.c
> > @@ -423,6 +423,37 @@ int lookup_symbol_name(unsigned long addr, char *symname)
> > return lookup_module_symbol_name(addr, symname);
> > }
> >
> > +#ifdef CONFIG_STACKTRACE_BUILD_ID
> > +
> > +static int append_buildid(char *buffer, const char *modname,
> > + const unsigned char *buildid)
> > +{
> > + if (!modname)
> > + return 0;
> > +
> > + if (!buildid) {
> > + pr_warn_once("Undefined buildid for the module %s\n", modname);
> > + return 0;
> > + }
>
> When ftrace_mod_address_lookup() succeeds in kallsyms_lookup_buildid(),
> it sets *modname but doesn't initialize *modbuildid. This leaves the
> buildid variable uninitialized when __sprint_symbol() calls
> append_buildid().
Just for record. This is a great analyze. This patchset is fixing
this bug in a later patch. ;-)
> Can the check above read uninitialized memory?>
> Looking at kallsyms_lookup_buildid():
> - module_address_lookup() properly initializes both modname and
> modbuildid
> - bpf_address_lookup() sets modname=NULL (so append_buildid isn't
> called)
> - ftrace_mod_address_lookup() sets modname=mod_map->mod->name but has
> no modbuildid parameter
>
> The commit message mentions wanting to catch when lookup functions don't
> handle buildid, but shouldn't kallsyms_lookup_buildid() initialize
> *modbuildid=NULL before calling the lookup functions to avoid undefined
> behavior?
It seems that we are going this way, see
https://lore.kernel.org/all/aQ3vWIqG31BgE4YD@pathway.suse.cz/
Best Regards,
Petr
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH 2/6] kallsyms: Cleanup code for appending the module buildid
2025-11-07 13:14 ` Petr Mladek
@ 2025-11-07 17:40 ` Alexei Starovoitov
0 siblings, 0 replies; 22+ messages in thread
From: Alexei Starovoitov @ 2025-11-07 17:40 UTC (permalink / raw)
To: Petr Mladek
Cc: bot+bpf-ci, Petr Pavlu, Steven Rostedt, Alexei Starovoitov,
Andrew Morton, Kees Cook, Daniel Borkmann, John Fastabend,
Masami Hiramatsu, Mark Rutland, Luis R. Rodriguez, Daniel Gomez,
Sami Tolvanen, LKML, bpf, linux-modules, linux-trace-kernel,
Andrii Nakryiko, Martin KaFai Lau, Eduard, Yonghong Song,
Chris Mason, Ihor Solodrai
On Fri, Nov 7, 2025 at 5:15 AM Petr Mladek <pmladek@suse.com> wrote:
>
> On Wed 2025-11-05 14:59:53, bot+bpf-ci@kernel.org wrote:
> > > diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
> > > index 1e7635864..9455e3bb0 100644
> > > --- a/kernel/kallsyms.c
> > > +++ b/kernel/kallsyms.c
> > > @@ -423,6 +423,37 @@ int lookup_symbol_name(unsigned long addr, char *symname)
> > > return lookup_module_symbol_name(addr, symname);
> > > }
> > >
> > > +#ifdef CONFIG_STACKTRACE_BUILD_ID
> > > +
> > > +static int append_buildid(char *buffer, const char *modname,
> > > + const unsigned char *buildid)
> > > +{
> > > + if (!modname)
> > > + return 0;
> > > +
> > > + if (!buildid) {
> > > + pr_warn_once("Undefined buildid for the module %s\n", modname);
> > > + return 0;
> > > + }
> >
> > When ftrace_mod_address_lookup() succeeds in kallsyms_lookup_buildid(),
> > it sets *modname but doesn't initialize *modbuildid. This leaves the
> > buildid variable uninitialized when __sprint_symbol() calls
> > append_buildid().
>
> Just for record. This is a great analyze. This patchset is fixing
> this bug in a later patch. ;-)
Currently AI analyses one patch at a time and comments on what it
understands the way humans would do if they read and comment
as they go.
Teaching AI to understand the whole series is on todo list.
Chris may comment on how feasible that is.
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 3/6] kallsyms/bpf: Set module buildid in bpf_address_lookup()
2025-11-05 14:23 [PATCH 0/6] kallsyms: Prevent invalid access when showing module buildid Petr Mladek
2025-11-05 14:23 ` [PATCH 1/6] module: Add helper function for reading module_buildid() Petr Mladek
2025-11-05 14:23 ` [PATCH 2/6] kallsyms: Cleanup code for appending the module buildid Petr Mladek
@ 2025-11-05 14:23 ` Petr Mladek
2025-11-06 2:53 ` Alexei Starovoitov
2025-11-05 14:23 ` [PATCH 4/6] kallsyms/ftrace: Set module buildid in ftrace_mod_address_lookup() Petr Mladek
` (2 subsequent siblings)
5 siblings, 1 reply; 22+ messages in thread
From: Petr Mladek @ 2025-11-05 14:23 UTC (permalink / raw)
To: Petr Pavlu, Steven Rostedt, Alexei Starovoitov, Andrew Morton,
Kees Cook
Cc: Daniel Borkmann, John Fastabend, Masami Hiramatsu, Mark Rutland,
Luis Chamberlain, Daniel Gomez, Sami Tolvanen, linux-kernel, bpf,
linux-modules, linux-trace-kernel, Petr Mladek
Make bpf_address_lookup() compatible with module_address_lookup()
and clear the pointer to @modbuildid together with @modname.
It is not strictly needed because __sprint_symbol() reads @modbuildid
only when @modname is set. But better be on the safe side and make
the API more safe.
Fixes: 9294523e3768 ("module: add printk formats to add module build ID to stacktraces")
Signed-off-by: Petr Mladek <pmladek@suse.com>
---
include/linux/filter.h | 15 +++++++++++----
kernel/kallsyms.c | 4 ++--
2 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/include/linux/filter.h b/include/linux/filter.h
index f5c859b8131a..b7b95840250a 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -1362,12 +1362,18 @@ struct bpf_prog *bpf_prog_ksym_find(unsigned long addr);
static inline int
bpf_address_lookup(unsigned long addr, unsigned long *size,
- unsigned long *off, char **modname, char *sym)
+ unsigned long *off, char **modname,
+ const unsigned char **modbuildid, char *sym)
{
int ret = __bpf_address_lookup(addr, size, off, sym);
- if (ret && modname)
- *modname = NULL;
+ if (ret) {
+ if (modname)
+ *modname = NULL;
+ if (modbuildid)
+ *modbuildid = NULL;
+ }
+
return ret;
}
@@ -1433,7 +1439,8 @@ static inline struct bpf_prog *bpf_prog_ksym_find(unsigned long addr)
static inline int
bpf_address_lookup(unsigned long addr, unsigned long *size,
- unsigned long *off, char **modname, char *sym)
+ unsigned long *off, char **modname,
+ const unsigned char **modbuildid, char *sym)
{
return 0;
}
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index 9455e3bb07fc..efb12b077220 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -374,8 +374,8 @@ static int kallsyms_lookup_buildid(unsigned long addr,
ret = module_address_lookup(addr, symbolsize, offset,
modname, modbuildid, namebuf);
if (!ret)
- ret = bpf_address_lookup(addr, symbolsize,
- offset, modname, namebuf);
+ ret = bpf_address_lookup(addr, symbolsize, offset,
+ modname, modbuildid, namebuf);
if (!ret)
ret = ftrace_mod_address_lookup(addr, symbolsize,
--
2.51.1
^ permalink raw reply related [flat|nested] 22+ messages in thread* Re: [PATCH 3/6] kallsyms/bpf: Set module buildid in bpf_address_lookup()
2025-11-05 14:23 ` [PATCH 3/6] kallsyms/bpf: Set module buildid in bpf_address_lookup() Petr Mladek
@ 2025-11-06 2:53 ` Alexei Starovoitov
2025-11-07 13:08 ` Petr Mladek
0 siblings, 1 reply; 22+ messages in thread
From: Alexei Starovoitov @ 2025-11-06 2:53 UTC (permalink / raw)
To: Petr Mladek
Cc: Petr Pavlu, Steven Rostedt, Alexei Starovoitov, Andrew Morton,
Kees Cook, Daniel Borkmann, John Fastabend, Masami Hiramatsu,
Mark Rutland, Luis Chamberlain, Daniel Gomez, Sami Tolvanen, LKML,
bpf, linux-modules, linux-trace-kernel
On Wed, Nov 5, 2025 at 6:24 AM Petr Mladek <pmladek@suse.com> wrote:
>
> Make bpf_address_lookup() compatible with module_address_lookup()
> and clear the pointer to @modbuildid together with @modname.
>
> It is not strictly needed because __sprint_symbol() reads @modbuildid
> only when @modname is set. But better be on the safe side and make
> the API more safe.
>
> Fixes: 9294523e3768 ("module: add printk formats to add module build ID to stacktraces")
> Signed-off-by: Petr Mladek <pmladek@suse.com>
> ---
> include/linux/filter.h | 15 +++++++++++----
> kernel/kallsyms.c | 4 ++--
> 2 files changed, 13 insertions(+), 6 deletions(-)
>
> diff --git a/include/linux/filter.h b/include/linux/filter.h
> index f5c859b8131a..b7b95840250a 100644
> --- a/include/linux/filter.h
> +++ b/include/linux/filter.h
> @@ -1362,12 +1362,18 @@ struct bpf_prog *bpf_prog_ksym_find(unsigned long addr);
>
> static inline int
> bpf_address_lookup(unsigned long addr, unsigned long *size,
> - unsigned long *off, char **modname, char *sym)
> + unsigned long *off, char **modname,
> + const unsigned char **modbuildid, char *sym)
> {
> int ret = __bpf_address_lookup(addr, size, off, sym);
>
> - if (ret && modname)
> - *modname = NULL;
> + if (ret) {
> + if (modname)
> + *modname = NULL;
> + if (modbuildid)
> + *modbuildid = NULL;
> + }
> +
> return ret;
> }
>
> @@ -1433,7 +1439,8 @@ static inline struct bpf_prog *bpf_prog_ksym_find(unsigned long addr)
>
> static inline int
> bpf_address_lookup(unsigned long addr, unsigned long *size,
> - unsigned long *off, char **modname, char *sym)
> + unsigned long *off, char **modname,
> + const unsigned char **modbuildid, char *sym)
> {
> return 0;
> }
> diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
> index 9455e3bb07fc..efb12b077220 100644
> --- a/kernel/kallsyms.c
> +++ b/kernel/kallsyms.c
> @@ -374,8 +374,8 @@ static int kallsyms_lookup_buildid(unsigned long addr,
> ret = module_address_lookup(addr, symbolsize, offset,
> modname, modbuildid, namebuf);
> if (!ret)
> - ret = bpf_address_lookup(addr, symbolsize,
> - offset, modname, namebuf);
> + ret = bpf_address_lookup(addr, symbolsize, offset,
> + modname, modbuildid, namebuf);
The initial bpf_address_lookup() 8 years ago was trying
to copy paste args and style of kallsyms_lookup().
It was odd back then. This change is doubling down on the wrong thing.
It's really odd to pass a pointer into bpf_address_lookup()
so it zero initializes it.
bpf ksyms are in the core kernel. They're never in modules.
Just call __bpf_address_lookup() here and remove the wrapper.
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH 3/6] kallsyms/bpf: Set module buildid in bpf_address_lookup()
2025-11-06 2:53 ` Alexei Starovoitov
@ 2025-11-07 13:08 ` Petr Mladek
2025-11-07 17:37 ` Alexei Starovoitov
0 siblings, 1 reply; 22+ messages in thread
From: Petr Mladek @ 2025-11-07 13:08 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: Petr Pavlu, Steven Rostedt, Alexei Starovoitov, Andrew Morton,
Kees Cook, Daniel Borkmann, John Fastabend, Masami Hiramatsu,
Mark Rutland, Luis Chamberlain, Daniel Gomez, Sami Tolvanen, LKML,
bpf, linux-modules, linux-trace-kernel
On Wed 2025-11-05 18:53:23, Alexei Starovoitov wrote:
> On Wed, Nov 5, 2025 at 6:24 AM Petr Mladek <pmladek@suse.com> wrote:
> >
> > Make bpf_address_lookup() compatible with module_address_lookup()
> > and clear the pointer to @modbuildid together with @modname.
> >
> > It is not strictly needed because __sprint_symbol() reads @modbuildid
> > only when @modname is set. But better be on the safe side and make
> > the API more safe.
> >
> > Fixes: 9294523e3768 ("module: add printk formats to add module build ID to stacktraces")
> > Signed-off-by: Petr Mladek <pmladek@suse.com>
> > ---
> > include/linux/filter.h | 15 +++++++++++----
> > kernel/kallsyms.c | 4 ++--
> > 2 files changed, 13 insertions(+), 6 deletions(-)
> >
> > diff --git a/include/linux/filter.h b/include/linux/filter.h
> > index f5c859b8131a..b7b95840250a 100644
> > --- a/include/linux/filter.h
> > +++ b/include/linux/filter.h
> > @@ -1362,12 +1362,18 @@ struct bpf_prog *bpf_prog_ksym_find(unsigned long addr);
> >
> > static inline int
> > bpf_address_lookup(unsigned long addr, unsigned long *size,
> > - unsigned long *off, char **modname, char *sym)
> > + unsigned long *off, char **modname,
> > + const unsigned char **modbuildid, char *sym)
> > {
> > int ret = __bpf_address_lookup(addr, size, off, sym);
> >
> > - if (ret && modname)
> > - *modname = NULL;
> > + if (ret) {
> > + if (modname)
> > + *modname = NULL;
> > + if (modbuildid)
> > + *modbuildid = NULL;
> > + }
> > +
> > return ret;
> > }
> >
> > @@ -1433,7 +1439,8 @@ static inline struct bpf_prog *bpf_prog_ksym_find(unsigned long addr)
> >
> > static inline int
> > bpf_address_lookup(unsigned long addr, unsigned long *size,
> > - unsigned long *off, char **modname, char *sym)
> > + unsigned long *off, char **modname,
> > + const unsigned char **modbuildid, char *sym)
> > {
> > return 0;
> > }
> > diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
> > index 9455e3bb07fc..efb12b077220 100644
> > --- a/kernel/kallsyms.c
> > +++ b/kernel/kallsyms.c
> > @@ -374,8 +374,8 @@ static int kallsyms_lookup_buildid(unsigned long addr,
> > ret = module_address_lookup(addr, symbolsize, offset,
> > modname, modbuildid, namebuf);
> > if (!ret)
> > - ret = bpf_address_lookup(addr, symbolsize,
> > - offset, modname, namebuf);
> > + ret = bpf_address_lookup(addr, symbolsize, offset,
> > + modname, modbuildid, namebuf);
>
> The initial bpf_address_lookup() 8 years ago was trying
> to copy paste args and style of kallsyms_lookup().
> It was odd back then. This change is doubling down on the wrong thing.
> It's really odd to pass a pointer into bpf_address_lookup()
> so it zero initializes it.
> bpf ksyms are in the core kernel. They're never in modules.
> Just call __bpf_address_lookup() here and remove the wrapper.
I agree that it is ugly. It would make sense to initialize the
pointers in kallsyms_lookup_buildid and call there
__bpf_address_lookup() variant. Something like:
static int kallsyms_lookup_buildid(unsigned long addr,
unsigned long *symbolsize,
unsigned long *offset, char **modname,
const unsigned char **modbuildid, char *namebuf)
{
int ret;
if (modname)
*modname = NULL;
if (modbuildid)
*modbuildid = NULL;
namebuf[0] = 0;
[...]
if (!ret)
ret = __bpf_address_lookup(addr, symbolsize, offset, namebuf);
}
As a result bpf_address_lookup() won't have any caller.
And __bpf_address_lookup() would have two callers.
It would make sense to remove bpf_address_lookup() and
rename __bpf_address_lookup() to bpf_address_lookup().
How does that sound?
Would you prefer to do this in one patch or in two steps, please?
Best Regards,
Petr
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH 3/6] kallsyms/bpf: Set module buildid in bpf_address_lookup()
2025-11-07 13:08 ` Petr Mladek
@ 2025-11-07 17:37 ` Alexei Starovoitov
0 siblings, 0 replies; 22+ messages in thread
From: Alexei Starovoitov @ 2025-11-07 17:37 UTC (permalink / raw)
To: Petr Mladek
Cc: Petr Pavlu, Steven Rostedt, Alexei Starovoitov, Andrew Morton,
Kees Cook, Daniel Borkmann, John Fastabend, Masami Hiramatsu,
Mark Rutland, Luis Chamberlain, Daniel Gomez, Sami Tolvanen, LKML,
bpf, linux-modules, linux-trace-kernel
On Fri, Nov 7, 2025 at 5:08 AM Petr Mladek <pmladek@suse.com> wrote:
>
> On Wed 2025-11-05 18:53:23, Alexei Starovoitov wrote:
> > On Wed, Nov 5, 2025 at 6:24 AM Petr Mladek <pmladek@suse.com> wrote:
> > >
> > > Make bpf_address_lookup() compatible with module_address_lookup()
> > > and clear the pointer to @modbuildid together with @modname.
> > >
> > > It is not strictly needed because __sprint_symbol() reads @modbuildid
> > > only when @modname is set. But better be on the safe side and make
> > > the API more safe.
> > >
> > > Fixes: 9294523e3768 ("module: add printk formats to add module build ID to stacktraces")
> > > Signed-off-by: Petr Mladek <pmladek@suse.com>
> > > ---
> > > include/linux/filter.h | 15 +++++++++++----
> > > kernel/kallsyms.c | 4 ++--
> > > 2 files changed, 13 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/include/linux/filter.h b/include/linux/filter.h
> > > index f5c859b8131a..b7b95840250a 100644
> > > --- a/include/linux/filter.h
> > > +++ b/include/linux/filter.h
> > > @@ -1362,12 +1362,18 @@ struct bpf_prog *bpf_prog_ksym_find(unsigned long addr);
> > >
> > > static inline int
> > > bpf_address_lookup(unsigned long addr, unsigned long *size,
> > > - unsigned long *off, char **modname, char *sym)
> > > + unsigned long *off, char **modname,
> > > + const unsigned char **modbuildid, char *sym)
> > > {
> > > int ret = __bpf_address_lookup(addr, size, off, sym);
> > >
> > > - if (ret && modname)
> > > - *modname = NULL;
> > > + if (ret) {
> > > + if (modname)
> > > + *modname = NULL;
> > > + if (modbuildid)
> > > + *modbuildid = NULL;
> > > + }
> > > +
> > > return ret;
> > > }
> > >
> > > @@ -1433,7 +1439,8 @@ static inline struct bpf_prog *bpf_prog_ksym_find(unsigned long addr)
> > >
> > > static inline int
> > > bpf_address_lookup(unsigned long addr, unsigned long *size,
> > > - unsigned long *off, char **modname, char *sym)
> > > + unsigned long *off, char **modname,
> > > + const unsigned char **modbuildid, char *sym)
> > > {
> > > return 0;
> > > }
> > > diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
> > > index 9455e3bb07fc..efb12b077220 100644
> > > --- a/kernel/kallsyms.c
> > > +++ b/kernel/kallsyms.c
> > > @@ -374,8 +374,8 @@ static int kallsyms_lookup_buildid(unsigned long addr,
> > > ret = module_address_lookup(addr, symbolsize, offset,
> > > modname, modbuildid, namebuf);
> > > if (!ret)
> > > - ret = bpf_address_lookup(addr, symbolsize,
> > > - offset, modname, namebuf);
> > > + ret = bpf_address_lookup(addr, symbolsize, offset,
> > > + modname, modbuildid, namebuf);
> >
> > The initial bpf_address_lookup() 8 years ago was trying
> > to copy paste args and style of kallsyms_lookup().
> > It was odd back then. This change is doubling down on the wrong thing.
> > It's really odd to pass a pointer into bpf_address_lookup()
> > so it zero initializes it.
> > bpf ksyms are in the core kernel. They're never in modules.
> > Just call __bpf_address_lookup() here and remove the wrapper.
>
> I agree that it is ugly. It would make sense to initialize the
> pointers in kallsyms_lookup_buildid and call there
> __bpf_address_lookup() variant. Something like:
>
> static int kallsyms_lookup_buildid(unsigned long addr,
> unsigned long *symbolsize,
> unsigned long *offset, char **modname,
> const unsigned char **modbuildid, char *namebuf)
> {
> int ret;
>
> if (modname)
> *modname = NULL;
> if (modbuildid)
> *modbuildid = NULL;
> namebuf[0] = 0;
> [...]
> if (!ret)
> ret = __bpf_address_lookup(addr, symbolsize, offset, namebuf);
>
> }
Yes. Exactly.
> As a result bpf_address_lookup() won't have any caller.
> And __bpf_address_lookup() would have two callers.
yep
> It would make sense to remove bpf_address_lookup() and
> rename __bpf_address_lookup() to bpf_address_lookup().
yep
> How does that sound?
> Would you prefer to do this in one patch or in two steps, please?
Whichever way is easier. I think it's fine to do it in one go,
though it crosses different subsystems.
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 4/6] kallsyms/ftrace: Set module buildid in ftrace_mod_address_lookup()
2025-11-05 14:23 [PATCH 0/6] kallsyms: Prevent invalid access when showing module buildid Petr Mladek
` (2 preceding siblings ...)
2025-11-05 14:23 ` [PATCH 3/6] kallsyms/bpf: Set module buildid in bpf_address_lookup() Petr Mladek
@ 2025-11-05 14:23 ` Petr Mladek
2025-11-05 16:22 ` Steven Rostedt
2025-11-07 22:49 ` Aaron Tomlin
2025-11-05 14:23 ` [PATCH 5/6] kallsyms: Clean up @namebuf initialization in kallsyms_lookup_buildid() Petr Mladek
2025-11-05 14:23 ` [PATCH 6/6] kallsyms: Prevent module removal when printing module name and buildid Petr Mladek
5 siblings, 2 replies; 22+ messages in thread
From: Petr Mladek @ 2025-11-05 14:23 UTC (permalink / raw)
To: Petr Pavlu, Steven Rostedt, Alexei Starovoitov, Andrew Morton,
Kees Cook
Cc: Daniel Borkmann, John Fastabend, Masami Hiramatsu, Mark Rutland,
Luis Chamberlain, Daniel Gomez, Sami Tolvanen, linux-kernel, bpf,
linux-modules, linux-trace-kernel, Petr Mladek
__sprint_symbol() might access an invalid pointer when
kallsyms_lookup_buildid() returns a symbol found by
ftrace_mod_address_lookup().
The ftrace lookup function must set both @modname and @modbuildid
the same way as module_address_lookup().
Fixes: 9294523e3768 ("module: add printk formats to add module build ID to stacktraces")
Signed-off-by: Petr Mladek <pmladek@suse.com>
---
include/linux/ftrace.h | 6 ++++--
kernel/kallsyms.c | 4 ++--
kernel/trace/ftrace.c | 5 ++++-
3 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index 7ded7df6e9b5..a003cf1b32d0 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -87,11 +87,13 @@ struct ftrace_hash;
defined(CONFIG_DYNAMIC_FTRACE)
int
ftrace_mod_address_lookup(unsigned long addr, unsigned long *size,
- unsigned long *off, char **modname, char *sym);
+ unsigned long *off, char **modname,
+ const unsigned char **modbuildid, char *sym);
#else
static inline int
ftrace_mod_address_lookup(unsigned long addr, unsigned long *size,
- unsigned long *off, char **modname, char *sym)
+ unsigned long *off, char **modname,
+ const unsigned char **modbuildid, char *sym)
{
return 0;
}
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index efb12b077220..71868a76e9a1 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -378,8 +378,8 @@ static int kallsyms_lookup_buildid(unsigned long addr,
modname, modbuildid, namebuf);
if (!ret)
- ret = ftrace_mod_address_lookup(addr, symbolsize,
- offset, modname, namebuf);
+ ret = ftrace_mod_address_lookup(addr, symbolsize, offset,
+ modname, modbuildid, namebuf);
return ret;
}
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 42bd2ba68a82..11f5096fb60c 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -7678,7 +7678,8 @@ ftrace_func_address_lookup(struct ftrace_mod_map *mod_map,
int
ftrace_mod_address_lookup(unsigned long addr, unsigned long *size,
- unsigned long *off, char **modname, char *sym)
+ unsigned long *off, char **modname,
+ const unsigned char **modbuildid, char *sym)
{
struct ftrace_mod_map *mod_map;
int ret = 0;
@@ -7690,6 +7691,8 @@ ftrace_mod_address_lookup(unsigned long addr, unsigned long *size,
if (ret) {
if (modname)
*modname = mod_map->mod->name;
+ if (modbuildid)
+ *modbuildid = module_buildid(mod_map->mod);
break;
}
}
--
2.51.1
^ permalink raw reply related [flat|nested] 22+ messages in thread* Re: [PATCH 4/6] kallsyms/ftrace: Set module buildid in ftrace_mod_address_lookup()
2025-11-05 14:23 ` [PATCH 4/6] kallsyms/ftrace: Set module buildid in ftrace_mod_address_lookup() Petr Mladek
@ 2025-11-05 16:22 ` Steven Rostedt
2025-11-07 22:49 ` Aaron Tomlin
1 sibling, 0 replies; 22+ messages in thread
From: Steven Rostedt @ 2025-11-05 16:22 UTC (permalink / raw)
To: Petr Mladek
Cc: Petr Pavlu, Alexei Starovoitov, Andrew Morton, Kees Cook,
Daniel Borkmann, John Fastabend, Masami Hiramatsu, Mark Rutland,
Luis Chamberlain, Daniel Gomez, Sami Tolvanen, linux-kernel, bpf,
linux-modules, linux-trace-kernel
On Wed, 5 Nov 2025 15:23:16 +0100
Petr Mladek <pmladek@suse.com> wrote:
> __sprint_symbol() might access an invalid pointer when
> kallsyms_lookup_buildid() returns a symbol found by
> ftrace_mod_address_lookup().
>
> The ftrace lookup function must set both @modname and @modbuildid
> the same way as module_address_lookup().
>
> Fixes: 9294523e3768 ("module: add printk formats to add module build ID to stacktraces")
> Signed-off-by: Petr Mladek <pmladek@suse.com>
> ---
> include/linux/ftrace.h | 6 ++++--
> kernel/kallsyms.c | 4 ++--
> kernel/trace/ftrace.c | 5 ++++-
> 3 files changed, 10 insertions(+), 5 deletions(-)
Acked-by: Steven Rostedt (Google) <rostedt@goodmis.org>
-- Steve
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH 4/6] kallsyms/ftrace: Set module buildid in ftrace_mod_address_lookup()
2025-11-05 14:23 ` [PATCH 4/6] kallsyms/ftrace: Set module buildid in ftrace_mod_address_lookup() Petr Mladek
2025-11-05 16:22 ` Steven Rostedt
@ 2025-11-07 22:49 ` Aaron Tomlin
1 sibling, 0 replies; 22+ messages in thread
From: Aaron Tomlin @ 2025-11-07 22:49 UTC (permalink / raw)
To: Petr Mladek
Cc: Petr Pavlu, Steven Rostedt, Alexei Starovoitov, Andrew Morton,
Kees Cook, Daniel Borkmann, John Fastabend, Masami Hiramatsu,
Mark Rutland, Luis Chamberlain, Daniel Gomez, Sami Tolvanen,
linux-kernel, bpf, linux-modules, linux-trace-kernel
On Wed, Nov 05, 2025 at 03:23:16PM +0100, Petr Mladek wrote:
> __sprint_symbol() might access an invalid pointer when
> kallsyms_lookup_buildid() returns a symbol found by
> ftrace_mod_address_lookup().
>
> The ftrace lookup function must set both @modname and @modbuildid
> the same way as module_address_lookup().
>
> Fixes: 9294523e3768 ("module: add printk formats to add module build ID to stacktraces")
> Signed-off-by: Petr Mladek <pmladek@suse.com>
> ---
> include/linux/ftrace.h | 6 ++++--
> kernel/kallsyms.c | 4 ++--
> kernel/trace/ftrace.c | 5 ++++-
> 3 files changed, 10 insertions(+), 5 deletions(-)
>
> diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
> index 7ded7df6e9b5..a003cf1b32d0 100644
> --- a/include/linux/ftrace.h
> +++ b/include/linux/ftrace.h
> @@ -87,11 +87,13 @@ struct ftrace_hash;
> defined(CONFIG_DYNAMIC_FTRACE)
> int
> ftrace_mod_address_lookup(unsigned long addr, unsigned long *size,
> - unsigned long *off, char **modname, char *sym);
> + unsigned long *off, char **modname,
> + const unsigned char **modbuildid, char *sym);
> #else
> static inline int
> ftrace_mod_address_lookup(unsigned long addr, unsigned long *size,
> - unsigned long *off, char **modname, char *sym)
> + unsigned long *off, char **modname,
> + const unsigned char **modbuildid, char *sym)
> {
> return 0;
> }
> diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
> index efb12b077220..71868a76e9a1 100644
> --- a/kernel/kallsyms.c
> +++ b/kernel/kallsyms.c
> @@ -378,8 +378,8 @@ static int kallsyms_lookup_buildid(unsigned long addr,
> modname, modbuildid, namebuf);
>
> if (!ret)
> - ret = ftrace_mod_address_lookup(addr, symbolsize,
> - offset, modname, namebuf);
> + ret = ftrace_mod_address_lookup(addr, symbolsize, offset,
> + modname, modbuildid, namebuf);
>
> return ret;
> }
> diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
> index 42bd2ba68a82..11f5096fb60c 100644
> --- a/kernel/trace/ftrace.c
> +++ b/kernel/trace/ftrace.c
> @@ -7678,7 +7678,8 @@ ftrace_func_address_lookup(struct ftrace_mod_map *mod_map,
>
> int
> ftrace_mod_address_lookup(unsigned long addr, unsigned long *size,
> - unsigned long *off, char **modname, char *sym)
> + unsigned long *off, char **modname,
> + const unsigned char **modbuildid, char *sym)
> {
> struct ftrace_mod_map *mod_map;
> int ret = 0;
> @@ -7690,6 +7691,8 @@ ftrace_mod_address_lookup(unsigned long addr, unsigned long *size,
> if (ret) {
> if (modname)
> *modname = mod_map->mod->name;
> + if (modbuildid)
> + *modbuildid = module_buildid(mod_map->mod);
> break;
> }
> }
> --
> 2.51.1
>
>
Reviewed-by: Aaron Tomlin <atomlin@atomlin.com>
--
Aaron Tomlin
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 5/6] kallsyms: Clean up @namebuf initialization in kallsyms_lookup_buildid()
2025-11-05 14:23 [PATCH 0/6] kallsyms: Prevent invalid access when showing module buildid Petr Mladek
` (3 preceding siblings ...)
2025-11-05 14:23 ` [PATCH 4/6] kallsyms/ftrace: Set module buildid in ftrace_mod_address_lookup() Petr Mladek
@ 2025-11-05 14:23 ` Petr Mladek
2025-11-07 22:50 ` Aaron Tomlin
2025-11-05 14:23 ` [PATCH 6/6] kallsyms: Prevent module removal when printing module name and buildid Petr Mladek
5 siblings, 1 reply; 22+ messages in thread
From: Petr Mladek @ 2025-11-05 14:23 UTC (permalink / raw)
To: Petr Pavlu, Steven Rostedt, Alexei Starovoitov, Andrew Morton,
Kees Cook
Cc: Daniel Borkmann, John Fastabend, Masami Hiramatsu, Mark Rutland,
Luis Chamberlain, Daniel Gomez, Sami Tolvanen, linux-kernel, bpf,
linux-modules, linux-trace-kernel, Petr Mladek
The function kallsyms_lookup_buildid() initializes the given @namebuf
by clearing the first and the last byte. It is not clear why.
The 1st byte makes sense because some callers ignore the return code
and expect that the buffer contains a valid string, for example:
- function_stat_show()
- kallsyms_lookup()
- kallsyms_lookup_buildid()
The initialization of the last byte does not make much sense because it
can later be overwritten. Fortunately, it seems that all called
functions behave correctly:
- kallsyms_expand_symbol() explicitly adds the trailing '\0'
at the end of the function.
- All *__address_lookup() functions either use the safe strscpy()
or they do not touch the buffer at all.
Document the reason for clearing the first byte. And remove the useless
initialization of the last byte.
Signed-off-by: Petr Mladek <pmladek@suse.com>
---
kernel/kallsyms.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index 71868a76e9a1..ff7017337535 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -352,7 +352,12 @@ static int kallsyms_lookup_buildid(unsigned long addr,
{
int ret;
- namebuf[KSYM_NAME_LEN - 1] = 0;
+ /*
+ * kallsyms_lookus() returns pointer to namebuf on success and
+ * NULL on error. But some callers ignore the return value.
+ * Instead they expect @namebuf filled either with valid
+ * or empty string.
+ */
namebuf[0] = 0;
if (is_ksym_addr(addr)) {
--
2.51.1
^ permalink raw reply related [flat|nested] 22+ messages in thread* Re: [PATCH 5/6] kallsyms: Clean up @namebuf initialization in kallsyms_lookup_buildid()
2025-11-05 14:23 ` [PATCH 5/6] kallsyms: Clean up @namebuf initialization in kallsyms_lookup_buildid() Petr Mladek
@ 2025-11-07 22:50 ` Aaron Tomlin
0 siblings, 0 replies; 22+ messages in thread
From: Aaron Tomlin @ 2025-11-07 22:50 UTC (permalink / raw)
To: Petr Mladek
Cc: Petr Pavlu, Steven Rostedt, Alexei Starovoitov, Andrew Morton,
Kees Cook, Daniel Borkmann, John Fastabend, Masami Hiramatsu,
Mark Rutland, Luis Chamberlain, Daniel Gomez, Sami Tolvanen,
linux-kernel, bpf, linux-modules, linux-trace-kernel
On Wed, Nov 05, 2025 at 03:23:17PM +0100, Petr Mladek wrote:
> The function kallsyms_lookup_buildid() initializes the given @namebuf
> by clearing the first and the last byte. It is not clear why.
>
> The 1st byte makes sense because some callers ignore the return code
> and expect that the buffer contains a valid string, for example:
>
> - function_stat_show()
> - kallsyms_lookup()
> - kallsyms_lookup_buildid()
>
> The initialization of the last byte does not make much sense because it
> can later be overwritten. Fortunately, it seems that all called
> functions behave correctly:
>
> - kallsyms_expand_symbol() explicitly adds the trailing '\0'
> at the end of the function.
>
> - All *__address_lookup() functions either use the safe strscpy()
> or they do not touch the buffer at all.
>
> Document the reason for clearing the first byte. And remove the useless
> initialization of the last byte.
>
> Signed-off-by: Petr Mladek <pmladek@suse.com>
> ---
> kernel/kallsyms.c | 7 ++++++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
> index 71868a76e9a1..ff7017337535 100644
> --- a/kernel/kallsyms.c
> +++ b/kernel/kallsyms.c
> @@ -352,7 +352,12 @@ static int kallsyms_lookup_buildid(unsigned long addr,
> {
> int ret;
>
> - namebuf[KSYM_NAME_LEN - 1] = 0;
> + /*
> + * kallsyms_lookus() returns pointer to namebuf on success and
> + * NULL on error. But some callers ignore the return value.
> + * Instead they expect @namebuf filled either with valid
> + * or empty string.
> + */
> namebuf[0] = 0;
>
> if (is_ksym_addr(addr)) {
> --
> 2.51.1
>
>
Reviewed-by: Aaron Tomlin <atomlin@atomlin.com>
--
Aaron Tomlin
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 6/6] kallsyms: Prevent module removal when printing module name and buildid
2025-11-05 14:23 [PATCH 0/6] kallsyms: Prevent invalid access when showing module buildid Petr Mladek
` (4 preceding siblings ...)
2025-11-05 14:23 ` [PATCH 5/6] kallsyms: Clean up @namebuf initialization in kallsyms_lookup_buildid() Petr Mladek
@ 2025-11-05 14:23 ` Petr Mladek
2025-11-08 0:36 ` Aaron Tomlin
2025-11-11 2:18 ` Aaron Tomlin
5 siblings, 2 replies; 22+ messages in thread
From: Petr Mladek @ 2025-11-05 14:23 UTC (permalink / raw)
To: Petr Pavlu, Steven Rostedt, Alexei Starovoitov, Andrew Morton,
Kees Cook
Cc: Daniel Borkmann, John Fastabend, Masami Hiramatsu, Mark Rutland,
Luis Chamberlain, Daniel Gomez, Sami Tolvanen, linux-kernel, bpf,
linux-modules, linux-trace-kernel, Petr Mladek
kallsyms_lookup_buildid() copies the symbol name into the given buffer
so that it can be safely read anytime later. But it just copies pointers
to mod->name and mod->build_id which might get reused after the related
struct module gets removed.
The lifetime of struct module is synchronized using RCU. Take the rcu
read lock for the entire __sprint_symbol().
Signed-off-by: Petr Mladek <pmladek@suse.com>
---
kernel/kallsyms.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index ff7017337535..1fda06b6638c 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -468,6 +468,9 @@ static int __sprint_symbol(char *buffer, unsigned long address,
unsigned long offset, size;
int len;
+ /* Prevent module removal until modname and modbuildid are printed */
+ guard(rcu)();
+
address += symbol_offset;
len = kallsyms_lookup_buildid(address, &size, &offset, &modname, &buildid,
buffer);
--
2.51.1
^ permalink raw reply related [flat|nested] 22+ messages in thread* Re: [PATCH 6/6] kallsyms: Prevent module removal when printing module name and buildid
2025-11-05 14:23 ` [PATCH 6/6] kallsyms: Prevent module removal when printing module name and buildid Petr Mladek
@ 2025-11-08 0:36 ` Aaron Tomlin
2025-11-10 13:26 ` Petr Mladek
2025-11-11 2:18 ` Aaron Tomlin
1 sibling, 1 reply; 22+ messages in thread
From: Aaron Tomlin @ 2025-11-08 0:36 UTC (permalink / raw)
To: Petr Mladek
Cc: Petr Pavlu, Steven Rostedt, Alexei Starovoitov, Andrew Morton,
Kees Cook, Daniel Borkmann, John Fastabend, Masami Hiramatsu,
Mark Rutland, Luis Chamberlain, Daniel Gomez, Sami Tolvanen,
linux-kernel, bpf, linux-modules, linux-trace-kernel
On Wed, Nov 05, 2025 at 03:23:18PM +0100, Petr Mladek wrote:
> kallsyms_lookup_buildid() copies the symbol name into the given buffer
> so that it can be safely read anytime later. But it just copies pointers
> to mod->name and mod->build_id which might get reused after the related
> struct module gets removed.
>
> The lifetime of struct module is synchronized using RCU. Take the rcu
> read lock for the entire __sprint_symbol().
>
> Signed-off-by: Petr Mladek <pmladek@suse.com>
> ---
> kernel/kallsyms.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
> index ff7017337535..1fda06b6638c 100644
> --- a/kernel/kallsyms.c
> +++ b/kernel/kallsyms.c
> @@ -468,6 +468,9 @@ static int __sprint_symbol(char *buffer, unsigned long address,
> unsigned long offset, size;
> int len;
>
> + /* Prevent module removal until modname and modbuildid are printed */
> + guard(rcu)();
> +
> address += symbol_offset;
> len = kallsyms_lookup_buildid(address, &size, &offset, &modname, &buildid,
> buffer);
> --
> 2.51.1
>
>
Hi Petr,
If I am not mistaken, this is handled safely within the context of
module_address_lookup() since f01369239293e ("module: Use RCU in
find_kallsyms_symbol()."), no?
Kind regards,
--
Aaron Tomlin
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH 6/6] kallsyms: Prevent module removal when printing module name and buildid
2025-11-08 0:36 ` Aaron Tomlin
@ 2025-11-10 13:26 ` Petr Mladek
2025-11-11 2:04 ` Aaron Tomlin
0 siblings, 1 reply; 22+ messages in thread
From: Petr Mladek @ 2025-11-10 13:26 UTC (permalink / raw)
To: Aaron Tomlin
Cc: Petr Pavlu, Steven Rostedt, Alexei Starovoitov, Andrew Morton,
Kees Cook, Daniel Borkmann, John Fastabend, Masami Hiramatsu,
Mark Rutland, Luis Chamberlain, Daniel Gomez, Sami Tolvanen,
linux-kernel, bpf, linux-modules, linux-trace-kernel
On Fri 2025-11-07 19:36:35, Aaron Tomlin wrote:
> On Wed, Nov 05, 2025 at 03:23:18PM +0100, Petr Mladek wrote:
> > kallsyms_lookup_buildid() copies the symbol name into the given buffer
> > so that it can be safely read anytime later. But it just copies pointers
> > to mod->name and mod->build_id which might get reused after the related
> > struct module gets removed.
> >
> > The lifetime of struct module is synchronized using RCU. Take the rcu
> > read lock for the entire __sprint_symbol().
> >
> > Signed-off-by: Petr Mladek <pmladek@suse.com>
> > ---
> > kernel/kallsyms.c | 3 +++
> > 1 file changed, 3 insertions(+)
> >
> > diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
> > index ff7017337535..1fda06b6638c 100644
> > --- a/kernel/kallsyms.c
> > +++ b/kernel/kallsyms.c
> > @@ -468,6 +468,9 @@ static int __sprint_symbol(char *buffer, unsigned long address,
> > unsigned long offset, size;
> > int len;
> >
> > + /* Prevent module removal until modname and modbuildid are printed */
> > + guard(rcu)();
> > +
> > address += symbol_offset;
> > len = kallsyms_lookup_buildid(address, &size, &offset, &modname, &buildid,
> > buffer);
> > --
> > 2.51.1
> >
> >
>
> Hi Petr,
>
> If I am not mistaken, this is handled safely within the context of
> module_address_lookup() since f01369239293e ("module: Use RCU in
> find_kallsyms_symbol()."), no?
The above mention commit fixed an API which is looking only for
the symbol name. It seems to be used, for example, in kprobe
or ftrace code.
This patch is fixing another API which is used in vsprintf() for
printing backtraces. It looks for more information: symbol name,
module name, and buildid. It needs its own RCU read protection.
Best Regards,
Petr
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH 6/6] kallsyms: Prevent module removal when printing module name and buildid
2025-11-10 13:26 ` Petr Mladek
@ 2025-11-11 2:04 ` Aaron Tomlin
0 siblings, 0 replies; 22+ messages in thread
From: Aaron Tomlin @ 2025-11-11 2:04 UTC (permalink / raw)
To: Petr Mladek
Cc: Petr Pavlu, Steven Rostedt, Alexei Starovoitov, Andrew Morton,
Kees Cook, Daniel Borkmann, John Fastabend, Masami Hiramatsu,
Mark Rutland, Luis Chamberlain, Daniel Gomez, Sami Tolvanen,
linux-kernel, bpf, linux-modules, linux-trace-kernel
On Mon, Nov 10, 2025 at 02:26:52PM +0100, Petr Mladek wrote:
> > Hi Petr,
> >
> > If I am not mistaken, this is handled safely within the context of
> > module_address_lookup() since f01369239293e ("module: Use RCU in
> > find_kallsyms_symbol()."), no?
>
> The above mention commit fixed an API which is looking only for
> the symbol name. It seems to be used, for example, in kprobe
> or ftrace code.
>
> This patch is fixing another API which is used in vsprintf() for
> printing backtraces. It looks for more information: symbol name,
> module name, and buildid. It needs its own RCU read protection.
Hi Petr,
I see and agree.
--
Aaron Tomlin
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 6/6] kallsyms: Prevent module removal when printing module name and buildid
2025-11-05 14:23 ` [PATCH 6/6] kallsyms: Prevent module removal when printing module name and buildid Petr Mladek
2025-11-08 0:36 ` Aaron Tomlin
@ 2025-11-11 2:18 ` Aaron Tomlin
1 sibling, 0 replies; 22+ messages in thread
From: Aaron Tomlin @ 2025-11-11 2:18 UTC (permalink / raw)
To: Petr Mladek
Cc: Petr Pavlu, Steven Rostedt, Alexei Starovoitov, Andrew Morton,
Kees Cook, Daniel Borkmann, John Fastabend, Masami Hiramatsu,
Mark Rutland, Luis Chamberlain, Daniel Gomez, Sami Tolvanen,
linux-kernel, bpf, linux-modules, linux-trace-kernel
On Wed, Nov 05, 2025 at 03:23:18PM +0100, Petr Mladek wrote:
> kallsyms_lookup_buildid() copies the symbol name into the given buffer
> so that it can be safely read anytime later. But it just copies pointers
> to mod->name and mod->build_id which might get reused after the related
> struct module gets removed.
>
> The lifetime of struct module is synchronized using RCU. Take the rcu
> read lock for the entire __sprint_symbol().
>
> Signed-off-by: Petr Mladek <pmladek@suse.com>
> ---
> kernel/kallsyms.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
> index ff7017337535..1fda06b6638c 100644
> --- a/kernel/kallsyms.c
> +++ b/kernel/kallsyms.c
> @@ -468,6 +468,9 @@ static int __sprint_symbol(char *buffer, unsigned long address,
> unsigned long offset, size;
> int len;
>
> + /* Prevent module removal until modname and modbuildid are printed */
> + guard(rcu)();
> +
> address += symbol_offset;
> len = kallsyms_lookup_buildid(address, &size, &offset, &modname, &buildid,
> buffer);
> --
> 2.51.1
Looks good to me.
Reviewed-by: Aaron Tomlin <atomlin@atomlin.com>
--
Aaron Tomlin
^ permalink raw reply [flat|nested] 22+ messages in thread