* [PATCH bpf-next v2 1/2] bpf: Mask pseudo pointer values in verifier logs
2026-06-23 10:43 [PATCH bpf-next v2 0/2] bpf: Mask pseudo pointer values in verifier logs Nuoqi Gui
@ 2026-06-23 10:43 ` Nuoqi Gui
2026-06-23 11:03 ` sashiko-bot
2026-06-23 10:43 ` [PATCH bpf-next v2 2/2] selftests/bpf: Cover pseudo-BTF ksym log masking Nuoqi Gui
` (2 subsequent siblings)
3 siblings, 1 reply; 7+ messages in thread
From: Nuoqi Gui @ 2026-06-23 10:43 UTC (permalink / raw)
To: Quentin Monnet, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi,
Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa,
Emil Tsalapatis, Hao Luo, Shuah Khan
Cc: Andrii Nakryiko, bpf, linux-kernel, linux-kselftest, Nuoqi Gui
print_bpf_insn() masks ldimm64 immediates for pointer-bearing pseudo
sources when pointer leaks are not allowed, but the mask only covers
BPF_PSEUDO_MAP_FD and BPF_PSEUDO_MAP_VALUE.
BPF_PSEUDO_MAP_IDX, BPF_PSEUDO_MAP_IDX_VALUE, and BPF_PSEUDO_BTF_ID can
also be resolved to kernel pointer values before the verifier log prints
the instruction. Include them in the existing pointer classification so
the log prints 0x0 instead of the rewritten address.
Fixes: 4976b718c355 ("bpf: Introduce pseudo_btf_id")
Fixes: 387544bfa291 ("bpf: Introduce fd_idx")
Signed-off-by: Nuoqi Gui <gnq25@mails.tsinghua.edu.cn>
---
kernel/bpf/disasm.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/kernel/bpf/disasm.c b/kernel/bpf/disasm.c
index f8a3c7eb451e..0391b3bc0073 100644
--- a/kernel/bpf/disasm.c
+++ b/kernel/bpf/disasm.c
@@ -323,7 +323,10 @@ void print_bpf_insn(const struct bpf_insn_cbs *cbs,
*/
u64 imm = ((u64)(insn + 1)->imm << 32) | (u32)insn->imm;
bool is_ptr = insn->src_reg == BPF_PSEUDO_MAP_FD ||
- insn->src_reg == BPF_PSEUDO_MAP_VALUE;
+ insn->src_reg == BPF_PSEUDO_MAP_VALUE ||
+ insn->src_reg == BPF_PSEUDO_MAP_IDX ||
+ insn->src_reg == BPF_PSEUDO_MAP_IDX_VALUE ||
+ insn->src_reg == BPF_PSEUDO_BTF_ID;
char tmp[64];
if (is_ptr && !allow_ptr_leaks)
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH bpf-next v2 1/2] bpf: Mask pseudo pointer values in verifier logs
2026-06-23 10:43 ` [PATCH bpf-next v2 1/2] " Nuoqi Gui
@ 2026-06-23 11:03 ` sashiko-bot
0 siblings, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-06-23 11:03 UTC (permalink / raw)
To: Nuoqi Gui; +Cc: bpf
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Translated BPF program dump (BPF_OBJ_GET_INFO_BY_FD) leaks physical kernel addresses from BPF_PSEUDO_BTF_ID instructions to users without CAP_PERFMON.
--
commit 302eadb037a969e2a3c9dbab8e1a08cf49f16888
Author: Nuoqi Gui <gnq25@mails.tsinghua.edu.cn>
bpf: Mask pseudo pointer values in verifier logs
This commit updates print_bpf_insn() to mask additional pointer-bearing
pseudo sources like BPF_PSEUDO_BTF_ID in verifier logs when pointer leaks
are not allowed.
> diff --git a/kernel/bpf/disasm.c b/kernel/bpf/disasm.c
> index f8a3c7eb451e4..0391b3bc00734 100644
> --- a/kernel/bpf/disasm.c
> +++ b/kernel/bpf/disasm.c
> @@ -323,7 +323,10 @@ void print_bpf_insn(const struct bpf_insn_cbs *cbs,
> */
> u64 imm = ((u64)(insn + 1)->imm << 32) | (u32)insn->imm;
> bool is_ptr = insn->src_reg == BPF_PSEUDO_MAP_FD ||
> - insn->src_reg == BPF_PSEUDO_MAP_VALUE;
> + insn->src_reg == BPF_PSEUDO_MAP_VALUE ||
> + insn->src_reg == BPF_PSEUDO_MAP_IDX ||
> + insn->src_reg == BPF_PSEUDO_MAP_IDX_VALUE ||
> + insn->src_reg == BPF_PSEUDO_BTF_ID;
[Severity: High]
This isn't a bug introduced by this patch, but does the kernel still leak
physical addresses from BPF_PSEUDO_BTF_ID instructions when a user without
CAP_PERFMON calls BPF_OBJ_GET_INFO_BY_FD to dump the translated program?
In kernel/bpf/verifier.c:convert_pseudo_ld_imm64(), the verifier clears
the src_reg for non-func pseudo loads after resolving the address:
if (insn->src_reg == BPF_PSEUDO_FUNC)
continue;
insn->src_reg = 0;
Later, when dumping the instructions in
kernel/bpf/syscall.c:bpf_insn_prepare_dump():
imm = ((u64)insns[i + 1].imm << 32) | (u32)insns[i].imm;
map = bpf_map_from_imm(prog, imm, &off, &type);
if (map) {
insns[i].src_reg = type;
insns[i].imm = map->id;
insns[i + 1].imm = off;
continue;
}
Because BPF_PSEUDO_BTF_ID resolves to a kernel symbol rather than a map,
bpf_map_from_imm() returns NULL. Since src_reg was zeroed by the verifier,
this code has no way to distinguish the leaked physical kernel address from
a normal 64-bit constant.
Could this allow users to retrieve raw kernel pointers, since there is no
fallback bpf_dump_raw_ok(f_cred) check here?
> char tmp[64];
>
> if (is_ptr && !allow_ptr_leaks)
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260623-f01-13-pseudo-btf-id-cap-bpf-v2-0-a190ebb8f3e2@mails.tsinghua.edu.cn?part=1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH bpf-next v2 2/2] selftests/bpf: Cover pseudo-BTF ksym log masking
2026-06-23 10:43 [PATCH bpf-next v2 0/2] bpf: Mask pseudo pointer values in verifier logs Nuoqi Gui
2026-06-23 10:43 ` [PATCH bpf-next v2 1/2] " Nuoqi Gui
@ 2026-06-23 10:43 ` Nuoqi Gui
2026-06-23 13:05 ` sashiko-bot
2026-06-25 20:38 ` [PATCH bpf-next v2 0/2] bpf: Mask pseudo pointer values in verifier logs Eduard Zingerman
2026-06-26 12:27 ` patchwork-bot+netdevbpf
3 siblings, 1 reply; 7+ messages in thread
From: Nuoqi Gui @ 2026-06-23 10:43 UTC (permalink / raw)
To: Quentin Monnet, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi,
Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa,
Emil Tsalapatis, Hao Luo, Shuah Khan
Cc: Andrii Nakryiko, bpf, linux-kernel, linux-kselftest, Nuoqi Gui
Add verifier_unpriv coverage for a raw socket-filter load of the
bpf_prog_active typed ksym. The test verifies that the unprivileged load
remains accepted and that the verbose verifier log prints the ldimm64
immediate as 0x0 instead of exposing a nonzero kernel address.
Signed-off-by: Nuoqi Gui <gnq25@mails.tsinghua.edu.cn>
---
tools/testing/selftests/bpf/progs/verifier_unpriv.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/tools/testing/selftests/bpf/progs/verifier_unpriv.c b/tools/testing/selftests/bpf/progs/verifier_unpriv.c
index c16f8382cf17..16de1595f015 100644
--- a/tools/testing/selftests/bpf/progs/verifier_unpriv.c
+++ b/tools/testing/selftests/bpf/progs/verifier_unpriv.c
@@ -6,6 +6,8 @@
#include "../../../include/linux/filter.h"
#include "bpf_misc.h"
+extern const int bpf_prog_active __ksym;
+
#define BPF_SK_LOOKUP(func) \
/* struct bpf_sock_tuple tuple = {} */ \
"r2 = 0;" \
@@ -77,6 +79,23 @@ __naked void dummy_prog_loop1_socket(void)
: __clobber_all);
}
+SEC("socket")
+__description("unpriv: pseudo btf id log masks address")
+__success_unpriv
+__msg_unpriv("0: (18) r1 = 0x0")
+__not_msg_unpriv("0: (18) r1 = 0x{{[1-9a-f][0-9a-f]*}}")
+__retval_unpriv(0)
+__log_level(2)
+__naked void pseudo_btf_id_log_masks_address(void)
+{
+ asm volatile ("r1 = %[bpf_prog_active] ll;"
+ "r0 = 0;"
+ "exit;"
+ :
+ : __imm_addr(bpf_prog_active)
+ : __clobber_all);
+}
+
SEC("socket")
__description("unpriv: return pointer")
__success __failure_unpriv __msg_unpriv("R0 leaks addr")
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH bpf-next v2 2/2] selftests/bpf: Cover pseudo-BTF ksym log masking
2026-06-23 10:43 ` [PATCH bpf-next v2 2/2] selftests/bpf: Cover pseudo-BTF ksym log masking Nuoqi Gui
@ 2026-06-23 13:05 ` sashiko-bot
0 siblings, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-06-23 13:05 UTC (permalink / raw)
To: Nuoqi Gui; +Cc: bpf
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [Critical] Unprivileged arbitrary kernel memory read via BPF_PSEUDO_BTF_ID leading to KASLR bypass and data leak.
--
commit 8c947383f7091d6bcf372bba38b8938dbc9b02e4
Author: Nuoqi Gui <gnq25@mails.tsinghua.edu.cn>
selftests/bpf: Cover pseudo-BTF ksym log masking
This commit adds a selftest to verify that an unprivileged raw socket-filter
can load the bpf_prog_active typed ksym. It ensures the load is accepted
and that the verifier log correctly masks the ldimm64 immediate address.
> diff --git a/tools/testing/selftests/bpf/progs/verifier_unpriv.c b/tools/testing/selftests/bpf/progs/verifier_unpriv.c
> index c16f8382cf17d..16de1595f0157 100644
> --- a/tools/testing/selftests/bpf/progs/verifier_unpriv.c
> +++ b/tools/testing/selftests/bpf/progs/verifier_unpriv.c
[ ... ]
> @@ -77,6 +79,23 @@ __naked void dummy_prog_loop1_socket(void)
> : __clobber_all);
> }
>
> +SEC("socket")
> +__description("unpriv: pseudo btf id log masks address")
> +__success_unpriv
> +__msg_unpriv("0: (18) r1 = 0x0")
> +__not_msg_unpriv("0: (18) r1 = 0x{{[1-9a-f][0-9a-f]*}}")
> +__retval_unpriv(0)
> +__log_level(2)
> +__naked void pseudo_btf_id_log_masks_address(void)
> +{
> + asm volatile ("r1 = %[bpf_prog_active] ll;"
[Severity: Critical]
This is a pre-existing issue, but by validating that unprivileged programs can
successfully load BPF_PSEUDO_BTF_ID instructions against btf_vmlinux, does
this highlight a potential KASLR bypass and kernel memory leak?
When an unprivileged user loads a BPF program using BPF_LD_IMM64 with
src_reg = BPF_PSEUDO_BTF_ID and the BTF ID of a non-struct kernel variable
(such as bpf_prog_active), __check_pseudo_btf_id() assigns the register
type PTR_TO_MEM | MEM_RDONLY:
kernel/bpf/verifier.c:__check_pseudo_btf_id() {
...
aux->btf_var.reg_type = PTR_TO_MEM | MEM_RDONLY;
aux->btf_var.mem_size = tsize;
...
}
If the user then issues a memory read instruction against this register,
check_mem_access() processes PTR_TO_MEM without enforcing
env->allow_ptr_leaks (unlike struct reads in check_ptr_to_btf_access):
kernel/bpf/verifier.c:check_mem_access() {
...
} else if (base_type(reg->type) == PTR_TO_MEM) {
...
if (!err && value_regno >= 0 && (t == BPF_READ || rdonly_mem))
mark_reg_unknown(env, regs, value_regno);
...
}
Could this resulting SCALAR_VALUE then be extracted via maps or return values,
allowing unprivileged attackers to read sensitive non-struct kernel variables?
> + "r0 = 0;"
> + "exit;"
> + :
> + : __imm_addr(bpf_prog_active)
> + : __clobber_all);
> +}
> +
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260623-f01-13-pseudo-btf-id-cap-bpf-v2-0-a190ebb8f3e2@mails.tsinghua.edu.cn?part=2
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH bpf-next v2 0/2] bpf: Mask pseudo pointer values in verifier logs
2026-06-23 10:43 [PATCH bpf-next v2 0/2] bpf: Mask pseudo pointer values in verifier logs Nuoqi Gui
2026-06-23 10:43 ` [PATCH bpf-next v2 1/2] " Nuoqi Gui
2026-06-23 10:43 ` [PATCH bpf-next v2 2/2] selftests/bpf: Cover pseudo-BTF ksym log masking Nuoqi Gui
@ 2026-06-25 20:38 ` Eduard Zingerman
2026-06-26 12:27 ` patchwork-bot+netdevbpf
3 siblings, 0 replies; 7+ messages in thread
From: Eduard Zingerman @ 2026-06-25 20:38 UTC (permalink / raw)
To: Nuoqi Gui, Quentin Monnet, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Kumar Kartikeya Dwivedi, Martin KaFai Lau,
Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis, Hao Luo,
Shuah Khan
Cc: Andrii Nakryiko, bpf, linux-kernel, linux-kselftest
On Tue, 2026-06-23 at 18:43 +0800, Nuoqi Gui wrote:
> Verifier log printing already hides ldimm64 immediates for map FD and
> map value pseudo sources when pointer leaks are not allowed. The same
> print path also sees rewritten immediates for BPF_PSEUDO_MAP_IDX,
> BPF_PSEUDO_MAP_IDX_VALUE, and BPF_PSEUDO_BTF_ID, but those sources were
> not included in the pointer classification.
>
> Extend the existing masking so all pointer-producing ldimm64 pseudo
> sources print as 0x0 when allow_ptr_leaks is false.
>
> Patch 1 extends the disassembler-side masking.
> Patch 2 adds verifier selftest coverage for pseudo-BTF ksym logs.
>
> Signed-off-by: Nuoqi Gui <gnq25@mails.tsinghua.edu.cn>
> ---
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
[...]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH bpf-next v2 0/2] bpf: Mask pseudo pointer values in verifier logs
2026-06-23 10:43 [PATCH bpf-next v2 0/2] bpf: Mask pseudo pointer values in verifier logs Nuoqi Gui
` (2 preceding siblings ...)
2026-06-25 20:38 ` [PATCH bpf-next v2 0/2] bpf: Mask pseudo pointer values in verifier logs Eduard Zingerman
@ 2026-06-26 12:27 ` patchwork-bot+netdevbpf
3 siblings, 0 replies; 7+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-06-26 12:27 UTC (permalink / raw)
To: Nuoqi Gui
Cc: qmo, ast, daniel, andrii, eddyz87, memxor, martin.lau, song,
yonghong.song, jolsa, emil, haoluo, shuah, andriin, bpf,
linux-kernel, linux-kselftest
Hello:
This series was applied to bpf/bpf.git (master)
by Alexei Starovoitov <ast@kernel.org>:
On Tue, 23 Jun 2026 18:43:37 +0800 you wrote:
> Verifier log printing already hides ldimm64 immediates for map FD and
> map value pseudo sources when pointer leaks are not allowed. The same
> print path also sees rewritten immediates for BPF_PSEUDO_MAP_IDX,
> BPF_PSEUDO_MAP_IDX_VALUE, and BPF_PSEUDO_BTF_ID, but those sources were
> not included in the pointer classification.
>
> Extend the existing masking so all pointer-producing ldimm64 pseudo
> sources print as 0x0 when allow_ptr_leaks is false.
>
> [...]
Here is the summary with links:
- [bpf-next,v2,1/2] bpf: Mask pseudo pointer values in verifier logs
https://git.kernel.org/bpf/bpf/c/72a85e9464a5
- [bpf-next,v2,2/2] selftests/bpf: Cover pseudo-BTF ksym log masking
https://git.kernel.org/bpf/bpf/c/8a870967ca61
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 7+ messages in thread