forked from Openwrt/openwrt
04981c716a
Recent libcap versions (>= 2.60) cause problems with BPF kselftests, so backport an upstream patch that replaces libcap and drops the dependency. Signed-off-by: Tony Ambardar <itugrok@yahoo.com>
124 lines
3.4 KiB
Diff
124 lines
3.4 KiB
Diff
From 5287acc6f097c0c18e54401b611a877a3083b68c Mon Sep 17 00:00:00 2001
|
|
From: Martin KaFai Lau <kafai@fb.com>
|
|
Date: Wed, 16 Mar 2022 10:38:23 -0700
|
|
Subject: [PATCH 1/3] bpf: selftests: Add helpers to directly use the capget
|
|
and capset syscall
|
|
|
|
After upgrading to the newer libcap (>= 2.60),
|
|
the libcap commit aca076443591 ("Make cap_t operations thread safe.")
|
|
added a "__u8 mutex;" to the "struct _cap_struct". It caused a few byte
|
|
shift that breaks the assumption made in the "struct libcap" definition
|
|
in test_verifier.c.
|
|
|
|
The bpf selftest usage only needs to enable and disable the effective
|
|
caps of the running task. It is easier to directly syscall the
|
|
capget and capset instead. It can also remove the libcap
|
|
library dependency.
|
|
|
|
The cap_helpers.{c,h} is added. One __u64 is used for all CAP_*
|
|
bits instead of two __u32.
|
|
|
|
Signed-off-by: Martin KaFai Lau <kafai@fb.com>
|
|
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
|
|
Acked-by: John Fastabend <john.fastabend@gmail.com>
|
|
Link: https://lore.kernel.org/bpf/20220316173823.2036955-1-kafai@fb.com
|
|
---
|
|
tools/testing/selftests/bpf/cap_helpers.c | 67 +++++++++++++++++++++++
|
|
tools/testing/selftests/bpf/cap_helpers.h | 19 +++++++
|
|
2 files changed, 86 insertions(+)
|
|
create mode 100644 tools/testing/selftests/bpf/cap_helpers.c
|
|
create mode 100644 tools/testing/selftests/bpf/cap_helpers.h
|
|
|
|
--- /dev/null
|
|
+++ b/tools/testing/selftests/bpf/cap_helpers.c
|
|
@@ -0,0 +1,67 @@
|
|
+// SPDX-License-Identifier: GPL-2.0
|
|
+#include "cap_helpers.h"
|
|
+
|
|
+/* Avoid including <sys/capability.h> from the libcap-devel package,
|
|
+ * so directly declare them here and use them from glibc.
|
|
+ */
|
|
+int capget(cap_user_header_t header, cap_user_data_t data);
|
|
+int capset(cap_user_header_t header, const cap_user_data_t data);
|
|
+
|
|
+int cap_enable_effective(__u64 caps, __u64 *old_caps)
|
|
+{
|
|
+ struct __user_cap_data_struct data[_LINUX_CAPABILITY_U32S_3];
|
|
+ struct __user_cap_header_struct hdr = {
|
|
+ .version = _LINUX_CAPABILITY_VERSION_3,
|
|
+ };
|
|
+ __u32 cap0 = caps;
|
|
+ __u32 cap1 = caps >> 32;
|
|
+ int err;
|
|
+
|
|
+ err = capget(&hdr, data);
|
|
+ if (err)
|
|
+ return err;
|
|
+
|
|
+ if (old_caps)
|
|
+ *old_caps = (__u64)(data[1].effective) << 32 | data[0].effective;
|
|
+
|
|
+ if ((data[0].effective & cap0) == cap0 &&
|
|
+ (data[1].effective & cap1) == cap1)
|
|
+ return 0;
|
|
+
|
|
+ data[0].effective |= cap0;
|
|
+ data[1].effective |= cap1;
|
|
+ err = capset(&hdr, data);
|
|
+ if (err)
|
|
+ return err;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int cap_disable_effective(__u64 caps, __u64 *old_caps)
|
|
+{
|
|
+ struct __user_cap_data_struct data[_LINUX_CAPABILITY_U32S_3];
|
|
+ struct __user_cap_header_struct hdr = {
|
|
+ .version = _LINUX_CAPABILITY_VERSION_3,
|
|
+ };
|
|
+ __u32 cap0 = caps;
|
|
+ __u32 cap1 = caps >> 32;
|
|
+ int err;
|
|
+
|
|
+ err = capget(&hdr, data);
|
|
+ if (err)
|
|
+ return err;
|
|
+
|
|
+ if (old_caps)
|
|
+ *old_caps = (__u64)(data[1].effective) << 32 | data[0].effective;
|
|
+
|
|
+ if (!(data[0].effective & cap0) && !(data[1].effective & cap1))
|
|
+ return 0;
|
|
+
|
|
+ data[0].effective &= ~cap0;
|
|
+ data[1].effective &= ~cap1;
|
|
+ err = capset(&hdr, data);
|
|
+ if (err)
|
|
+ return err;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
--- /dev/null
|
|
+++ b/tools/testing/selftests/bpf/cap_helpers.h
|
|
@@ -0,0 +1,19 @@
|
|
+/* SPDX-License-Identifier: GPL-2.0 */
|
|
+#ifndef __CAP_HELPERS_H
|
|
+#define __CAP_HELPERS_H
|
|
+
|
|
+#include <linux/types.h>
|
|
+#include <linux/capability.h>
|
|
+
|
|
+#ifndef CAP_PERFMON
|
|
+#define CAP_PERFMON 38
|
|
+#endif
|
|
+
|
|
+#ifndef CAP_BPF
|
|
+#define CAP_BPF 39
|
|
+#endif
|
|
+
|
|
+int cap_enable_effective(__u64 caps, __u64 *old_caps);
|
|
+int cap_disable_effective(__u64 caps, __u64 *old_caps);
|
|
+
|
|
+#endif
|