Re: [PATCH bpf-next 00/25] libbpf: extend [ku]probe and syscall argument tracing support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Jan 17, 2023 at 1:52 AM Ilya Leoshkevich <iii@xxxxxxxxxxxxx> wrote:
>
> On Mon, 2023-01-16 at 23:37 +0100, Ilya Leoshkevich wrote:
> > On Mon, 2023-01-16 at 23:09 +0100, Ilya Leoshkevich wrote:
> > > On Fri, 2023-01-13 at 00:33 -0800, Andrii Nakryiko wrote:
> > > > This patch set fixes and extends libbpf's bpf_tracing.h support
> > > > for
> > > > tracing
> > > > arguments of kprobes/uprobes, and syscall as a special case.
> > > >
> > > > Depending on the architecture, anywhere between 3 and 8 arguments
> > > > can
> > > > be
> > > > passed to a function in registers (so relevant to kprobes and
> > > > uprobes), but
> > > > before this patch set libbpf's macros in bpf_tracing.h only
> > > > supported
> > > > up to
> > > > 5 arguments, which is limiting in practice. This patch set
> > > > extends
> > > > bpf_tracing.h to support up to 8 arguments, if architecture
> > > > allows.
> > > > This
> > > > includes explicit PT_REGS_PARMx() macro family, as well as
> > > > BPF_KPROBE() macro.
> > > >
> > > > Now, with tracing syscall arguments situation is sometimes quite
> > > > different.
> > > > For a lot of architectures syscall argument passing through
> > > > registers
> > > > differs
> > > > from function call sequence at least a little. For i386 it
> > > > differs
> > > > *a
> > > > lot*.
> > > > This patch set addresses this issue across all currently
> > > > supported
> > > > architectures and hopefully fixes existing issues. syscall(2)
> > > > manpage
> > > > defines
> > > > that either 6 or 7 arguments can be supported, depending on
> > > > architecture, so
> > > > libbpf defines 6 or 7 registers per architecture to be used to
> > > > fetch
> > > > syscall
> > > > arguments.
> > > >
> > > > Also, BPF_UPROBE and BPF_URETPROBE are introduced as part of this
> > > > patch set.
> > > > They are aliases for BPF_KPROBE and BPF_KRETPROBE (as mechanics
> > > > of
> > > > argument
> > > > fetching of kernel functions and user-space functions are
> > > > identical),
> > > > but it
> > > > allows BPF users to have less confusing BPF-side code when
> > > > working
> > > > with
> > > > uprobes.
> > > >
> > > > For both sets of changes selftests are extended to test these new
> > > > register
> > > > definitions to architecture-defined limits. Unfortunately I don't
> > > > have ability
> > > > to test it on all architectures, and BPF CI only tests 3
> > > > architecture
> > > > (x86-64,
> > > > arm64, and s390x), so it would be greatly appreciated if CC'ed
> > > > people
> > > > can help
> > > > review and test changes on architectures they are familiar with
> > > > (and
> > > > maybe
> > > > have direct access to for testing). Thank you.
> > > >
> > > > Cc: Alan Maguire <alan.maguire@xxxxxxxxxx>
> > > > Cc: Ilya Leoshkevich <iii@xxxxxxxxxxxxx>
> > > > Cc: Pu Lehui <pulehui@xxxxxxxxxx>
> > > > Cc: Hengqi Chen <hengqi.chen@xxxxxxxxx>
> > > > Cc: Vladimir Isaev <isaev@xxxxxxxxxxxx>
> > > > Cc: Björn Töpel <bjorn@xxxxxxxxxx>
> > > > Cc: Kenta Tada <Kenta.Tada@xxxxxxxx>
> > > > Cc: Florent Revest <revest@xxxxxxxxxxxx>
> > > >
> > > > Andrii Nakryiko (25):
> > > >   libbpf: add support for fetching up to 8 arguments in kprobes
> > > >   libbpf: add 6th argument support for x86-64 in bpf_tracing.h
> > > >   libbpf: fix arm and arm64 specs in bpf_tracing.h
> > > >   libbpf: complete mips spec in bpf_tracing.h
> > > >   libbpf: complete powerpc spec in bpf_tracing.h
> > > >   libbpf: complete sparc spec in bpf_tracing.h
> > > >   libbpf: complete riscv arch spec in bpf_tracing.h
> > > >   libbpf: fix and complete ARC spec in bpf_tracing.h
> > > >   libbpf: complete LoongArch (loongarch) spec in bpf_tracing.h
> > > >   libbpf: add BPF_UPROBE and BPF_URETPROBE macro aliases
> > > >   selftests/bpf: validate arch-specific argument registers limits
> > > >   libbpf: improve syscall tracing support in bpf_tracing.h
> > > >   libbpf: define x86-64 syscall regs spec in bpf_tracing.h
> > > >   libbpf: define i386 syscall regs spec in bpf_tracing.h
> > > >   libbpf: define s390x syscall regs spec in bpf_tracing.h
> > > >   libbpf: define arm syscall regs spec in bpf_tracing.h
> > > >   libbpf: define arm64 syscall regs spec in bpf_tracing.h
> > > >   libbpf: define mips syscall regs spec in bpf_tracing.h
> > > >   libbpf: define powerpc syscall regs spec in bpf_tracing.h
> > > >   libbpf: define sparc syscall regs spec in bpf_tracing.h
> > > >   libbpf: define riscv syscall regs spec in bpf_tracing.h
> > > >   libbpf: define arc syscall regs spec in bpf_tracing.h
> > > >   libbpf: define loongarch syscall regs spec in bpf_tracing.h
> > > >   selftests/bpf: add 6-argument syscall tracing test
> > > >   libbpf: clean up now not needed __PT_PARM{1-6}_SYSCALL_REG
> > > > defaults
> > > >
> > > >  tools/lib/bpf/bpf_tracing.h                   | 301
> > > > +++++++++++++++-
> > > > --
> > > >  .../bpf/prog_tests/test_bpf_syscall_macro.c   |  18 +-
> > > >  .../bpf/prog_tests/uprobe_autoattach.c        |  33 +-
> > > >  tools/testing/selftests/bpf/progs/bpf_misc.h  |  25 ++
> > > >  .../selftests/bpf/progs/bpf_syscall_macro.c   |  26 ++
> > > >  .../bpf/progs/test_uprobe_autoattach.c        |  48 ++-
> > > >  6 files changed, 405 insertions(+), 46 deletions(-)
> > > >
> > >
> > > With the following fixup for 24/25:
>
> [...]
>
> > > Tested-by: Ilya Leoshkevich <iii@xxxxxxxxxxxxx>  # s390x
> >
> > While the above fixup works, I realized that it's ugly. It's better
> > to
> > admit that mmap and old_mmap are different syscalls and create a
> > different probe, even if it means duplicating pid filtering code:
>
> [...]
>
> Sorry, I'm being dense. Both fixups defeat the purpose of having this
> test, because they don't use all 6 register arguments. We need to
> choose a different syscall; I believe splice() fits the bill. The other

