summaryrefslogtreecommitdiff
path: root/tools/perf
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2018-09-03 21:02:22 +0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2018-09-03 21:13:33 +0300
commit21d7eb9a24739cdc5ea19c90a79e5a585866ba35 (patch)
tree03bf9d78e5f922bb733ee6d93bb03b52dffb0f57 /tools/perf
parent58094c48f4079cfc784f53a73caaa446db436389 (diff)
downloadlinux-21d7eb9a24739cdc5ea19c90a79e5a585866ba35.tar.xz
perf augmented_syscalls: Check probe_read_str() return separately
Using a value returned from probe_read_str() to tell how many bytes to copy using perf_event_output() has issues in some older kernels, like 4.17.17-100.fc27.x86_64, so separate the bounds checking done on how many bytes to copy to a separate variable, so that the next patch has only what is being done to make the test pass on older BPF validators. For reference, see the discussion in this thread: https://www.spinics.net/lists/netdev/msg480099.html Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Daniel Borkmann <daniel@iogearbox.net> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Wang Nan <wangnan0@huawei.com> Cc: Yonghong Song <yhs@fb.com> Link: https://lkml.kernel.org/n/tip-jtsapwibyxrnv1xjfsgzp0fj@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/examples/bpf/augmented_syscalls.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/tools/perf/examples/bpf/augmented_syscalls.c b/tools/perf/examples/bpf/augmented_syscalls.c
index 1419a9186937..0decbcfa8b90 100644
--- a/tools/perf/examples/bpf/augmented_syscalls.c
+++ b/tools/perf/examples/bpf/augmented_syscalls.c
@@ -33,9 +33,9 @@ struct syscall_exit_args {
};
struct augmented_filename {
- int size;
- int reserved;
- char value[256];
+ unsigned int size;
+ int reserved;
+ char value[256];
};
#define augmented_filename_syscall(syscall) \
@@ -46,14 +46,15 @@ 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, \
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; \
perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, \
- &augmented_args, \
- (sizeof(augmented_args) - sizeof(augmented_args.filename.value) + \
- augmented_args.filename.size)); \
+ &augmented_args, len); \
return 0; \
} \
int syscall_exit(syscall)(struct syscall_exit_args *args) \