1*a4985a17SQi Tang // SPDX-License-Identifier: GPL-2.0 2*a4985a17SQi Tang /* Copyright (c) 2026 Qi Tang */ 3*a4985a17SQi Tang 4*a4985a17SQi Tang #include <vmlinux.h> 5*a4985a17SQi Tang #include <bpf/bpf_helpers.h> 6*a4985a17SQi Tang #include "bpf_misc.h" 7*a4985a17SQi Tang 8*a4985a17SQi Tang char _license[] SEC("license") = "GPL"; 9*a4985a17SQi Tang 10*a4985a17SQi Tang /* Verify that the verifier rejects direct access to nullable PTR_TO_BUF. */ 11*a4985a17SQi Tang SEC("iter/bpf_map_elem") 12*a4985a17SQi Tang __failure __msg("invalid mem access") 13*a4985a17SQi Tang int iter_buf_null_deref(struct bpf_iter__bpf_map_elem *ctx) 14*a4985a17SQi Tang { 15*a4985a17SQi Tang /* 16*a4985a17SQi Tang * ctx->key is PTR_TO_BUF | PTR_MAYBE_NULL | MEM_RDONLY. 17*a4985a17SQi Tang * Direct access without null check must be rejected. 18*a4985a17SQi Tang */ 19*a4985a17SQi Tang volatile __u32 v = *(__u32 *)ctx->key; 20*a4985a17SQi Tang 21*a4985a17SQi Tang (void)v; 22*a4985a17SQi Tang return 0; 23*a4985a17SQi Tang } 24*a4985a17SQi Tang 25*a4985a17SQi Tang /* Verify that access after a null check is still accepted. */ 26*a4985a17SQi Tang SEC("iter/bpf_map_elem") 27*a4985a17SQi Tang __success 28*a4985a17SQi Tang int iter_buf_null_check_ok(struct bpf_iter__bpf_map_elem *ctx) 29*a4985a17SQi Tang { 30*a4985a17SQi Tang __u32 *key = ctx->key; 31*a4985a17SQi Tang 32*a4985a17SQi Tang if (!key) 33*a4985a17SQi Tang return 0; 34*a4985a17SQi Tang 35*a4985a17SQi Tang volatile __u32 v = *key; 36*a4985a17SQi Tang 37*a4985a17SQi Tang (void)v; 38*a4985a17SQi Tang return 0; 39*a4985a17SQi Tang } 40