[v1,3/7] perf trace: Augmented syscalls fix libbpf 1.0+ compatibility

Message ID 20221103045437.163510-4-irogers@google.com
State New
Headers
Series Fix perf trace libbpf 1.0+ compatibility |

Commit Message

Ian Rogers Nov. 3, 2022, 4:54 a.m. UTC
  Don't use deprecated and now broken map style. Avoid use of
tools/perf/include/bpf/bpf.h and use the more regular BPF headers.
Add "< 0" checks to fix BPF verifier failures about potentially
negative values being passed to bpf_perf_event_output replacing an
existing mask. Add a raw_syscalls:sys_enter to avoid the evlist being
empty and causing perf trace to exit during argument parsing.

Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/examples/bpf/augmented_syscalls.c | 58 ++++++++++++++------
 1 file changed, 41 insertions(+), 17 deletions(-)
  

Patch

diff --git a/tools/perf/examples/bpf/augmented_syscalls.c b/tools/perf/examples/bpf/augmented_syscalls.c
index 524fdb8534b3..a809e1eab95d 100644
--- a/tools/perf/examples/bpf/augmented_syscalls.c
+++ b/tools/perf/examples/bpf/augmented_syscalls.c
@@ -16,11 +16,17 @@ 
  * contents of pointer arguments.
  */
 
-#include <stdio.h>
-#include <linux/socket.h>
+#include <linux/bpf.h>
+#include <bpf/bpf_helpers.h>
+#include <sys/socket.h>
 
 /* bpf-output associated map */
-bpf_map(__augmented_syscalls__, PERF_EVENT_ARRAY, int, u32, __NR_CPUS__);
+struct __augmented_syscalls__ {
+	__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
+	__type(key, int);
+	__type(value, __u32);
+	__uint(max_entries, __NR_CPUS__);
+} __augmented_syscalls__ SEC(".maps");
 
 struct syscall_exit_args {
 	unsigned long long common_tp_fields;
@@ -34,6 +40,12 @@  struct augmented_filename {
 	char		value[256];
 };
 
+#define syscall_enter(name)						\
+	SEC("!syscalls:sys_enter_" #name) syscall_enter_ ## name
+
+#define syscall_exit(name)					\
+	SEC("!syscalls:sys_exit_" #name) syscall_exit_ ## name
+
 #define augmented_filename_syscall(syscall)							\
 struct augmented_enter_##syscall##_args {			 				\
 	struct syscall_enter_##syscall##_args	args;				 		\
@@ -42,18 +54,23 @@  struct augmented_enter_##syscall##_args {			 				\
 int syscall_enter(syscall)(struct syscall_enter_##syscall##_args *args)				\
 {												\
 	struct augmented_enter_##syscall##_args augmented_args = { .filename.reserved = 0, }; 	\
-	unsigned int len = sizeof(augmented_args);						\
-	probe_read(&augmented_args.args, sizeof(augmented_args.args), args);			\
-	augmented_args.filename.size = probe_read_str(&augmented_args.filename.value, 		\
+	long size;										\
+												\
+	if (bpf_probe_read(&augmented_args.args, sizeof(augmented_args.args), args) < 0)	\
+		return -1;									\
+												\
+	size = bpf_probe_read_str(&augmented_args.filename.value,				\
 						      sizeof(augmented_args.filename.value), 	\
 						      args->filename_ptr); 			\
-	if (augmented_args.filename.size < sizeof(augmented_args.filename.value)) {		\
-		len -= sizeof(augmented_args.filename.value) - augmented_args.filename.size;	\
-		len &= sizeof(augmented_args.filename.value) - 1;				\
-	}											\
+	if (size < 0)										\
+		return -1;									\
+												\
+	augmented_args.filename.size = size;							\
 	/* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */	\
-	return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, 		\
-				 &augmented_args, len);						\
+	return bpf_perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU,		\
+				 &augmented_args,						\
+				 (sizeof(augmented_args) - sizeof(augmented_args.filename.value) + \
+				 size));				\
 }												\
 int syscall_exit(syscall)(struct syscall_exit_args *args)					\
 {												\
@@ -106,7 +123,7 @@  augmented_filename_syscall(newstat);
 #define _K_SS_MAXSIZE 128
 #endif
 
-#define augmented_sockaddr_syscall(syscall)						\
+#define augmented_sockaddr_syscall(syscall)							\
 struct augmented_enter_##syscall##_args {			 				\
 	struct syscall_enter_##syscall##_args	args;				 		\
 	struct sockaddr_storage			addr;						\
@@ -115,14 +132,14 @@  int syscall_enter(syscall)(struct syscall_enter_##syscall##_args *args)				\
 {												\
 	struct augmented_enter_##syscall##_args augmented_args;				 	\
 	unsigned long addrlen = sizeof(augmented_args.addr);					\
-	probe_read(&augmented_args.args, sizeof(augmented_args.args), args);			\
+	bpf_probe_read(&augmented_args.args, sizeof(augmented_args.args), args);		\
 /* FIXME_CLANG_OPTIMIZATION_THAT_ACCESSES_USER_CONTROLLED_ADDRLEN_DESPITE_THIS_CHECK */		\
 /*	if (addrlen > augmented_args.args.addrlen)				     */		\
 /*		addrlen = augmented_args.args.addrlen;				     */		\
 /*										     */		\
-	probe_read(&augmented_args.addr, addrlen, args->addr_ptr); 				\
+	bpf_probe_read(&augmented_args.addr, addrlen, args->addr_ptr);				\
 	/* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */	\
-	return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, 		\
+	return bpf_perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU,		\
 				 &augmented_args, 						\
 				sizeof(augmented_args) - sizeof(augmented_args.addr) + addrlen);\
 }												\
@@ -166,4 +183,11 @@  struct syscall_enter_sendto_args {
 
 augmented_sockaddr_syscall(sendto);
 
-license(GPL);
+struct syscall_enter_args;
+
+SEC("raw_syscalls:sys_enter")
+int sys_enter(struct syscall_enter_args *args)
+{
+	return 0;
+}
+char _license[] SEC("license") = "GPL";