164 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */3 4#include <errno.h>5#include <string.h>6#include <linux/bpf.h>7#include <bpf/bpf_helpers.h>8#include "bpf_misc.h"9 10char _license[] SEC("license") = "GPL";11 12#define ITER_HELPERS \13 __imm(bpf_iter_num_new), \14 __imm(bpf_iter_num_next), \15 __imm(bpf_iter_num_destroy)16 17SEC("?raw_tp")18__success19int force_clang_to_emit_btf_for_externs(void *ctx)20{21 /* we need this as a workaround to enforce compiler emitting BTF22 * information for bpf_iter_num_{new,next,destroy}() kfuncs,23 * as, apparently, it doesn't emit it for symbols only referenced from24 * assembly (or cleanup attribute, for that matter, as well)25 */26 bpf_repeat(0);27 28 return 0;29}30 31SEC("?raw_tp")32__success33int consume_first_item_only(void *ctx)34{35 struct bpf_iter_num iter;36 37 asm volatile (38 /* create iterator */39 "r1 = %[iter];"40 "r2 = 0;"41 "r3 = 1000;"42 "call %[bpf_iter_num_new];"43 44 /* consume first item */45 "r1 = %[iter];"46 "call %[bpf_iter_num_next];"47 48 "if r0 == 0 goto +1;"49 "r0 = *(u32 *)(r0 + 0);"50 51 /* destroy iterator */52 "r1 = %[iter];"53 "call %[bpf_iter_num_destroy];"54 :55 : __imm_ptr(iter), ITER_HELPERS56 : __clobber_common57 );58 59 return 0;60}61 62SEC("?raw_tp")63__failure __msg("R0 invalid mem access 'scalar'")64int missing_null_check_fail(void *ctx)65{66 struct bpf_iter_num iter;67 68 asm volatile (69 /* create iterator */70 "r1 = %[iter];"71 "r2 = 0;"72 "r3 = 1000;"73 "call %[bpf_iter_num_new];"74 75 /* consume first element */76 "r1 = %[iter];"77 "call %[bpf_iter_num_next];"78 79 /* FAIL: deref with no NULL check */80 "r1 = *(u32 *)(r0 + 0);"81 82 /* destroy iterator */83 "r1 = %[iter];"84 "call %[bpf_iter_num_destroy];"85 :86 : __imm_ptr(iter), ITER_HELPERS87 : __clobber_common88 );89 90 return 0;91}92 93SEC("?raw_tp")94__failure95__msg("invalid access to memory, mem_size=4 off=0 size=8")96__msg("R0 min value is outside of the allowed memory range")97int wrong_sized_read_fail(void *ctx)98{99 struct bpf_iter_num iter;100 101 asm volatile (102 /* create iterator */103 "r1 = %[iter];"104 "r2 = 0;"105 "r3 = 1000;"106 "call %[bpf_iter_num_new];"107 108 /* consume first element */109 "r1 = %[iter];"110 "call %[bpf_iter_num_next];"111 112 "if r0 == 0 goto +1;"113 /* FAIL: deref more than available 4 bytes */114 "r0 = *(u64 *)(r0 + 0);"115 116 /* destroy iterator */117 "r1 = %[iter];"118 "call %[bpf_iter_num_destroy];"119 :120 : __imm_ptr(iter), ITER_HELPERS121 : __clobber_common122 );123 124 return 0;125}126 127SEC("?raw_tp")128__success __log_level(2)129__flag(BPF_F_TEST_STATE_FREQ)130int simplest_loop(void *ctx)131{132 struct bpf_iter_num iter;133 134 asm volatile (135 "r6 = 0;" /* init sum */136 137 /* create iterator */138 "r1 = %[iter];"139 "r2 = 0;"140 "r3 = 10;"141 "call %[bpf_iter_num_new];"142 143 "1:"144 /* consume next item */145 "r1 = %[iter];"146 "call %[bpf_iter_num_next];"147 148 "if r0 == 0 goto 2f;"149 "r0 = *(u32 *)(r0 + 0);"150 "r6 += r0;" /* accumulate sum */151 "goto 1b;"152 153 "2:"154 /* destroy iterator */155 "r1 = %[iter];"156 "call %[bpf_iter_num_destroy];"157 :158 : __imm_ptr(iter), ITER_HELPERS159 : __clobber_common, "r6"160 );161 162 return 0;163}164