Linux Hardening
 help / color / mirror / Atom feed
* [PATCH v2 0/2] vsprintf: Don't leak pointers
@ 2026-08-21 15:26 Sebastian Andrzej Siewior
  2026-08-21 15:26 ` [PATCH v2 1/2] vsprintf: Don't leak pointers for %ps without KALLSYMS enabled Sebastian Andrzej Siewior
  2026-08-21 15:26 ` [PATCH v2 2/2] kallsyms: Document why unresolved symbols are revealed Sebastian Andrzej Siewior
  0 siblings, 2 replies; 8+ messages in thread
From: Sebastian Andrzej Siewior @ 2026-08-21 15:26 UTC (permalink / raw)
  To: linux-kernel, linux-hardening
  Cc: Andrew Morton, Andy Shevchenko, Kees Cook, Petr Mladek,
	Rasmus Villemoes, Sergey Senozhatsky, Steven Rostedt,
	Tycho Andersen, Sebastian Andrzej Siewior

It is possible to leak pointers via %ps without KALLSYMS enabled.
With KALLSYMS pointers can be leaked if they can not be resolved.

The tiny series has two patches, first addresses the first issue, the
second documents why we want to keep it that way.

v1…v2: https://lore.kernel.org/all/20260814144854.746840-1-bigeasy@linutronix.de/
  - For %ps and !KALLSYMS no_hash_pointers is used to decide if the
    pointer should be written or not. This aligns with the %p policy.
  - For %ps and KALLSYMS, unresolved pointer continue to be leaked. It
    has been pointed out it might be useful to see them in backtraces/
    crashes if the return address became invalid.

Sebastian Andrzej Siewior (1):
  vsprintf: Don't leak pointers for %ps without KALLSYMS enabled
  kallsyms: Document why unresolved symbols are revealed

 kernel/kallsyms.c | 7 ++++++-
 lib/vsprintf.c    | 4 +++-
 2 files changed, 9 insertions(+), 2 deletions(-)

-- 
2.55.0

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 1/2] vsprintf: Don't leak pointers for %ps without KALLSYMS enabled
  2026-08-21 15:26 [PATCH v2 0/2] vsprintf: Don't leak pointers Sebastian Andrzej Siewior
@ 2026-08-21 15:26 ` Sebastian Andrzej Siewior
  2026-08-26 15:56   ` Petr Mladek
  2026-08-21 15:26 ` [PATCH v2 2/2] kallsyms: Document why unresolved symbols are revealed Sebastian Andrzej Siewior
  1 sibling, 1 reply; 8+ messages in thread
From: Sebastian Andrzej Siewior @ 2026-08-21 15:26 UTC (permalink / raw)
  To: linux-kernel, linux-hardening
  Cc: Andrew Morton, Andy Shevchenko, Kees Cook, Petr Mladek,
	Rasmus Villemoes, Sergey Senozhatsky, Steven Rostedt,
	Tycho Andersen, Sebastian Andrzej Siewior

The "%ps" format modifier prints the name of the symbol which is more
valuable in terms of debugging and does not leak the actual pointer.

Without KALLSYMS it will leak the pointer which is not intended. The
default policy for pointers is to print a hashed value and not to leak
the actual pointer.

For !KALLSYMS, print "(unknown)" for any symbol resolution. If hashed
pointer are disabled print the bare number.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 lib/vsprintf.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 2bc6ef483576c..fcb63f22b1997 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -1008,7 +1008,9 @@ char *symbol_string(char *buf, char *end, void *ptr,
 
 	return string_nocheck(buf, end, sym, spec);
 #else
-	return special_hex_number(buf, end, value, sizeof(void *));
+	if (unlikely(no_hash_pointers))
+		return special_hex_number(buf, end, value, sizeof(void *));
+	return string_nocheck(buf, end, "(unknown)", spec);
 #endif
 }
 
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 2/2] kallsyms: Document why unresolved symbols are revealed
  2026-08-21 15:26 [PATCH v2 0/2] vsprintf: Don't leak pointers Sebastian Andrzej Siewior
  2026-08-21 15:26 ` [PATCH v2 1/2] vsprintf: Don't leak pointers for %ps without KALLSYMS enabled Sebastian Andrzej Siewior
@ 2026-08-21 15:26 ` Sebastian Andrzej Siewior
  2026-08-26 16:21   ` Petr Mladek
  1 sibling, 1 reply; 8+ messages in thread
