public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [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