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

samples/bpf: add a test for bpf_override_return

This adds a basic test for bpf_override_return to verify it works. We
override the main function for mounting a btrfs fs so it'll return
-ENOMEM and then make sure that trying to mount a btrfs fs will fail.

Acked-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Josef Bacik <jbacik@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Josef Bacik and committed by
Alexei Starovoitov
965de87e 9802d865

+71 -2
+4
samples/bpf/Makefile
··· 12 12 hostprogs-y += tracex4 13 13 hostprogs-y += tracex5 14 14 hostprogs-y += tracex6 15 + hostprogs-y += tracex7 15 16 hostprogs-y += test_probe_write_user 16 17 hostprogs-y += trace_output 17 18 hostprogs-y += lathist ··· 59 58 tracex4-objs := bpf_load.o $(LIBBPF) tracex4_user.o 60 59 tracex5-objs := bpf_load.o $(LIBBPF) tracex5_user.o 61 60 tracex6-objs := bpf_load.o $(LIBBPF) tracex6_user.o 61 + tracex7-objs := bpf_load.o $(LIBBPF) tracex7_user.o 62 62 load_sock_ops-objs := bpf_load.o $(LIBBPF) load_sock_ops.o 63 63 test_probe_write_user-objs := bpf_load.o $(LIBBPF) test_probe_write_user_user.o 64 64 trace_output-objs := bpf_load.o $(LIBBPF) trace_output_user.o ··· 103 101 always += tracex4_kern.o 104 102 always += tracex5_kern.o 105 103 always += tracex6_kern.o 104 + always += tracex7_kern.o 106 105 always += sock_flags_kern.o 107 106 always += test_probe_write_user_kern.o 108 107 always += trace_output_kern.o ··· 158 155 HOSTLOADLIBES_tracex4 += -lelf -lrt 159 156 HOSTLOADLIBES_tracex5 += -lelf 160 157 HOSTLOADLIBES_tracex6 += -lelf 158 + HOSTLOADLIBES_tracex7 += -lelf 161 159 HOSTLOADLIBES_test_cgrp2_sock2 += -lelf 162 160 HOSTLOADLIBES_load_sock_ops += -lelf 163 161 HOSTLOADLIBES_test_probe_write_user += -lelf
+15
samples/bpf/test_override_return.sh
··· 1 + #!/bin/bash 2 + 3 + rm -f testfile.img 4 + dd if=/dev/zero of=testfile.img bs=1M seek=1000 count=1 5 + DEVICE=$(losetup --show -f testfile.img) 6 + mkfs.btrfs -f $DEVICE 7 + mkdir tmpmnt 8 + ./tracex7 $DEVICE 9 + if [ $? -eq 0 ] 10 + then 11 + echo "SUCCESS!" 12 + else 13 + echo "FAILED!" 14 + fi 15 + losetup -d $DEVICE
+16
samples/bpf/tracex7_kern.c
··· 1 + #include <uapi/linux/ptrace.h> 2 + #include <uapi/linux/bpf.h> 3 + #include <linux/version.h> 4 + #include "bpf_helpers.h" 5 + 6 + SEC("kprobe/open_ctree") 7 + int bpf_prog1(struct pt_regs *ctx) 8 + { 9 + unsigned long rc = -12; 10 + 11 + bpf_override_return(ctx, rc); 12 + return 0; 13 + } 14 + 15 + char _license[] SEC("license") = "GPL"; 16 + u32 _version SEC("version") = LINUX_VERSION_CODE;
+28
samples/bpf/tracex7_user.c
··· 1 + #define _GNU_SOURCE 2 + 3 + #include <stdio.h> 4 + #include <linux/bpf.h> 5 + #include <unistd.h> 6 + #include "libbpf.h" 7 + #include "bpf_load.h" 8 + 9 + int main(int argc, char **argv) 10 + { 11 + FILE *f; 12 + char filename[256]; 13 + char command[256]; 14 + int ret; 15 + 16 + snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); 17 + 18 + if (load_bpf_file(filename)) { 19 + printf("%s", bpf_log_buf); 20 + return 1; 21 + } 22 + 23 + snprintf(command, 256, "mount %s tmpmnt/", argv[1]); 24 + f = popen(command, "r"); 25 + ret = pclose(f); 26 + 27 + return ret ? 0 : 1; 28 + }
+6 -1
tools/include/uapi/linux/bpf.h
··· 677 677 * @buf: buf to fill 678 678 * @buf_size: size of the buf 679 679 * Return : 0 on success or negative error code 680 + * 681 + * int bpf_override_return(pt_regs, rc) 682 + * @pt_regs: pointer to struct pt_regs 683 + * @rc: the return value to set 680 684 */ 681 685 #define __BPF_FUNC_MAPPER(FN) \ 682 686 FN(unspec), \ ··· 740 736 FN(xdp_adjust_meta), \ 741 737 FN(perf_event_read_value), \ 742 738 FN(perf_prog_read_value), \ 743 - FN(getsockopt), 739 + FN(getsockopt), \ 740 + FN(override_return), 744 741 745 742 /* integer value in 'imm' field of BPF_CALL instruction selects which helper 746 743 * function eBPF program intends to call
+2 -1
tools/testing/selftests/bpf/bpf_helpers.h
··· 82 82 static int (*bpf_perf_prog_read_value)(void *ctx, void *buf, 83 83 unsigned int buf_size) = 84 84 (void *) BPF_FUNC_perf_prog_read_value; 85 - 85 + static int (*bpf_override_return)(void *ctx, unsigned long rc) = 86 + (void *) BPF_FUNC_override_return; 86 87 87 88 /* llvm builtin functions that eBPF C program may use to 88 89 * emit BPF_LD_ABS and BPF_LD_IND instructions