From: Sebastian Andrzej Siewior @ 2026-08-21 15:26 UTC (permalink / raw)
  To: linux-kernel, linux-hardening
  Cc: Andrew Morton, Andy Shevchenko, Kees Cook, Petr Mladek,
	Rasmus Villemoes, Sergey Senozhatsky, Steven Rostedt,
	Tycho Andersen, Sebastian Andrzej Siewior

__sprint_symbol() is supposed to resolve the passed address to a symbol
name. If the symbol can not be resolved it will print the actual pointer
that was passed. The pointer policy is to not reveal actual pointer
values. However for post-mortem analysis of crashes it is helpful to see
the raw pointer if it is a corrupted pointer.

Document why raw unresolved pointers are printed.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 kernel/kallsyms.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index aec2f06858afd..983eae8d66f88 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -482,8 +482,13 @@ static int __sprint_symbol(char *buffer, unsigned long address,
 	address += symbol_offset;
 	len = kallsyms_lookup_buildid(address, &size, &offset, &modname, &buildid,
 				       buffer);
-	if (!len)
+	if (!len) {
+		/*
+		 * Print the raw pointer to allow post-mortem analysis of corrupted
+		 * pointer in backtraces.
+		 */
 		return sprintf(buffer, "0x%lx", address - symbol_offset);
+	}
 
 	offset -= symbol_offset;
 
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 1/2] vsprintf: Don't leak pointers for %ps without KALLSYMS enabled
  2026-08-21 15:26 ` [PATCH v2 1/2] vsprintf: Don't leak pointers for %ps without KALLSYMS enabled Sebastian Andrzej Siewior
@ 2026-08-26 15:56   ` Petr Mladek
  2026-08-27  9:14     ` Sebastian Andrzej Siewior
  0 siblings, 1 reply; 8+ messages in thread
From: Petr Mladek @ 2026-08-26 15:56 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: linux-kernel, linux-hardening, Andrew Morton, Andy Shevchenko,
	Kees Cook, Rasmus Villemoes, Sergey Senozhatsky, Steven Rostedt,
	Tycho Andersen

On Fri 2026-08-21 17:26:13, Sebastian Andrzej Siewior wrote:
> The "%ps" format modifier prints the name of the symbol which is more
> valuable in terms of debugging and does not leak the actual pointer.
> 
> Without KALLSYMS it will leak the pointer which is not intended. The
> default policy for pointers is to print a hashed value and not to leak
> the actual pointer.
> 
> For !KALLSYMS, print "(unknown)" for any symbol resolution. If hashed
> pointer are disabled print the bare number.
> 
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> ---
>  lib/vsprintf.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/lib/vsprintf.c b/lib/vsprintf.c
> index 2bc6ef483576c..fcb63f22b1997 100644
> --- a/lib/vsprintf.c
> +++ b/lib/vsprintf.c
> @@ -1008,7 +1008,9 @@ char *symbol_string(char *buf, char *end, void *ptr,
>  
>  	return string_nocheck(buf, end, sym, spec);
>  #else
> -	return special_hex_number(buf, end, value, sizeof(void *));
> +	if (unlikely(no_hash_pointers))
> +		return special_hex_number(buf, end, value, sizeof(void *));
> +	return string_nocheck(buf, end, "(unknown)", spec);
>  #endif
>  }

My understanding was that we were going to use

	return default_pointer(buf, end, ptr, spec);

It would print the hashed pointer unless no_hash_pointers was set.
IMHO, it would make the handling of pointer values more consistent.

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 2/2] kallsyms: Document why unresolved symbols are revealed
  2026-08-21 15:26 ` [PATCH v2 2/2] kallsyms: Document why unresolved symbols are revealed Sebastian Andrzej Siewior
@ 2026-08-26 16:21   ` Petr Mladek
  2026-08-27 10:24     ` Sebastian Andrzej Siewior
  0 siblings, 1 reply; 8+ messages in thread
From: Petr Mladek @ 2026-08-26 16:21 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: linux-kernel, linux-hardening, Andrew Morton, Andy Shevchenko,
	Kees Cook, Rasmus Villemoes, Sergey Senozhatsky, Steven Rostedt,
	Tycho Andersen, Linus Torvalds

Adding Linus into Cc.

