* [PATCH bpf-next v1] selftests/bpf:Enhance bpf ability to detect ksym read error by libcap
@ 2024-09-14 9:24 Lin Yikai
2024-09-24 22:40 ` Martin KaFai Lau
0 siblings, 1 reply; 2+ messages in thread
From: Lin Yikai @ 2024-09-14 9:24 UTC (permalink / raw)
To: bpf
Cc: opensource.kernel, yikai.lin, Andrii Nakryiko, Eduard Zingerman,
Mykola Lysenko, Alexei Starovoitov, Daniel Borkmann,
Martin KaFai Lau, Song Liu, Yonghong Song, John Fastabend,
KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa, Shuah Khan,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
linux-kselftest, linux-kernel, llvm
Ksym addr access is restricted
by ``kptr_restrict``(/proc/sys/kernel/kptr_restrict).
On some OS systems(like Android),
ksym addr access is not accessed because ``kptr_restrict=2`.
And it took me a long time to find the root case.
-When ``kptr_restrict==0``, addr is accessed.
# echo 0 > /proc/sys/kernel/kptr_restrict
# cat /proc/kallsyms | grep bpf_link_fops
ffffffd6bfd3fb60 d bpf_link_fops
-When ``kptr_restrict==2``, addr is replaced by ZERO.
# echo 2 > /proc/sys/kernel/kptr_restrict
# cat /proc/kallsyms | grep bpf_link_fops
0000000000000000 d bpf_link_fops
-When ``kptr_restrict==1``, addr is accessed for user having CAP_SYSLOG.
So we should perform a check to remind users for these conditions
before reading /proc/kallsyms.
[before]:
# echo 2 > /proc/sys/kernel/kptr_restrict
# ./test_progs -t ksyms
#133 ksyms:FAIL
[after]:
# echo 2 > /proc/sys/kernel/kptr_restrict
# ./test_progs -t ksym
ksyms restricted, please check /proc/sys/kernel/kptr_restrict
#133 ksyms:FAIL
Signed-off-by: Lin Yikai <yikai.lin@vivo.com>
---
tools/testing/selftests/bpf/Makefile | 7 ++-
tools/testing/selftests/bpf/trace_helpers.c | 63 +++++++++++++++++++++
2 files changed, 69 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 04716a5e43f1..369c5ad8fc4a 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -183,7 +183,7 @@ NON_CHECK_FEAT_TARGETS := clean docs-clean
CHECK_FEAT := $(filter-out $(NON_CHECK_FEAT_TARGETS),$(or $(MAKECMDGOALS), "none"))
ifneq ($(CHECK_FEAT),)
FEATURE_USER := .selftests
-FEATURE_TESTS := llvm
+FEATURE_TESTS := llvm libcap
FEATURE_DISPLAY := $(FEATURE_TESTS)
# Makefile.feature expects OUTPUT to end with a slash
@@ -208,6 +208,11 @@ ifeq ($(feature-llvm),1)
LLVM_LDFLAGS += $(shell $(LLVM_CONFIG) --ldflags)
endif
+ifeq ($(feature-libcap), 1)
+ CFLAGS += -DHAVE_LIBCAP_SUPPORT
+ LDLIBS += -lcap
+endif
+
SCRATCH_DIR := $(OUTPUT)/tools
BUILD_DIR := $(SCRATCH_DIR)/build
INCLUDE_DIR := $(SCRATCH_DIR)/include
diff --git a/tools/testing/selftests/bpf/trace_helpers.c b/tools/testing/selftests/bpf/trace_helpers.c
index 2d742fdac6b9..8d2f951464ff 100644
--- a/tools/testing/selftests/bpf/trace_helpers.c
+++ b/tools/testing/selftests/bpf/trace_helpers.c
@@ -17,6 +17,10 @@
#include <linux/limits.h>
#include <libelf.h>
#include <gelf.h>
+#include <stdbool.h>
+#include <linux/capability.h>
+#include <linux/compiler.h>
+#include <sys/types.h>
#include "bpf/libbpf_internal.h"
#define TRACEFS_PIPE "/sys/kernel/tracing/trace_pipe"
@@ -31,6 +35,55 @@ struct ksyms {
static struct ksyms *ksyms;
static pthread_mutex_t ksyms_mutex = PTHREAD_MUTEX_INITIALIZER;
+#ifdef HAVE_LIBCAP_SUPPORT
+#include <sys/capability.h>
+static bool bpf_cap__capable(cap_value_t cap)
+{
+ cap_flag_value_t val;
+ cap_t caps = cap_get_proc();
+
+ if (!caps)
+ return false;
+
+ if (cap_get_flag(caps, cap, CAP_EFFECTIVE, &val) != 0)
+ val = CAP_CLEAR;
+
+ if (cap_free(caps) != 0)
+ return false;
+
+ return val == CAP_SET;
+}
+#else
+static inline bool bpf_cap__capable(int cap __maybe_unused)
+{
+ return geteuid() == 0;
+}
+#endif /* HAVE_LIBCAP_SUPPORT */
+
+/* For older systems */
+#ifndef CAP_SYSLOG
+#define CAP_SYSLOG 34
+#endif
+
+static bool ksyms__kptr_restrict(void)
+{
+ bool value = false;
+ FILE *fp = fopen("/proc/sys/kernel/kptr_restrict", "r");
+
+ if (fp != NULL) {
+ char line[8];
+
+ if (fgets(line, sizeof(line), fp) != NULL)
+ value = bpf_cap__capable(CAP_SYSLOG) ?
+ (atoi(line) >= 2) :
+ (atoi(line) != 0);
+
+ fclose(fp);
+ }
+
+ return value;
+}
+
static int ksyms__add_symbol(struct ksyms *ksyms, const char *name,
unsigned long addr)
{
@@ -72,6 +125,11 @@ static struct ksyms *load_kallsyms_local_common(ksym_cmp_t cmp_cb)
int ret;
struct ksyms *ksyms;
+ if (ksyms__kptr_restrict()) {
+ printf("ksyms restricted, please check /proc/sys/kernel/kptr_restrict\n");
+ return NULL;
+ }
+
f = fopen("/proc/kallsyms", "r");
if (!f)
return NULL;
@@ -218,6 +276,11 @@ int kallsyms_find(const char *sym, unsigned long long *addr)
int err = 0;
FILE *f;
+ if (ksyms__kptr_restrict()) {
+ printf("ksyms restricted, please check /proc/sys/kernel/kptr_restrict\n");
+ return -EINVAL;
+ }
+
f = fopen("/proc/kallsyms", "r");
if (!f)
return -EINVAL;
--
2.34.1
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH bpf-next v1] selftests/bpf:Enhance bpf ability to detect ksym read error by libcap
2024-09-14 9:24 [PATCH bpf-next v1] selftests/bpf:Enhance bpf ability to detect ksym read error by libcap Lin Yikai
@ 2024-09-24 22:40 ` Martin KaFai Lau
0 siblings, 0 replies; 2+ messages in thread
From: Martin KaFai Lau @ 2024-09-24 22:40 UTC (permalink / raw)
To: Lin Yikai
Cc: bpf, opensource.kernel, Andrii Nakryiko, Eduard Zingerman,
Mykola Lysenko, Alexei Starovoitov, Daniel Borkmann, Song Liu,
Yonghong Song, John Fastabend, KP Singh, Stanislav Fomichev,
Hao Luo, Jiri Olsa, Shuah Khan, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt, linux-kselftest,
linux-kernel, llvm
On 9/14/24 11:24 AM, Lin Yikai wrote:
> diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
> index 04716a5e43f1..369c5ad8fc4a 100644
> --- a/tools/testing/selftests/bpf/Makefile
> +++ b/tools/testing/selftests/bpf/Makefile
> @@ -183,7 +183,7 @@ NON_CHECK_FEAT_TARGETS := clean docs-clean
> CHECK_FEAT := $(filter-out $(NON_CHECK_FEAT_TARGETS),$(or $(MAKECMDGOALS), "none"))
> ifneq ($(CHECK_FEAT),)
> FEATURE_USER := .selftests
> -FEATURE_TESTS := llvm
> +FEATURE_TESTS := llvm libcap
> FEATURE_DISPLAY := $(FEATURE_TESTS)
>
> # Makefile.feature expects OUTPUT to end with a slash
> @@ -208,6 +208,11 @@ ifeq ($(feature-llvm),1)
> LLVM_LDFLAGS += $(shell $(LLVM_CONFIG) --ldflags)
> endif
>
> +ifeq ($(feature-libcap), 1)
> + CFLAGS += -DHAVE_LIBCAP_SUPPORT
> + LDLIBS += -lcap
> +endif
> +
[ ... ]
> @@ -31,6 +35,55 @@ struct ksyms {
> static struct ksyms *ksyms;
> static pthread_mutex_t ksyms_mutex = PTHREAD_MUTEX_INITIALIZER;
>
> +#ifdef HAVE_LIBCAP_SUPPORT
> +#include <sys/capability.h>
> +static bool bpf_cap__capable(cap_value_t cap)
> +{
> + cap_flag_value_t val;
> + cap_t caps = cap_get_proc();
> +
> + if (!caps)
> + return false;
> +
> + if (cap_get_flag(caps, cap, CAP_EFFECTIVE, &val) != 0)
Instead of adding new dependency on libcap, please check if capget() can
directly be used. Take a look at tools/testing/selftests/bpf/cap_helpers.c.
pw-bot: cr
> + val = CAP_CLEAR;
> +
> + if (cap_free(caps) != 0)
> + return false;
> +
> + return val == CAP_SET;
> +}
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2024-09-24 22:41 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-14 9:24 [PATCH bpf-next v1] selftests/bpf:Enhance bpf ability to detect ksym read error by libcap Lin Yikai
2024-09-24 22:40 ` Martin KaFai Lau
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox