* [PATCH bpf-next v2 0/2] bpf: Mask pseudo pointer values in verifier logs
@ 2026-06-23 10:43 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
0 siblings, 2 replies; 5+ 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
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>
---
Changes in v2:
- Replace the CAP_BPF gate with verifier-log masking in print_bpf_insn().
- Also mask BPF_PSEUDO_MAP_IDX and BPF_PSEUDO_MAP_IDX_VALUE immediates.
- Update selftests to check masked pseudo-BTF ksym logs.
- Link to v1: https://patch.msgid.link/20260620-f01-13-pseudo-btf-id-cap-bpf-v1-0-f950f69fe60c@mails.tsinghua.edu.cn
To: Quentin Monnet <qmo@kernel.org>
To: Alexei Starovoitov <ast@kernel.org>
To: Daniel Borkmann <daniel@iogearbox.net>
To: Andrii Nakryiko <andrii@kernel.org>
To: Eduard Zingerman <eddyz87@gmail.com>
To: Kumar Kartikeya Dwivedi <memxor@gmail.com>
To: Martin KaFai Lau <martin.lau@linux.dev>
To: Song Liu <song@kernel.org>
To: Yonghong Song <yonghong.song@linux.dev>
To: Jiri Olsa <jolsa@kernel.org>
To: Emil Tsalapatis <emil@etsalapatis.com>
To: Hao Luo <haoluo@google.com>
To: Shuah Khan <shuah@kernel.org>
Cc: Andrii Nakryiko <andriin@fb.com>
Cc: bpf@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-kselftest@vger.kernel.org
---
Nuoqi Gui (2):
bpf: Mask pseudo pointer values in verifier logs
selftests/bpf: Cover pseudo-BTF ksym log masking
kernel/bpf/disasm.c | 5 ++++-
tools/testing/selftests/bpf/progs/verifier_unpriv.c | 19 +++++++++++++++++++
2 files changed, 23 insertions(+), 1 deletion(-)
---
base-commit: a3847994b4d20c0701ccc54fe110920ea78e73dc
change-id: 20260619-f01-13-pseudo-btf-id-cap-bpf-585f98eac268
Best regards,
--
Nuoqi Gui <gnq25@mails.tsinghua.edu.cn>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [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
1 sibling, 1 reply; 5+ 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] 5+ 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
1 sibling, 1 reply; 5+ 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] 5+ 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; 5+ 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] 5+ 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; 5+ 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] 5+ messages in thread
end of thread, other threads:[~2026-06-23 13:05 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 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
2026-06-23 13:05 ` sashiko-bot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.