On Fri 2026-08-21 17:26:14, Sebastian Andrzej Siewior wrote:
> __sprint_symbol() is supposed to resolve the passed address to a symbol
> name. If the symbol can not be resolved it will print the actual pointer
> that was passed. The pointer policy is to not reveal actual pointer
> values. However for post-mortem analysis of crashes it is helpful to see
> the raw pointer if it is a corrupted pointer.
> 
> Document why raw unresolved pointers are printed.

> --- a/kernel/kallsyms.c
> +++ b/kernel/kallsyms.c
> @@ -482,8 +482,13 @@ static int __sprint_symbol(char *buffer, unsigned long address,
>  	address += symbol_offset;
>  	len = kallsyms_lookup_buildid(address, &size, &offset, &modname, &buildid,
>  				       buffer);
> -	if (!len)
> +	if (!len) {
> +		/*
> +		 * Print the raw pointer to allow post-mortem analysis of corrupted
> +		 * pointer in backtraces.

This might be acceptable when the system is going to panic().
But is this formatting used only during panic?

> +		 */
>  		return sprintf(buffer, "0x%lx", address - symbol_offset);

I expected that we would replace this by "%p" so that the pointer got
hashed by default. After all, we suggest to use %ps because it should
not leak pointers.

Hmm, I see %ps or %pS used by many interfaces, like procfs, sysfs,
ftrace. Many of them are accessible only by root. Maybe, people expect
to see the valid pointers.

But we do not want to repeate the %pK eperience here. We could not
reliably check the access rights of the vsprintf() caller.
So, we should agree on the default behavior which does not
depend on the caller.

And I think that we want to reduce the risk of leaking.
So, I would use %p here.

If some callers really want to always print the real pointer when
the symbol is not resolved then we might add some modifier for
this, e.g. %p[SsB][R][p], where p would mean plain. But I am
not sure if we really want it.

> +	}
>  
>  	offset -= symbol_offset;

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 1/2] vsprintf: Don't leak pointers for %ps without KALLSYMS enabled
  2026-08-26 15:56   ` Petr Mladek
@ 2026-08-27  9:14     ` Sebastian Andrzej Siewior
  2026-08-27  9:51       ` Petr Mladek
  0 siblings, 1 reply; 8+ messages in thread
From: Sebastian Andrzej Siewior @ 2026-08-27  9:14 UTC (permalink / raw)
  To: Petr Mladek
  Cc: linux-kernel, linux-hardening, Andrew Morton, Andy Shevchenko,
	Kees Cook, Rasmus Villemoes, Sergey Senozhatsky, Steven Rostedt,
	Tycho Andersen

On 2026-08-26 17:56:12 [+0200], Petr Mladek wrote:
> On Fri 2026-08-21 17:26:13, Sebastian Andrzej Siewior wrote:
> > The "%ps" format modifier prints the name of the symbol which is more
> > valuable in terms of debugging and does not leak the actual pointer.
> > 
> > Without KALLSYMS it will leak the pointer which is not intended. The
> > default policy for pointers is to print a hashed value and not to leak
> > the actual pointer.
> > 
> > For !KALLSYMS, print "(unknown)" for any symbol resolution. If hashed
> > pointer are disabled print the bare number.
> > 
> > Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> > ---
> >  lib/vsprintf.c | 4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> > 
> > diff --git a/lib/vsprintf.c b/lib/vsprintf.c
> > index 2bc6ef483576c..fcb63f22b1997 100644
> > --- a/lib/vsprintf.c
> > +++ b/lib/vsprintf.c
> > @@ -1008,7 +1008,9 @@ char *symbol_string(char *buf, char *end, void *ptr,
> >  
> >  	return string_nocheck(buf, end, sym, spec);
> >  #else
> > -	return special_hex_number(buf, end, value, sizeof(void *));
> > +	if (unlikely(no_hash_pointers))
> > +		return special_hex_number(buf, end, value, sizeof(void *));
> > +	return string_nocheck(buf, end, "(unknown)", spec);
> >  #endif
> >  }
> 
> My understanding was that we were going to use
> 
> 	return default_pointer(buf, end, ptr, spec);
> 
> It would print the hashed pointer unless no_hash_pointers was set.
> IMHO, it would make the handling of pointer values more consistent.

The difference is that prints "Unknown" instead a value where a name was
expected. Look at this, we have now:

| # cat /proc/timer_list
…
|  next_event:     89340000000 nsecs
|  set_next_event: (unknown)
|  shutdown:       (unknown)
|  periodic:       (unknown)
|  oneshot:        (unknown)
|  oneshot stopped: (unknown)
|  event_handler:  (unknown)
…
| [    1.584810] ------------[ cut here ]------------
| [    1.584811] WARNING: init/main.c:1572 at (unknown), CPU#2: swapper/0/1
| [    1.584813] Modules linked in:
| [    1.584816] CPU: 2 UID: 0 PID: 1 Comm: swapper/0 Not tainted 7.2.0+ #66 PREEMPT_{RT,(lazy)}
| [    1.584819] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 2026.05-2 08/06/2026
| [    1.584820] RIP: 0010:(unknown)
| [    1.584821] Code: 74 46 e8 89 7c 2d ff e8 14 e5 42 ff e8 df c8 09 ff e8 ba 01 21 ff c7 05 04 2d 75 00 03 00 00 00 e8 8b bf 2b ff e8 56 1b 5c ff <0f> 0b 48 8b 3d bd 41 4a 00 48 85 ff 74 33 e8 33 60 09 ff 85 c0 75
| [    1.584823] RSP: 0018:ffffc90000023f30 EFLAGS: 00010292
| [    1.584825] RAX: ffff8881f8d0b000 RBX: ffffffff8216a030 RCX: ffff888102cae000
| [    1.584826] RDX: 0000000000000000 RSI: 0000000000000012 RDI: ffff8881002a3480
| [    1.584827] RBP: 0000000000000000 R08: ffff8881002a3480 R09: ffffea00040b2b80
| [    1.584828] R10: ffff888100041180 R11: ffffc90000023ec0 R12: ffffc90000023f58
| [    1.584829] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
| [    1.584833] FS:  0000000000000000(0000) GS:ffff8881f8d0b000(0000) knlGS:0000000000000000
| [    1.584834] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
| [    1.584835] CR2: 0000000000000000 CR3: 0000000002e46000 CR4: 00000000003506f0
| [    1.584837] Call Trace:
| [    1.584846]  <TASK>
| [    1.584847]  (unknown)
| [    1.584847]  ? (unknown)
| [    1.584849]  (unknown)
| [    1.584850]  </TASK>
| [    1.584850] ---[ end trace 0000000000000000 ]---

while printing a hashed pointer instead would give you:
| # cat /proc/timer_list
…
| next_event:     66384000000 nsecs
| set_next_event: 0000000095ee31e0
| shutdown:       00000000c838001a
| periodic:       000000002e3ab76e
| oneshot:        0000000019def7ac
| oneshot stopped: 00000000c838001a
| event_handler:  0000000053e7a80d
…
| [    1.498126] ------------[ cut here ]------------
| [    1.498127] WARNING: init/main.c:1572 at 000000007224a107, CPU#6: swapper/0/1
| [    1.498131] Modules linked in:
| [    1.498135] CPU: 6 UID: 0 PID: 1 Comm: swapper/0 Not tainted 7.2.0+ #68 PREEMPT_{RT,(lazy)}
| [    1.498138] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 2026.05-2 08/06/2026
| [    1.498140] RIP: 0010:000000007224a107
| [    1.498142] Code: 74 46 e8 e9 7c 2d ff e8 74 e5 42 ff e8 3f c9 09 ff e8 1a 02 21 ff c7 05 64 2d 75 00 03 00 00 00 e8 eb bf 2b ff e8 b6 1b 5c ff <0f> 0b 48 8b 3d 1d 42 4a 00 48 85 ff 74 33 e8 93 60 09 ff 85 c0 75
| [    1.498145] RSP: 0018:ffffc90000023f30 EFLAGS: 00010292
| [    1.498147] RAX: ffff8881f8e0b000 RBX: ffffffff82169fd0 RCX: ffff888102d9d2a0
| [    1.498149] RDX: 0000000000000000 RSI: 000000000000001e RDI: ffff8881002a3480
| [    1.498150] RBP: 0000000000000000 R08: ffff8881002a3480 R09: ffffea00040b6740
| [    1.498152] R10: ffff888100041180 R11: ffffc90000023ec0 R12: ffffc90000023f58
| [    1.498153] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
| [    1.498159] FS:  0000000000000000(0000) GS:ffff8881f8e0b000(0000) knlGS:0000000000000000
| [    1.498161] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
| [    1.498162] CR2: 0000000000000000 CR3: 0000000002e46000 CR4: 00000000003506f0
| [    1.498164] Call Trace:
| [    1.498171]  <TASK>
| [    1.498172]  00000000cb9bc262
| [    1.498174]  ? 00000000eb5021dd
| [    1.498176]  00000000ed1a9938
| [    1.498178]  </TASK>
| [    1.498179] ---[ end trace 0000000000000000 ]---

isn't this confusing? There is no added value in printing some random
numbers. Before this change you would also see "other" random values
with address randomisation. It confuses at best imho.

> Best Regards,
> Petr

Sebastian

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 1/2] vsprintf: Don't leak pointers for %ps without KALLSYMS enabled
  2026-08-27  9:14     ` Sebastian Andrzej Siewior
