bpfLock: avoid using ifAtLeastKernelVersion()
Per inspection of:
https://source.corp.google.com/h/prodkernel/kernel/upstream/torvalds/linux-2.6/+/master:kernel/bpf/syscall.c;drc=2884dc7d08d98a89d8d65121524bb7533183a63a;l=5786
bpf system call returns -EINVAL on unknown operations:
static int __sys_bpf(int cmd, bpfptr_t uattr, unsigned int size)
{
...
switch (cmd) {
...
case BPF_OBJ_GET_INFO_BY_FD:
err = bpf_obj_get_info_by_fd(&attr, uattr.user);
break;
..
default:
err = -EINVAL;
break;
}
return err;
}
Equivalent logic is present in ACK 4.9-Q:
SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, size)
This is what should thus be returned on 4.9-T devices.
Test: TreeHugger
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I124686ca360513f45e17afba23efa87acf1ce480
diff --git a/staticlibs/native/bpf_syscall_wrappers/include/BpfSyscallWrappers.h b/staticlibs/native/bpf_syscall_wrappers/include/BpfSyscallWrappers.h
index 7da4222..c710941 100644
--- a/staticlibs/native/bpf_syscall_wrappers/include/BpfSyscallWrappers.h
+++ b/staticlibs/native/bpf_syscall_wrappers/include/BpfSyscallWrappers.h
@@ -22,8 +22,6 @@
#include <linux/unistd.h>
#include <sys/file.h>
-#include "../../bpf_headers/include/bpf/KernelUtils.h"
-
#ifdef BPF_FD_JUST_USE_INT
#define BPF_FD_TYPE int
#define BPF_FD_TO_U32(x) static_cast<__u32>(x)
@@ -136,15 +134,18 @@
int bpfGetFdMapId(const BPF_FD_TYPE map_fd);
inline int bpfLock(int fd, short type) {
- if (!isAtLeastKernelVersion(4, 14, 0)) return fd; // 4.14+ required to fetch map id
if (fd < 0) return fd; // pass any errors straight through
#ifdef BPF_FD_JUST_USE_INT
int mapId = bpfGetFdMapId(fd);
+ int saved_errno = errno;
#else
base::unique_fd ufd(fd);
int mapId = bpfGetFdMapId(ufd);
+ int saved_errno = errno;
(void)ufd.release();
#endif
+ // 4.14+ required to fetch map id, but we don't want to call isAtLeastKernelVersion
+ if (mapId == -1 && saved_errno == EINVAL) return fd;
if (mapId <= 0) abort(); // should not be possible
// on __LP64__ (aka. 64-bit userspace) 'struct flock64' is the same as 'struct flock'