This patch adds two more API to libbpf: libbpf_enable_sys_bpf() and libbpf_disable_sys_bpf(). For root, these two APIs are no-op. Signed-off-by: Song Liu <songliubraving@xxxxxx> --- tools/lib/bpf/libbpf.c | 54 ++++++++++++++++++++++++++++++++++++++++ tools/lib/bpf/libbpf.h | 7 ++++++ tools/lib/bpf/libbpf.map | 2 ++ 3 files changed, 63 insertions(+) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 5186b7710430..449764840c5a 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -35,6 +35,7 @@ #include <sys/stat.h> #include <sys/types.h> #include <sys/vfs.h> +#include <sys/ioctl.h> #include <tools/libc_compat.h> #include <libelf.h> #include <gelf.h> @@ -4286,3 +4287,56 @@ int libbpf_num_possible_cpus(void) } return cpus; } + +LIBBPF_API bool libbpf_enable_sys_bpf(void) +{ + char *cp, errmsg[STRERR_BUFSIZE]; + int fd, ret; + + if (geteuid() == 0) + return true; + + fd = open(LIBBPF_DEV_BPF, O_WRONLY); + if (fd < 0) { + cp = libbpf_strerror_r(errno, errmsg, sizeof(errmsg)); + pr_warning("failed to open %s: %s\n", LIBBPF_DEV_BPF, cp); + return false; + } + + ret = ioctl(fd, BPF_DEV_IOCTL_ENABLE_SYS_BPF); + + if (ret) { + cp = libbpf_strerror_r(errno, errmsg, sizeof(errmsg)); + pr_warning("failed to enable access to sys_bpf(): %s\n", cp); + close(fd); + return false; + } + close(fd); + pr_debug("enabled access to sys_bpf() for non-privileged user\n"); + return true; +} + +LIBBPF_API void libbpf_disable_sys_bpf(void) +{ + char *cp, errmsg[STRERR_BUFSIZE]; + int fd, ret; + + if (geteuid() == 0) + return; + + fd = open(LIBBPF_DEV_BPF, O_WRONLY); + if (fd < 0) { + cp = libbpf_strerror_r(errno, errmsg, sizeof(errmsg)); + pr_warning("failed to open %s: %s\n", LIBBPF_DEV_BPF, cp); + return; + } + + ret = ioctl(fd, BPF_DEV_IOCTL_DISABLE_SYS_BPF); + if (ret) { + cp = libbpf_strerror_r(errno, errmsg, sizeof(errmsg)); + pr_warning("failed to disable access to sys_bpf(): %s\n", cp); + close(fd); + } + close(fd); + pr_debug("disabled access to sys_bpf() for non-privileged user\n"); +} diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h index d639f47e3110..0e3b9c0f1cdf 100644 --- a/tools/lib/bpf/libbpf.h +++ b/tools/lib/bpf/libbpf.h @@ -470,6 +470,13 @@ bpf_program__bpil_offs_to_addr(struct bpf_prog_info_linear *info_linear); */ LIBBPF_API int libbpf_num_possible_cpus(void); +#define LIBBPF_DEV_BPF "/dev/bpf" + +/* (For non-root user) get permission to access bpf() syscall */ +LIBBPF_API bool libbpf_enable_sys_bpf(void); +/* (For non-root user) put permission to access bpf() syscall */ +LIBBPF_API void libbpf_disable_sys_bpf(void); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map index 2c6d835620d2..c5951315a3a5 100644 --- a/tools/lib/bpf/libbpf.map +++ b/tools/lib/bpf/libbpf.map @@ -173,4 +173,6 @@ LIBBPF_0.0.4 { btf__parse_elf; bpf_object__load_xattr; libbpf_num_possible_cpus; + libbpf_enable_sys_bpf; + libbpf_disable_sys_bpf; } LIBBPF_0.0.3; -- 2.17.1