@ 2026-08-27  9:51       ` Petr Mladek
  0 siblings, 0 replies; 8+ messages in thread
From: Petr Mladek @ 2026-08-27  9:51 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: linux-kernel, linux-hardening, Andrew Morton, Andy Shevchenko,
	Kees Cook, Rasmus Villemoes, Sergey Senozhatsky, Steven Rostedt,
	Tycho Andersen

On Thu 2026-08-27 11:14:07, Sebastian Andrzej Siewior wrote:
> On 2026-08-26 17:56:12 [+0200], Petr Mladek wrote:
> > On Fri 2026-08-21 17:26:13, Sebastian Andrzej Siewior wrote:
> > > The "%ps" format modifier prints the name of the symbol which is more
> > > valuable in terms of debugging and does not leak the actual pointer.
> > > 
> > > Without KALLSYMS it will leak the pointer which is not intended. The
> > > default policy for pointers is to print a hashed value and not to leak
> > > the actual pointer.
> > > 
> > > For !KALLSYMS, print "(unknown)" for any symbol resolution. If hashed
> > > pointer are disabled print the bare number.
> > > 
> > > Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> > > ---
> > >  lib/vsprintf.c | 4 +++-
> > >  1 file changed, 3 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/lib/vsprintf.c b/lib/vsprintf.c
> > > index 2bc6ef483576c..fcb63f22b1997 100644
> > > --- a/lib/vsprintf.c
> > > +++ b/lib/vsprintf.c
> > > @@ -1008,7 +1008,9 @@ char *symbol_string(char *buf, char *end, void *ptr,
> > >  
> > >  	return string_nocheck(buf, end, sym, spec);
> > >  #else
> > > -	return special_hex_number(buf, end, value, sizeof(void *));
> > > +	if (unlikely(no_hash_pointers))
> > > +		return special_hex_number(buf, end, value, sizeof(void *));
> > > +	return string_nocheck(buf, end, "(unknown)", spec);
> > >  #endif
> > >  }
> > 
> > My understanding was that we were going to use
> > 
> > 	return default_pointer(buf, end, ptr, spec);
> > 
> > It would print the hashed pointer unless no_hash_pointers was set.
> > IMHO, it would make the handling of pointer values more consistent.
> 
> The difference is that prints "Unknown" instead a value where a name was
> expected. Look at this, we have now:
> 
> | # cat /proc/timer_list
> …
> |  next_event:     89340000000 nsecs
> |  set_next_event: (unknown)
> |  shutdown:       (unknown)
> |  periodic:       (unknown)
> |  oneshot:        (unknown)
> |  oneshot stopped: (unknown)
> |  event_handler:  (unknown)
> …
> | [    1.584810] ------------[ cut here ]------------
> | [    1.584811] WARNING: init/main.c:1572 at (unknown), CPU#2: swapper/0/1
> | [    1.584813] Modules linked in:
> | [    1.584816] CPU: 2 UID: 0 PID: 1 Comm: swapper/0 Not tainted 7.2.0+ #66 PREEMPT_{RT,(lazy)}
> | [    1.584819] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 2026.05-2 08/06/2026
> | [    1.584820] RIP: 0010:(unknown)
> | [    1.584821] Code: 74 46 e8 89 7c 2d ff e8 14 e5 42 ff e8 df c8 09 ff e8 ba 01 21 ff c7 05 04 2d 75 00 03 00 00 00 e8 8b bf 2b ff e8 56 1b 5c ff <0f> 0b 48 8b 3d bd 41 4a 00 48 85 ff 74 33 e8 33 60 09 ff 85 c0 75
> | [    1.584823] RSP: 0018:ffffc90000023f30 EFLAGS: 00010292
> | [    1.584825] RAX: ffff8881f8d0b000 RBX: ffffffff8216a030 RCX: ffff888102cae000
> | [    1.584826] RDX: 0000000000000000 RSI: 0000000000000012 RDI: ffff8881002a3480
> | [    1.584827] RBP: 0000000000000000 R08: ffff8881002a3480 R09: ffffea00040b2b80
> | [    1.584828] R10: ffff888100041180 R11: ffffc90000023ec0 R12: ffffc90000023f58
> | [    1.584829] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
> | [    1.584833] FS:  0000000000000000(0000) GS:ffff8881f8d0b000(0000) knlGS:0000000000000000
> | [    1.584834] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> | [    1.584835] CR2: 0000000000000000 CR3: 0000000002e46000 CR4: 00000000003506f0
> | [    1.584837] Call Trace:
> | [    1.584846]  <TASK>
> | [    1.584847]  (unknown)
> | [    1.584847]  ? (unknown)
> | [    1.584849]  (unknown)
> | [    1.584850]  </TASK>
> | [    1.584850] ---[ end trace 0000000000000000 ]---
> 
> while printing a hashed pointer instead would give you:
> | # cat /proc/timer_list
> …
> | next_event:     66384000000 nsecs
> | set_next_event: 0000000095ee31e0
> | shutdown:       00000000c838001a
> | periodic:       000000002e3ab76e
> | oneshot:        0000000019def7ac
> | oneshot stopped: 00000000c838001a
> | event_handler:  0000000053e7a80d
> …
> | [    1.498126] ------------[ cut here ]------------
> | [    1.498127] WARNING: init/main.c:1572 at 000000007224a107, CPU#6: swapper/0/1
> | [    1.498131] Modules linked in:
> | [    1.498135] CPU: 6 UID: 0 PID: 1 Comm: swapper/0 Not tainted 7.2.0+ #68 PREEMPT_{RT,(lazy)}
> | [    1.498138] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 2026.05-2 08/06/2026
> | [    1.498140] RIP: 0010:000000007224a107
> | [    1.498142] Code: 74 46 e8 e9 7c 2d ff e8 74 e5 42 ff e8 3f c9 09 ff e8 1a 02 21 ff c7 05 64 2d 75 00 03 00 00 00 e8 eb bf 2b ff e8 b6 1b 5c ff <0f> 0b 48 8b 3d 1d 42 4a 00 48 85 ff 74 33 e8 93 60 09 ff 85 c0 75
> | [    1.498145] RSP: 0018:ffffc90000023f30 EFLAGS: 00010292
> | [    1.498147] RAX: ffff8881f8e0b000 RBX: ffffffff82169fd0 RCX: ffff888102d9d2a0
> | [    1.498149] RDX: 0000000000000000 RSI: 000000000000001e RDI: ffff8881002a3480
> | [    1.498150] RBP: 0000000000000000 R08: ffff8881002a3480 R09: ffffea00040b6740
> | [    1.498152] R10: ffff888100041180 R11: ffffc90000023ec0 R12: ffffc90000023f58
> | [    1.498153] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
> | [    1.498159] FS:  0000000000000000(0000) GS:ffff8881f8e0b000(0000) knlGS:0000000000000000
> | [    1.498161] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> | [    1.498162] CR2: 0000000000000000 CR3: 0000000002e46000 CR4: 00000000003506f0
> | [    1.498164] Call Trace:
> | [    1.498171]  <TASK>
> | [    1.498172]  00000000cb9bc262
> | [    1.498174]  ? 00000000eb5021dd
> | [    1.498176]  00000000ed1a9938
> | [    1.498178]  </TASK>
> | [    1.498179] ---[ end trace 0000000000000000 ]---
> 
> isn't this confusing? There is no added value in printing some random
> numbers. Before this change you would also see "other" random values
> with address randomisation. It confuses at best imho.

I think that it is a matter of taste. I could understand that
"(unknown)" might look more obvious to some people.

I would still prefer the hashed pointer. It make it consistent with
%p handling. Both print addresses in this case.

The motivation for the hash in %p is that it is slightly more useful
than a static string, e.g. "(address)" or "(pointer)". The hash allows
to match the same addresses. It is not 100% reliable but better
than nothing.

Also the hash makes it more obvious the connection with "no_hash_pointer"
option.

IMHO, the only drawback is that people might confuse the hash with
a real value. But it is easier on 64-bit systems because the higher
32-bits are zeros.

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 2/2] kallsyms: Document why unresolved symbols are revealed
  2026-08-26 16:21   ` Petr Mladek
