]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bpf: Fix memory access flags in helper prototypes
authorZesen Liu <ftyghome@gmail.com>
Tue, 20 Jan 2026 08:28:46 +0000 (16:28 +0800)
committerAlexei Starovoitov <ast@kernel.org>
Wed, 21 Jan 2026 00:59:25 +0000 (16:59 -0800)
After commit 37cce22dbd51 ("bpf: verifier: Refactor helper access type tracking"),
the verifier started relying on the access type flags in helper
function prototypes to perform memory access optimizations.

Currently, several helper functions utilizing ARG_PTR_TO_MEM lack the
corresponding MEM_RDONLY or MEM_WRITE flags. This omission causes the
verifier to incorrectly assume that the buffer contents are unchanged
across the helper call. Consequently, the verifier may optimize away
subsequent reads based on this wrong assumption, leading to correctness
issues.

For bpf_get_stack_proto_raw_tp, the original MEM_RDONLY was incorrect
since the helper writes to the buffer. Change it to ARG_PTR_TO_UNINIT_MEM
which correctly indicates write access to potentially uninitialized memory.

Similar issues were recently addressed for specific helpers in commit
ac44dcc788b9 ("bpf: Fix verifier assumptions of bpf_d_path's output buffer")
and commit 2eb7648558a7 ("bpf: Specify access type of bpf_sysctl_get_name args").

Fix these prototypes by adding the correct memory access flags.

Fixes: 37cce22dbd51 ("bpf: verifier: Refactor helper access type tracking")
Co-developed-by: Shuran Liu <electronlsr@gmail.com>
Signed-off-by: Shuran Liu <electronlsr@gmail.com>
Co-developed-by: Peili Gao <gplhust955@gmail.com>
Signed-off-by: Peili Gao <gplhust955@gmail.com>
Co-developed-by: Haoran Ni <haoran.ni.cs@gmail.com>
Signed-off-by: Haoran Ni <haoran.ni.cs@gmail.com>
Signed-off-by: Zesen Liu <ftyghome@gmail.com>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20260120-helper_proto-v3-1-27b0180b4e77@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
kernel/bpf/helpers.c
kernel/bpf/syscall.c
kernel/trace/bpf_trace.c
net/core/filter.c

