Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/bpf: Test for syscall program type

bpf_prog_type_syscall is a program that creates a bpf map,
updates it, and loads another bpf program using bpf_sys_bpf() helper.

Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20210514003623.28033-6-alexei.starovoitov@gmail.com

authored by

Alexei Starovoitov and committed by
Daniel Borkmann
00899e7e 5452fc9a

+123
+52
tools/testing/selftests/bpf/prog_tests/syscall.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) 2021 Facebook */ 3 + #include <test_progs.h> 4 + #include "syscall.skel.h" 5 + 6 + struct args { 7 + __u64 log_buf; 8 + __u32 log_size; 9 + int max_entries; 10 + int map_fd; 11 + int prog_fd; 12 + }; 13 + 14 + void test_syscall(void) 15 + { 16 + static char verifier_log[8192]; 17 + struct args ctx = { 18 + .max_entries = 1024, 19 + .log_buf = (uintptr_t) verifier_log, 20 + .log_size = sizeof(verifier_log), 21 + }; 22 + struct bpf_prog_test_run_attr tattr = { 23 + .ctx_in = &ctx, 24 + .ctx_size_in = sizeof(ctx), 25 + }; 26 + struct syscall *skel = NULL; 27 + __u64 key = 12, value = 0; 28 + int err; 29 + 30 + skel = syscall__open_and_load(); 31 + if (!ASSERT_OK_PTR(skel, "skel_load")) 32 + goto cleanup; 33 + 34 + tattr.prog_fd = bpf_program__fd(skel->progs.bpf_prog); 35 + err = bpf_prog_test_run_xattr(&tattr); 36 + ASSERT_EQ(err, 0, "err"); 37 + ASSERT_EQ(tattr.retval, 1, "retval"); 38 + ASSERT_GT(ctx.map_fd, 0, "ctx.map_fd"); 39 + ASSERT_GT(ctx.prog_fd, 0, "ctx.prog_fd"); 40 + ASSERT_OK(memcmp(verifier_log, "processed", sizeof("processed") - 1), 41 + "verifier_log"); 42 + 43 + err = bpf_map_lookup_elem(ctx.map_fd, &key, &value); 44 + ASSERT_EQ(err, 0, "map_lookup"); 45 + ASSERT_EQ(value, 34, "map lookup value"); 46 + cleanup: 47 + syscall__destroy(skel); 48 + if (ctx.prog_fd > 0) 49 + close(ctx.prog_fd); 50 + if (ctx.map_fd > 0) 51 + close(ctx.map_fd); 52 + }
+71
tools/testing/selftests/bpf/progs/syscall.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) 2021 Facebook */ 3 + #include <linux/stddef.h> 4 + #include <linux/bpf.h> 5 + #include <bpf/bpf_helpers.h> 6 + #include <bpf/bpf_tracing.h> 7 + #include <../../../tools/include/linux/filter.h> 8 + 9 + char _license[] SEC("license") = "GPL"; 10 + 11 + struct args { 12 + __u64 log_buf; 13 + __u32 log_size; 14 + int max_entries; 15 + int map_fd; 16 + int prog_fd; 17 + }; 18 + 19 + SEC("syscall") 20 + int bpf_prog(struct args *ctx) 21 + { 22 + static char license[] = "GPL"; 23 + static struct bpf_insn insns[] = { 24 + BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 25 + BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 26 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 27 + BPF_LD_MAP_FD(BPF_REG_1, 0), 28 + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), 29 + BPF_MOV64_IMM(BPF_REG_0, 0), 30 + BPF_EXIT_INSN(), 31 + }; 32 + static union bpf_attr map_create_attr = { 33 + .map_type = BPF_MAP_TYPE_HASH, 34 + .key_size = 8, 35 + .value_size = 8, 36 + }; 37 + static union bpf_attr map_update_attr = { .map_fd = 1, }; 38 + static __u64 key = 12; 39 + static __u64 value = 34; 40 + static union bpf_attr prog_load_attr = { 41 + .prog_type = BPF_PROG_TYPE_XDP, 42 + .insn_cnt = sizeof(insns) / sizeof(insns[0]), 43 + }; 44 + int ret; 45 + 46 + map_create_attr.max_entries = ctx->max_entries; 47 + prog_load_attr.license = (long) license; 48 + prog_load_attr.insns = (long) insns; 49 + prog_load_attr.log_buf = ctx->log_buf; 50 + prog_load_attr.log_size = ctx->log_size; 51 + prog_load_attr.log_level = 1; 52 + 53 + ret = bpf_sys_bpf(BPF_MAP_CREATE, &map_create_attr, sizeof(map_create_attr)); 54 + if (ret <= 0) 55 + return ret; 56 + ctx->map_fd = ret; 57 + insns[3].imm = ret; 58 + 59 + map_update_attr.map_fd = ret; 60 + map_update_attr.key = (long) &key; 61 + map_update_attr.value = (long) &value; 62 + ret = bpf_sys_bpf(BPF_MAP_UPDATE_ELEM, &map_update_attr, sizeof(map_update_attr)); 63 + if (ret < 0) 64 + return ret; 65 + 66 + ret = bpf_sys_bpf(BPF_PROG_LOAD, &prog_load_attr, sizeof(prog_load_attr)); 67 + if (ret <= 0) 68 + return ret; 69 + ctx->prog_fd = ret; 70 + return 1; 71 + }