@ 2026-08-27 10:24     ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 8+ messages in thread
From: Sebastian Andrzej Siewior @ 2026-08-27 10:24 UTC (permalink / raw)
  To: Petr Mladek
  Cc: linux-kernel, linux-hardening, Andrew Morton, Andy Shevchenko,
	Kees Cook, Rasmus Villemoes, Sergey Senozhatsky, Steven Rostedt,
	Tycho Andersen, Linus Torvalds

On 2026-08-26 18:21:12 [+0200], Petr Mladek wrote:
> Adding Linus into Cc.
> 
> On Fri 2026-08-21 17:26:14, Sebastian Andrzej Siewior wrote:
> > __sprint_symbol() is supposed to resolve the passed address to a symbol
> > name. If the symbol can not be resolved it will print the actual pointer
> > that was passed. The pointer policy is to not reveal actual pointer
> > values. However for post-mortem analysis of crashes it is helpful to see
> > the raw pointer if it is a corrupted pointer.
> > 
> > Document why raw unresolved pointers are printed.
> 
> > --- a/kernel/kallsyms.c
> > +++ b/kernel/kallsyms.c
> > @@ -482,8 +482,13 @@ static int __sprint_symbol(char *buffer, unsigned long address,
> >  	address += symbol_offset;
> >  	len = kallsyms_lookup_buildid(address, &size, &offset, &modname, &buildid,
> >  				       buffer);
> > -	if (!len)
> > +	if (!len) {
> > +		/*
> > +		 * Print the raw pointer to allow post-mortem analysis of corrupted
> > +		 * pointer in backtraces.
> 
> This might be acceptable when the system is going to panic().
> But is this formatting used only during panic?

panic, bug, warning, stack backtrace, … everything using %p[sSB] where
the symbol can not be resolved to an actual function.

> > +		 */
> >  		return sprintf(buffer, "0x%lx", address - symbol_offset);
> 
> I expected that we would replace this by "%p" so that the pointer got
> hashed by default. After all, we suggest to use %ps because it should
> not leak pointers.
> 
> Hmm, I see %ps or %pS used by many interfaces, like procfs, sysfs,
> ftrace. Many of them are accessible only by root. Maybe, people expect
> to see the valid pointers.

For %p[sS] it should something in .text area either kernel or module. If
it can not be resolved then something went south. This can be either a
legitime case like in commit b86280aa48b67 ("kernel/kallsyms.c: fix %pB
when there's no symbol at the address") or the IP gets invalid due to
$reason and the system panics. Making this %p would mean you have to use
unhashed pointers just to see the unresolved pointer in the crash case.

> But we do not want to repeate the %pK eperience here. We could not
> reliably check the access rights of the vsprintf() caller.
> So, we should agree on the default behavior which does not
> depend on the caller.

We don't want that, yes.

> And I think that we want to reduce the risk of leaking.
> So, I would use %p here.
> 
> If some callers really want to always print the real pointer when
> the symbol is not resolved then we might add some modifier for
> this, e.g. %p[SsB][R][p], where p would mean plain. But I am
> not sure if we really want it.

That sounds like too much. The general policy should be what we want. So
if the IP gets to be entire nonsense I get

| BUG: unable to handle page fault for address: 0000000012345678                                                                                                    11:52 [2/1960]
| #PF: supervisor instruction fetch in kernel mode
| #PF: error_code(0x0010) - not-present page
| PGD 0 P4D 0 
| Oops: Oops: 0010 [#1] SMP NOPTI
| CPU: 6 UID: 0 PID: 1915 Comm: kworker/6:2 Tainted: G        W           7.2.0+ #72 PREEMPT_{RT,(lazy)} 
| Tainted: [W]=WARN
| Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 2026.05-2 08/06/2026
| Workqueue: events inv_func
| RIP: 0010:unresolved

The %pS that did get resolved (instead 0000000012345678).

| Code: Unable to access opcode bytes at 0x1234564e.
| RSP: 0018:ffffc900024c7e78 EFLAGS: 00010286
| RAX: ffffffff812691a0 RBX: ffff8881080f2780 RCX: 0000000000000006
| RDX: 0000000000000000 RSI: 000073746e657665 RDI: 0000000012345678
| RBP: ffff8881000ada00 R08: 8080808080808080 R09: ffff8881080f2808
| R10: ffff8881000964c0 R11: fefefefefefefeff R12: ffff88817bdaa500
| R13: ffff8881000ada05 R14: 0000000000000000 R15: ffffffff8280e000
| FS:  0000000000000000(0000) GS:ffff8881f8c09000(0000) knlGS:0000000000000000
| CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
| CR2: 0000000012345678 CR3: 000000010858d000 CR4: 00000000003506f0

and on x86 we have CR2

| Call Trace:
|  <TASK>
|  ? process_one_work+0x174/0x350
…

So given that "BUG:" here would print that information, the RIP %pS line
might now have to.
If I use a data pointer instead:
| kernel tried to execute NX-protected page - exploit attempt? (uid: 0)
| BUG: unable to handle page fault for address: ffffffff8280e000
| #PF: supervisor instruction fetch in kernel mode
| #PF: error_code(0x0011) - permissions violation
| PGD 3049067 P4D 3049067 PUD 304a063 PMD 80000000030001e3
| Oops: Oops: 0011 [#1] SMP NOPTI
| CPU: 6 UID: 0 PID: 1731 Comm: kworker/6:2 Tainted: G        W           7.2.0+ #73 PREEMPT_{RT,(lazy)}
| Tainted: [W]=WARN
| Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 2026.05-2 08/06/2026
| Workqueue: events inv_func
| RIP: 0010:unresolved
| Code: 00 00 66 2e 0f 1f 84 00 00 00 00 00 66 2e 0f 1f 84 00 00 00 00 00 66 2e 0f 1f 84 00 00 00 00 00 66 2e 0f 1f 84 00 00 00 00 00 <00> 00 40 03 00 00 00 00 08 e0 80 82 ff ff ff ff 08 e0 80 82 ff ff
| RSP: 0018:ffffc90001fc3e78 EFLAGS: 00010286
| RAX: ffffffff812691a0 RBX: ffff88810364e240 RCX: 0000000000000006
| RDX: 0000000000000000 RSI: 000073746e657665 RDI: ffffffff8280e000
| RBP: ffff8881000ada00 R08: 8080808080808080 R09: ffff88810364e2c8
| R10: ffff8881000964c0 R11: fefefefefefefeff R12: ffff88817bdaa500
| R13: ffff8881000ada05 R14: 0000000000000000 R15: ffffffff8280e000
| FS:  0000000000000000(0000) GS:ffff8881f8c09000(0000) knlGS:0000000000000000
| CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
| CR2: ffffffff8280e000 CR3: 0000000100ac6000 CR4: 00000000003506f0
| Call Trace:
|  <TASK>
|  ? process_one_work+0x174/0x350

given that, we could go back to (unknown) instead in the hashed case
instead of printing the pointer. I see the same kind of output for
arm64.
The only question would if that is enough for stack trace. But if so, I
would indeed suggest to replace it with "(unknown)" as I already had in
v1.

> > +	}
> >  
> >  	offset -= symbol_offset;
> 
> Best Regards,
> Petr

Sebastian

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-08-27 10:24 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-21 15:26 [PATCH v2 0/2] vsprintf: Don't leak pointers Sebastian Andrzej Siewior
2026-08-21 15:26 ` [PATCH v2 1/2] vsprintf: Don't leak pointers for %ps without KALLSYMS enabled Sebastian Andrzej Siewior
2026-08-26 15:56   ` Petr Mladek
2026-08-27  9:14     ` Sebastian Andrzej Siewior
2026-08-27  9:51       ` Petr Mladek
2026-08-21 15:26 ` [PATCH v2 2/2] kallsyms: Document why unresolved symbols are revealed Sebastian Andrzej Siewior
2026-08-26 16:21   ` Petr Mladek
2026-08-27 10:24     ` Sebastian Andrzej Siewior

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox