| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- From 5287acc6f097c0c18e54401b611a877a3083b68c Mon Sep 17 00:00:00 2001
- From: Martin KaFai Lau <[email protected]>
- 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 <[email protected]>
- Signed-off-by: Alexei Starovoitov <[email protected]>
- Acked-by: John Fastabend <[email protected]>
- Link: https://lore.kernel.org/bpf/[email protected]
- ---
- 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
|