bpf: Support O_PATH FDs in BPF_OBJ_PIN and BPF_OBJ_GET commands
authorAndrii Nakryiko <andrii@kernel.org>
Mon, 15 May 2023 23:48:06 +0000 (16:48 -0700)
committerDaniel Borkmann <daniel@iogearbox.net>
Tue, 23 May 2023 21:31:42 +0000 (23:31 +0200)
commitcb8edce28073a906401c9e421eca7c99f3396da1
tree0b7b898cbc04c364be127c1ef05b76aa3a8d2596
parent2b001b94073be6097b1a4a21defc5cfbb7aa2f9f
bpf: Support O_PATH FDs in BPF_OBJ_PIN and BPF_OBJ_GET commands

Current UAPI of BPF_OBJ_PIN and BPF_OBJ_GET commands of bpf() syscall
forces users to specify pinning location as a string-based absolute or
relative (to current working directory) path. This has various
implications related to security (e.g., symlink-based attacks), forces
BPF FS to be exposed in the file system, which can cause races with
other applications.

One of the feedbacks we got from folks working with containers heavily
was that inability to use purely FD-based location specification was an
unfortunate limitation and hindrance for BPF_OBJ_PIN and BPF_OBJ_GET
commands. This patch closes this oversight, adding path_fd field to
BPF_OBJ_PIN and BPF_OBJ_GET UAPI, following conventions established by
*at() syscalls for dirfd + pathname combinations.

This now allows interesting possibilities like working with detached BPF
FS mount (e.g., to perform multiple pinnings without running a risk of
someone interfering with them), and generally making pinning/getting
more secure and not prone to any races and/or security attacks.

This is demonstrated by a selftest added in subsequent patch that takes
advantage of new mount APIs (fsopen, fsconfig, fsmount) to demonstrate
creating detached BPF FS mount, pinning, and then getting BPF map out of
it, all while never exposing this private instance of BPF FS to outside
worlds.

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Reviewed-by: Christian Brauner <brauner@kernel.org>
Link: https://lore.kernel.org/bpf/20230523170013.728457-4-andrii@kernel.org
include/linux/bpf.h
include/uapi/linux/bpf.h
kernel/bpf/inode.c
kernel/bpf/syscall.c
tools/include/uapi/linux/bpf.h