mirror of
https://github.com/torvalds/linux.git
synced 2026-09-12 12:34:02 +02:00
selftests/bpf: a demo for check_cond_jmp_op() non-null inference bug
A comparison between PTR_TO_MEM | MEM_RDONLY | PTR_UNTRUSTED and PTR_TO_MAP_VALUE_OR_NULL should not infer that map pointer is not null. A bug in check_cond_jmp_op() made such inference possible. Signed-off-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://lore.kernel.org/r/20260826-bug-029-bad-non-null-inference-v2-2-136789ace9e9@localhost Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
d3ef6c097b
commit
ce6dcd0aed
|
|
@ -3,7 +3,9 @@
|
|||
|
||||
#include <linux/bpf.h>
|
||||
#include <bpf/bpf_helpers.h>
|
||||
#include <stdbool.h>
|
||||
#include "bpf_misc.h"
|
||||
#include "bpf_kfuncs.h"
|
||||
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_XSKMAP);
|
||||
|
|
@ -12,6 +14,13 @@ struct {
|
|||
__type(value, int);
|
||||
} map_xskmap SEC(".maps");
|
||||
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_HASH);
|
||||
__uint(max_entries, 1);
|
||||
__type(key, int);
|
||||
__type(value, int);
|
||||
} map_hash SEC(".maps");
|
||||
|
||||
/* This is equivalent to the following program:
|
||||
*
|
||||
* r6 = skb->sk;
|
||||
|
|
@ -264,4 +273,47 @@ __naked void jne_reg_reg_null_check(void)
|
|||
: __clobber_all);
|
||||
}
|
||||
|
||||
/*
|
||||
* A comparison between PTR_TO_MEM | MEM_RDONLY | PTR_UNTRUSTED and
|
||||
* PTR_TO_MAP_VALUE_OR_NULL should not infer that map pointer is not null.
|
||||
* A bug in check_cond_jmp_op() made such inference possible.
|
||||
*/
|
||||
SEC("raw_tp")
|
||||
__failure
|
||||
__msg("error: invalid dereference of R0 (a nullable map value pointer)")
|
||||
__msg(">>> 11 | (61) r0 = *(u32 *)(r0 +0)")
|
||||
__naked void untrusted_mem_does_not_infer_map_value_non_null(void)
|
||||
{
|
||||
asm volatile (" \
|
||||
/* r6 = bpf_rdonly_cast(0, 0); */ \
|
||||
r1 = 0; \
|
||||
r2 = 0; \
|
||||
call %[bpf_rdonly_cast]; \
|
||||
r6 = r0; \
|
||||
/* r0 = bpf_map_lookup_elem(map_hash, &key); */ \
|
||||
*(u64 *)(r10 - 8) = 0; \
|
||||
r1 = %[map_hash] ll; \
|
||||
r2 = r10; \
|
||||
r2 += -8; \
|
||||
call %[bpf_map_lookup_elem]; \
|
||||
/* \
|
||||
* buggy verifier assumed that r6 can't be null \
|
||||
* and marked r0 non-null as well. \
|
||||
*/ \
|
||||
if r6 != r0 goto 1f; \
|
||||
r0 = *(u32 *)(r0 + 0); \
|
||||
1: r0 = 0; \
|
||||
exit; \
|
||||
" :
|
||||
: __imm(bpf_rdonly_cast),
|
||||
__imm(bpf_map_lookup_elem),
|
||||
__imm_addr(map_hash)
|
||||
: __clobber_all);
|
||||
}
|
||||
|
||||
void kfunc_root(void)
|
||||
{
|
||||
bpf_rdonly_cast(0, 0);
|
||||
}
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user