index f8aa1320e2f7ccabe9a521868bfbdd59a3c0421d..4d1af703cfcb28dc2341ee65b4a3a682b02c9b23 100644 (file)
@@ -1077,7 +1077,7 @@ const struct bpf_func_proto bpf_snprintf_proto = {
        .func           = bpf_snprintf,
        .gpl_only       = true,
        .ret_type       = RET_INTEGER,
-       .arg1_type      = ARG_PTR_TO_MEM_OR_NULL,
+       .arg1_type      = ARG_PTR_TO_MEM_OR_NULL | MEM_WRITE,
        .arg2_type      = ARG_CONST_SIZE_OR_ZERO,
        .arg3_type      = ARG_PTR_TO_CONST_STR,
        .arg4_type      = ARG_PTR_TO_MEM | PTR_MAYBE_NULL | MEM_RDONLY,
index ecc0929ce462930a5357daa87d4a22a4390612a6..3c5c03d43f5f74380dd23549971b666e89ecbe61 100644 (file)
@@ -6451,7 +6451,7 @@ static const struct bpf_func_proto bpf_kallsyms_lookup_name_proto = {
        .func           = bpf_kallsyms_lookup_name,
        .gpl_only       = false,
        .ret_type       = RET_INTEGER,
-       .arg1_type      = ARG_PTR_TO_MEM,
+       .arg1_type      = ARG_PTR_TO_MEM | MEM_RDONLY,
        .arg2_type      = ARG_CONST_SIZE_OR_ZERO,
        .arg3_type      = ARG_ANYTHING,
        .arg4_type      = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_WRITE | MEM_ALIGNED,
index f73e08c223b5b3a53eb4e71b4e94993a0de148f5..bd15ff62490b01eb20fc7e0f965c63361e30b18c 100644 (file)
@@ -1022,7 +1022,7 @@ const struct bpf_func_proto bpf_snprintf_btf_proto = {
        .func           = bpf_snprintf_btf,
        .gpl_only       = false,
        .ret_type       = RET_INTEGER,
-       .arg1_type      = ARG_PTR_TO_MEM,
+       .arg1_type      = ARG_PTR_TO_MEM | MEM_WRITE,
        .arg2_type      = ARG_CONST_SIZE,
        .arg3_type      = ARG_PTR_TO_MEM | MEM_RDONLY,
        .arg4_type      = ARG_CONST_SIZE,
@@ -1526,7 +1526,7 @@ static const struct bpf_func_proto bpf_read_branch_records_proto = {
        .gpl_only       = true,
        .ret_type       = RET_INTEGER,
        .arg1_type      = ARG_PTR_TO_CTX,
-       .arg2_type      = ARG_PTR_TO_MEM_OR_NULL,
+       .arg2_type      = ARG_PTR_TO_MEM_OR_NULL | MEM_WRITE,
        .arg3_type      = ARG_CONST_SIZE_OR_ZERO,
        .arg4_type      = ARG_ANYTHING,
 };
@@ -1661,7 +1661,7 @@ static const struct bpf_func_proto bpf_get_stack_proto_raw_tp = {
        .gpl_only       = true,
        .ret_type       = RET_INTEGER,
        .arg1_type      = ARG_PTR_TO_CTX,
-       .arg2_type      = ARG_PTR_TO_MEM | MEM_RDONLY,
+       .arg2_type      = ARG_PTR_TO_UNINIT_MEM,
        .arg3_type      = ARG_CONST_SIZE_OR_ZERO,
        .arg4_type      = ARG_ANYTHING,
 };
index d43df98e1deda10668ede0b11445260f52149bdb..d14401193b01d0373d41476c5ccc86dae35fa046 100644 (file)
@@ -6399,7 +6399,7 @@ static const struct bpf_func_proto bpf_xdp_fib_lookup_proto = {
        .gpl_only       = true,
        .ret_type       = RET_INTEGER,
        .arg1_type      = ARG_PTR_TO_CTX,
-       .arg2_type      = ARG_PTR_TO_MEM,
+       .arg2_type      = ARG_PTR_TO_MEM | MEM_WRITE,
        .arg3_type      = ARG_CONST_SIZE,
        .arg4_type      = ARG_ANYTHING,
 };
@@ -6454,7 +6454,7 @@ static const struct bpf_func_proto bpf_skb_fib_lookup_proto = {
        .gpl_only       = true,
        .ret_type       = RET_INTEGER,
        .arg1_type      = ARG_PTR_TO_CTX,
-       .arg2_type      = ARG_PTR_TO_MEM,
+       .arg2_type      = ARG_PTR_TO_MEM | MEM_WRITE,
        .arg3_type      = ARG_CONST_SIZE,
        .arg4_type      = ARG_ANYTHING,
 };
@@ -8008,9 +8008,9 @@ static const struct bpf_func_proto bpf_tcp_raw_gen_syncookie_ipv4_proto = {
        .gpl_only       = true, /* __cookie_v4_init_sequence() is GPL */
        .pkt_access     = true,
        .ret_type       = RET_INTEGER,
-       .arg1_type      = ARG_PTR_TO_FIXED_SIZE_MEM,
+       .arg1_type      = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_RDONLY,
        .arg1_size      = sizeof(struct iphdr),
-       .arg2_type      = ARG_PTR_TO_MEM,
+       .arg2_type      = ARG_PTR_TO_MEM | MEM_RDONLY,
        .arg3_type      = ARG_CONST_SIZE_OR_ZERO,
 };
 
@@ -8040,9 +8040,9 @@ static const struct bpf_func_proto bpf_tcp_raw_gen_syncookie_ipv6_proto = {
        .gpl_only       = true, /* __cookie_v6_init_sequence() is GPL */
        .pkt_access     = true,
        .ret_type       = RET_INTEGER,
-       .arg1_type      = ARG_PTR_TO_FIXED_SIZE_MEM,
+       .arg1_type      = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_RDONLY,
        .arg1_size      = sizeof(struct ipv6hdr),
-       .arg2_type      = ARG_PTR_TO_MEM,
+       .arg2_type      = ARG_PTR_TO_MEM | MEM_RDONLY,
        .arg3_type      = ARG_CONST_SIZE_OR_ZERO,
 };
 
@@ -8060,9 +8060,9 @@ static const struct bpf_func_proto bpf_tcp_raw_check_syncookie_ipv4_proto = {
        .gpl_only       = true, /* __cookie_v4_check is GPL */
        .pkt_access     = true,
        .ret_type       = RET_INTEGER,
-       .arg1_type      = ARG_PTR_TO_FIXED_SIZE_MEM,
+       .arg1_type      = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_RDONLY,
        .arg1_size      = sizeof(struct iphdr),
-       .arg2_type      = ARG_PTR_TO_FIXED_SIZE_MEM,
+       .arg2_type      = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_RDONLY,
        .arg2_size      = sizeof(struct tcphdr),
 };
 
@@ -8084,9 +8084,9 @@ static const struct bpf_func_proto bpf_tcp_raw_check_syncookie_ipv6_proto = {
        .gpl_only       = true, /* __cookie_v6_check is GPL */
        .pkt_access     = true,
        .ret_type       = RET_INTEGER,
-       .arg1_type      = ARG_PTR_TO_FIXED_SIZE_MEM,
+       .arg1_type      = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_RDONLY,
        .arg1_size      = sizeof(struct ipv6hdr),
-       .arg2_type      = ARG_PTR_TO_FIXED_SIZE_MEM,
+       .arg2_type      = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_RDONLY,
        .arg2_size      = sizeof(struct tcphdr),
 };
 #endif /* CONFIG_SYN_COOKIES */