Re: netfilter: xt_bpf: Fix XT_BPF_MODE_FD_PINNED mode of 'xt_bpf_info_v1'

From: Willem de Bruijn
Date: Sat Dec 02 2017 - 23:23:12 EST


>> OK... See vfs.git#untested.mkobj; it really needs testing, though - mq_open(2)
>> passes LTP tests, but that's not saying much, and BPF side is completely
>> untested.
>
> ... and FWIW, completely untested patch for net/netfilter/xt_bpf.c follows:

Thanks a lot for this fix.

The tree including the bpf fix passes this basic xt_bpf test:

mount -t bpf bpf /sys/fs/bpf
./pin /sys/fs/bpf/pass
iptables -A INPUT -m bpf --object-pinned /sys/fs/bpf/five -j LOG
iptables -L INPUT
iptables -F INPUT

where pin is as follows:

diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index adeaa1302f34..0cd2bb8d634b 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -41,6 +41,7 @@ hostprogs-y += xdp_redirect_map
hostprogs-y += xdp_redirect_cpu
hostprogs-y += xdp_monitor
hostprogs-y += syscall_tp
+hostprogs-y += pin

# Libbpf dependencies
LIBBPF := ../../tools/lib/bpf/bpf.o
@@ -89,6 +90,7 @@ xdp_redirect_map-objs := bpf_load.o $(LIBBPF)
xdp_redirect_map_user.o
xdp_redirect_cpu-objs := bpf_load.o $(LIBBPF) xdp_redirect_cpu_user.o
xdp_monitor-objs := bpf_load.o $(LIBBPF) xdp_monitor_user.o
syscall_tp-objs := bpf_load.o $(LIBBPF) syscall_tp_user.o
+pin-objs := $(LIBBPF) pin.o

# Tell kbuild to always build the programs
always := $(hostprogs-y)
diff --git a/samples/bpf/pin.c b/samples/bpf/pin.c
new file mode 100644
index 000000000000..826e86784edf
--- /dev/null
+++ b/samples/bpf/pin.c
@@ -0,0 +1,41 @@
+#define _GNU_SOURCE
+
+#include <errno.h>
+#include <error.h>
+#include <linux/bpf.h>
+#include <linux/filter.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "libbpf.h"
+#include "bpf_load.h"
+
+static char log_buf[1 << 16];
+
+int main(int argc, char **argv)
+{
+ struct bpf_insn prog[] = {
+ BPF_MOV64_IMM(BPF_REG_0, 1),
+ BPF_EXIT_INSN(),
+ };
+ int fd;
+
+ if (argc != 2)
+ error(1, 0, "Usage: %s <filepath>\n", argv[0]);
+
+ fd = bpf_load_program(BPF_PROG_TYPE_SOCKET_FILTER, prog,
+ sizeof(prog) / sizeof(prog[0]),
+ "GPL", 0, log_buf, sizeof(log_buf));
+ if (fd == -1)
+ error(1, errno, "load: %s", log_buf);
+
+ if (bpf_obj_pin(fd, argv[1]))
+ error(1, errno, "pin");
+
+ if (close(fd))
+ error(1, errno, "close");
+
+ return 0;
+}