This patch adds two more API to libbpf: libbpf_get_bpf_permission() and libbpf_put_bpf_permission(). 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 68f45a96769f..cf2d68268bde 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_get_bpf_permission(void) +{ + char *cp, errmsg[STRERR_BUFSIZE]; + int fd, ret; + + if (geteuid() == 0) + return true; + + fd = open(LIBBPF_DEV_BPF, O_RDONLY); + 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_GET_PERM); + + if (ret) { + cp = libbpf_strerror_r(errno, errmsg, sizeof(errmsg)); + pr_warning("failed to get BPF permission: %s\n", cp); + close(fd); + return false; + } + close(fd); + pr_debug("got BPF permission for non-privileged user\n"); + return true; +} + +LIBBPF_API void libbpf_put_bpf_permission(void) +{ + char *cp, errmsg[STRERR_BUFSIZE]; + int fd, ret; + + if (geteuid() == 0) + return; + + fd = open(LIBBPF_DEV_BPF, O_RDONLY); + 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_PUT_PERM); + if (ret) { + cp = libbpf_strerror_r(errno, errmsg, sizeof(errmsg)); + pr_warning("failed to release BPF permission: %s\n", cp); + close(fd); + } + close(fd); + pr_debug("released BPF permission for non-privileged user\n"); +} diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h index d639f47e3110..22052c55a96c 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_get_bpf_permission(void); +/* (For non-root user) put permission to access bpf() syscall */ +LIBBPF_API void libbpf_put_bpf_permission(void); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map index 2c6d835620d2..93a2c4175fdd 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_get_bpf_permission; + libbpf_put_bpf_permission; } LIBBPF_0.0.3; -- 2.17.1