* [PATCH v3 1/2] vsprintf: Don't leak pointers for %ps without KALLSYMS enabled
2026-10-15 16:06 [PATCH v3 0/2] vsprintf: Don't leak pointers Sebastian Andrzej Siewior
@ 2026-10-15 16:06 ` Sebastian Andrzej Siewior
2026-10-15 16:06 ` [PATCH v3 2/2] kallsyms: Don't leak pointers for unresolved symbols Sebastian Andrzej Siewior
1 sibling, 0 replies; 3+ messages in thread
From: Sebastian Andrzej Siewior @ 2026-10-15 16:06 UTC (permalink / raw)
To: linux-kernel
Cc: Sebastian Andrzej Siewior, Andrew Morton, Andy Shevchenko,
Kees Cook, Petr Mladek, Rasmus Villemoes, Sergey Senozhatsky,
Steven Rostedt, Tycho Andersen
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.
Print a hashed pointer for any symbol resolution witout KALLSYMS
enabled like it is the case for %p.
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
lib/vsprintf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 1d95ab9314bf7..a3db25cc1e567 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -1008,7 +1008,7 @@ 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 *));
+ return default_pointer(buf, end, ptr, spec);
#endif
}
--
2.55.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH v3 2/2] kallsyms: Don't leak pointers for unresolved symbols
2026-10-15 16:06 [PATCH v3 0/2] vsprintf: Don't leak pointers Sebastian Andrzej Siewior
2026-10-15 16:06 ` [PATCH v3 1/2] vsprintf: Don't leak pointers for %ps without KALLSYMS enabled Sebastian Andrzej Siewior
@ 2026-10-15 16:06 ` Sebastian Andrzej Siewior
1 sibling, 0 replies; 3+ messages in thread
From: Sebastian Andrzej Siewior @ 2026-10-15 16:06 UTC (permalink / raw)
To: linux-kernel
Cc: Sebastian Andrzej Siewior, Andrew Morton, Andy Shevchenko,
Kees Cook, Petr Mladek, Rasmus Villemoes, Sergey Senozhatsky,
Steven Rostedt, Tycho Andersen, Namhyung Kim
__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.
For post-mortem analysis the pointer in the backtrace shouldn't be
relevant. In BUG(), WARN() and panic() related backtraces the PC
register will contain the actual value.
Add snprintf_default_pointer() as a wrapper around default_pointer() and
use it __sprint_symbol() if the pointer has not been resolved.
Cc: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
include/linux/sprintf.h | 1 +
kernel/kallsyms.c | 3 ++-
lib/vsprintf.c | 25 +++++++++++++++++++++++++
3 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/include/linux/sprintf.h b/include/linux/sprintf.h
index f06f7b7850911..596c73a57371e 100644
--- a/include/linux/sprintf.h
+++ b/include/linux/sprintf.h
@@ -24,6 +24,7 @@ __scanf(2, 0) int vsscanf(const char *, const char *, va_list);
/* These are for specific cases, do not use without real need */
extern bool no_hash_pointers;
void hash_pointers_finalize(bool slub_debug);
+int snprintf_default_pointer(char *buf, unsigned int len, const void *ptr);
/* Used for Rust formatting ('%pA') */
char *rust_fmt_argument(char *buf, char *end, const void *ptr);
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index aec2f06858afd..5d51c825c1e71 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -483,7 +483,8 @@ static int __sprint_symbol(char *buffer, unsigned long address,
len = kallsyms_lookup_buildid(address, &size, &offset, &modname, &buildid,
buffer);
if (!len)
- return sprintf(buffer, "0x%lx", address - symbol_offset);
+ return snprintf_default_pointer(buffer, KSYM_SYMBOL_LEN,
+ (void *)(address - symbol_offset));
offset -= symbol_offset;
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index a3db25cc1e567..0ed7134ad2f41 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -849,6 +849,31 @@ static char *default_pointer(char *buf, char *end, const void *ptr,
return ptr_to_id(buf, end, ptr, spec);
}
+/**
+ * snprintf_default_pointer - Format a pointer and place it in a buffer
+ * @buf: The buffer to place the result into
+ * @size: The size of the buffer, including the trailing null space
+ * @ptr: The pointer to format
+ *
+ * Formats the passed pointer the same way as the %p modifier. Does not write
+ * more than len bytes to buf including the NULL terminator.
+ *
+ * Returns the number of written bytes.
+ */
+int snprintf_default_pointer(char *buf, unsigned int len, const void *ptr)
+{
+ struct printf_spec spec = {
+ .base = 10,
+ .precision = -1,
+ .field_width = -1,
+ };
+ char *endp;
+
+ endp = default_pointer(buf, buf + len, ptr, spec);
+ *endp = '\0';
+ return endp - buf;
+}
+
int kptr_restrict __read_mostly;
EXPORT_SYMBOL_FOR_MODULES(kptr_restrict, "printf_kunit");
--
2.55.0
^ permalink raw reply [flat|nested] 3+ messages in thread