nice, thanks for digging that up :) I've applied your suggested
changes (and added Suggested-by tag), thanks! Let's hope v2 will make
it to patchworks and we'll get BPF CI to test all this properly.


> alternatives that I rejected were:
>
> - clone() - argument order is messy;
> - recvfrom() - s390x uses socketcall instead;
> - ipc() - doesn't seem to be available on aarch64.
>
> The following worked for me:
>
> diff --git
> a/tools/testing/selftests/bpf/prog_tests/test_bpf_syscall_macro.c
> b/tools/testing/selftests/bpf/prog_tests/test_bpf_syscall_macro.c
> index e18dd82eb801..2900c5e9a016 100644
> --- a/tools/testing/selftests/bpf/prog_tests/test_bpf_syscall_macro.c
> +++ b/tools/testing/selftests/bpf/prog_tests/test_bpf_syscall_macro.c
> @@ -1,20 +1,22 @@
>  // SPDX-License-Identifier: GPL-2.0
>  /* Copyright 2022 Sony Group Corporation */
> +#define _GNU_SOURCE
> +#include <fcntl.h>
>  #include <sys/prctl.h>
> -#include <sys/mman.h>
>  #include <test_progs.h>
>  #include "bpf_syscall_macro.skel.h"
>
>  void test_bpf_syscall_macro(void)
>  {
>         struct bpf_syscall_macro *skel = NULL;
> -       int err, page_size = getpagesize();
> +       int err;
>         int exp_arg1 = 1001;
>         unsigned long exp_arg2 = 12;
>         unsigned long exp_arg3 = 13;
>         unsigned long exp_arg4 = 14;
>         unsigned long exp_arg5 = 15;
> -       void *r;
> +       loff_t off_in, off_out;
> +       ssize_t r;
>
>         /* check whether it can open program */
>         skel = bpf_syscall_macro__open();
> @@ -71,18 +73,17 @@ void test_bpf_syscall_macro(void)
>         ASSERT_EQ(skel->bss->arg4_syscall, exp_arg4,
> "BPF_KPROBE_SYSCALL_arg4");
>         ASSERT_EQ(skel->bss->arg5_syscall, exp_arg5,
> "BPF_KPROBE_SYSCALL_arg5");
>
> -       r = mmap((void *)0x12340000, 3 * page_size, PROT_READ |
> PROT_WRITE,
> -                MAP_PRIVATE, -42, 5 * page_size);
> +       r = splice(-42, &off_in, 42, &off_out, 0x12340000,
> SPLICE_F_NONBLOCK);
>         err = -errno;
> -       ASSERT_EQ(r, MAP_FAILED, "mmap_res");
> -       ASSERT_EQ(err, -EBADF, "mmap_err");
> +       ASSERT_EQ(r, -1, "splice_res");
> +       ASSERT_EQ(err, -EBADF, "splice_err");
>
> -       ASSERT_EQ(skel->bss->mmap_addr, 0x12340000, "mmap_arg1");
> -       ASSERT_EQ(skel->bss->mmap_length, 3 * page_size, "mmap_arg2");
> -       ASSERT_EQ(skel->bss->mmap_prot, PROT_READ | PROT_WRITE,
> "mmap_arg3");
> -       ASSERT_EQ(skel->bss->mmap_flags, MAP_PRIVATE, "mmap_arg4");
> -       ASSERT_EQ(skel->bss->mmap_fd, -42, "mmap_arg5");
> -       ASSERT_EQ(skel->bss->mmap_offset, 5 * page_size, "mmap_arg6");
> +       ASSERT_EQ(skel->bss->splice_fd_in, -42, "splice_arg1");
> +       ASSERT_EQ(skel->bss->splice_off_in, (__u64)&off_in,
> "splice_arg2");
> +       ASSERT_EQ(skel->bss->splice_fd_out, 42, "splice_arg3");
> +       ASSERT_EQ(skel->bss->splice_off_out, (__u64)&off_out,
> "splice_arg4");
> +       ASSERT_EQ(skel->bss->splice_len, 0x12340000, "splice_arg5");
> +       ASSERT_EQ(skel->bss->splice_flags, SPLICE_F_NONBLOCK,
> "splice_arg6");
>
>  cleanup:
>         bpf_syscall_macro__destroy(skel);
> diff --git a/tools/testing/selftests/bpf/progs/bpf_syscall_macro.c
> b/tools/testing/selftests/bpf/progs/bpf_syscall_macro.c
> index c07c5c52d5fc..1a476d8ed354 100644
> --- a/tools/testing/selftests/bpf/progs/bpf_syscall_macro.c
> +++ b/tools/testing/selftests/bpf/progs/bpf_syscall_macro.c
> @@ -81,28 +81,28 @@ int BPF_KSYSCALL(prctl_enter, int option, unsigned
> long arg2,
>         return 0;
>  }
>
> -__u64 mmap_addr;
> -__u64 mmap_length;
> -__u64 mmap_prot;
> -__u64 mmap_flags;
> -__u64 mmap_fd;
> -__u64 mmap_offset;
> -
> -SEC("ksyscall/mmap")
> -int BPF_KSYSCALL(mmap_enter, void *addr, size_t length, int prot, int
> flags,
> -                int fd, off_t offset)
> +__u64 splice_fd_in;
> +__u64 splice_off_in;
> +__u64 splice_fd_out;
> +__u64 splice_off_out;
> +__u64 splice_len;
> +__u64 splice_flags;
> +
> +SEC("ksyscall/splice")
> +int BPF_KSYSCALL(splice_enter, int fd_in, loff_t *off_in, int fd_out,
> +                loff_t *off_out, size_t len, unsigned int flags)
>  {
>         pid_t pid = bpf_get_current_pid_tgid() >> 32;
>
>         if (pid != filter_pid)
>                 return 0;
>
> -       mmap_addr = (__u64)addr;
> -       mmap_length = length;
> -       mmap_prot = prot;
> -       mmap_flags = flags;
> -       mmap_fd = fd;
> -       mmap_offset = offset;
> +       splice_fd_in = fd_in;
> +       splice_off_in = (__u64)off_in;
> +       splice_fd_out = fd_out;
> +       splice_off_out = (__u64)off_out;
> +       splice_len = len;
> +       splice_flags = flags;
>
>         return 0;
>  }
> --
> 2.39.0
>
> Best regards,
> Ilya




[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux