From patchwork Sun May 29 22:06:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Xu X-Patchwork-Id: 12864246 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DBF81C433F5 for ; Sun, 29 May 2022 22:06:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231864AbiE2WG3 (ORCPT ); Sun, 29 May 2022 18:06:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34914 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231830AbiE2WG2 (ORCPT ); Sun, 29 May 2022 18:06:28 -0400 Received: from out3-smtp.messagingengine.com (out3-smtp.messagingengine.com [66.111.4.27]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B4A9C79811; Sun, 29 May 2022 15:06:26 -0700 (PDT) Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.nyi.internal (Postfix) with ESMTP id 0FC095C00D6; Sun, 29 May 2022 18:06:25 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute5.internal (MEProxy); Sun, 29 May 2022 18:06:25 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dxuuu.xyz; h=cc :cc:content-transfer-encoding:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to; s=fm3; t=1653861985; x=1653948385; bh=UC lJxbC3dYsTnlB9EQCDEeVJjlgkJVQ4fF8v6lEjbLQ=; b=osrKy06y7Y33av7im0 vHoSIXyW69mOFQcoxrw8r8uwkYyhWoJy0HmOAkGlbxvxS4PK4aJ5nBhmQCv/wT/o wVkODVeDiNcuOLJh8rwdsW5MxSztCqC4yC+8v8Y9Vqg95POb2oQI2SfzuByDoULa vNN+o8xuVg//AwKhIumg+hVETlhRvCjj1sbgcM880ptB7iM+5+ZAUJkr4b3h3bfC 5mPHak6hT+XXFGJ2fn/dZymwSOfUUr6JLrFh//OGJmzryuMZLbukavmAS1rBspzY I0AWPS8gG2hgk9Wj2O3LDagm0MuF6wxRHNUqM0k3P/Jx3TsF7bxurYBsmr75l7tA Svrw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm1; t=1653861985; x=1653948385; bh=UClJxbC3dYsTn lB9EQCDEeVJjlgkJVQ4fF8v6lEjbLQ=; b=mohLzHOMvBAsdEZAAGCqcamBtQos0 uzxUbCe1+/xVUUlRk9VD6XnC/yoIl/d+LEHN9PWktSe6B9OB0V34aeYzoXoNcBo6 1qsqbO6RshVJAuTN8f23WA8P3QOL41rtpw8Iy0/Kuu0Bz/HXK1n6LZ80dtYqKaHr LdYRgsZgUyc85rOSxHukaTD+TxrhnWYzhomyFN8QKsWy9SRu8zben+iRGjtStz/Y JStlbmYweSPz0+tb6acg4zEUgU/L0bfCRze6PtEc5ntuhMiJJoQuS1C9AC0iNjbF slR/dXJvVARiS9xj44QCmOdpO1pEc2hOFSafCaMzyWX8cNJS6J0QWjYMw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvfedrkeehgddtfecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecufghrlhcuvffnffculdejtddmnecujfgurhephffvve fufffkofgjfhgggfestdekredtredttdenucfhrhhomhepffgrnhhivghlucgiuhcuoegu gihusegugihuuhhurdighiiiqeenucggtffrrghtthgvrhhnpefgfefggeejhfduieekvd euteffleeifeeuvdfhheejleejjeekgfffgefhtddtteenucevlhhushhtvghrufhiiigv pedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpegugihusegugihuuhhurdighiii X-ME-Proxy: Feedback-ID: i6a694271:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sun, 29 May 2022 18:06:24 -0400 (EDT) From: Daniel Xu To: bpf@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org Cc: Daniel Xu , linux-kernel@vger.kernel.org Subject: [PATCH bpf-next 1/2] bpf, test_run: Add PROG_TEST_RUN support to kprobe Date: Sun, 29 May 2022 17:06:05 -0500 Message-Id: X-Mailer: git-send-email 2.36.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net This commit adds PROG_TEST_RUN support to BPF_PROG_TYPE_KPROBE progs. On top of being generally useful for unit testing kprobe progs, this commit more specifically helps solve a relability problem with bpftrace BEGIN and END probes. BEGIN and END probes are run exactly once at the beginning and end of a bpftrace tracing session, respectively. bpftrace currently implements the probes by creating two dummy functions and attaching the BEGIN and END progs, if defined, to those functions and calling the dummy functions as appropriate. This works pretty well most of the time except for when distros strip symbols from bpftrace. Every now and then this happens and users get confused. Having PROG_TEST_RUN support will help solve this issue by allowing us to directly trigger uprobes from userspace. Admittedly, this is a pretty specific problem and could probably be solved other ways. However, PROG_TEST_RUN also makes unit testing more convenient, especially as users start building more complex tracing applications. So I see this as killing two birds with one stone. Signed-off-by: Daniel Xu Reported-by: kernel test robot Reported-by: kernel test robot --- include/linux/bpf.h | 10 ++++++++++ kernel/trace/bpf_trace.c | 1 + net/bpf/test_run.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 2b914a56a2c5..dec3082ee158 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -1751,6 +1751,9 @@ int bpf_prog_test_run_raw_tp(struct bpf_prog *prog, int bpf_prog_test_run_sk_lookup(struct bpf_prog *prog, const union bpf_attr *kattr, union bpf_attr __user *uattr); +int bpf_prog_test_run_kprobe(struct bpf_prog *prog, + const union bpf_attr *kattr, + union bpf_attr __user *uattr); bool btf_ctx_access(int off, int size, enum bpf_access_type type, const struct bpf_prog *prog, struct bpf_insn_access_aux *info); @@ -1998,6 +2001,13 @@ static inline int bpf_prog_test_run_sk_lookup(struct bpf_prog *prog, return -ENOTSUPP; } +static inline int bpf_prog_test_run_kprobe(struct bpf_prog *prog, + const union bpf_attr *kattr, + union bpf_attr __user *uattr) +{ + return -ENOTSUPP; +} + static inline void bpf_map_put(struct bpf_map *map) { } diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 10b157a6d73e..b452e84b9ba4 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -1363,6 +1363,7 @@ const struct bpf_verifier_ops kprobe_verifier_ops = { }; const struct bpf_prog_ops kprobe_prog_ops = { + .test_run = bpf_prog_test_run_kprobe, }; BPF_CALL_5(bpf_perf_event_output_tp, void *, tp_buff, struct bpf_map *, map, diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c index 56f059b3c242..0b6fc17ce901 100644 --- a/net/bpf/test_run.c +++ b/net/bpf/test_run.c @@ -1622,6 +1622,42 @@ int bpf_prog_test_run_syscall(struct bpf_prog *prog, return err; } +int bpf_prog_test_run_kprobe(struct bpf_prog *prog, + const union bpf_attr *kattr, + union bpf_attr __user *uattr) +{ + void __user *ctx_in = u64_to_user_ptr(kattr->test.ctx_in); + __u32 ctx_size_in = kattr->test.ctx_size_in; + u32 repeat = kattr->test.repeat; + struct pt_regs *ctx = NULL; + u32 retval, duration; + int err = 0; + + if (kattr->test.data_in || kattr->test.data_out || + kattr->test.ctx_out || kattr->test.flags || + kattr->test.cpu || kattr->test.batch_size) + return -EINVAL; + + if (ctx_size_in != sizeof(struct pt_regs)) + return -EINVAL; + + ctx = memdup_user(ctx_in, ctx_size_in); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); + + err = bpf_test_run(prog, ctx, repeat, &retval, &duration, false); + if (err) + goto out; + + if (copy_to_user(&uattr->test.retval, &retval, sizeof(retval)) || + copy_to_user(&uattr->test.duration, &duration, sizeof(duration))) { + err = -EFAULT; + } +out: + kfree(ctx); + return err; +} + static const struct btf_kfunc_id_set bpf_prog_test_kfunc_set = { .owner = THIS_MODULE, .check_set = &test_sk_check_kfunc_ids, From patchwork Sun May 29 22:06:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Xu X-Patchwork-Id: 12864245 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EEB4AC433EF for ; Sun, 29 May 2022 22:06:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231877AbiE2WGa (ORCPT ); Sun, 29 May 2022 18:06:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34912 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230326AbiE2WG2 (ORCPT ); Sun, 29 May 2022 18:06:28 -0400 Received: from out3-smtp.messagingengine.com (out3-smtp.messagingengine.com [66.111.4.27]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A79537980D; Sun, 29 May 2022 15:06:26 -0700 (PDT) Received: from compute2.internal (compute2.nyi.internal [10.202.2.46]) by mailout.nyi.internal (Postfix) with ESMTP id CDFB45C00DF; Sun, 29 May 2022 18:06:25 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute2.internal (MEProxy); Sun, 29 May 2022 18:06:25 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dxuuu.xyz; h=cc :cc:content-transfer-encoding:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to; s=fm3; t=1653861985; x=1653948385; bh=o5 Io0TbLicI9bF16Sf8cW9EWMZ3JMY7fjlIo1Z3Xc7o=; b=SBDRcitWGQXvRvn+aO Wrd50+ZmOERLrrs5kT5xhO7yukm6NrgDpKs2fvhNvuGDsZq2q9a1t8GcJuDP7exV O12nPS9pjKTtZacs6aVEeJd5HLlsAZ4DZoLnibt2z08kw7Ca0jXjcub7lkPD1zvk 3W5QB+bC8t03gtTkxQaCRDdiwUeFt996+Og63uFjNpGjvZXWmYsAwc6UfGLO+OCA WR1F/yK/UFMrVzWrS/7VNbaprMSy3hTten0cRF0F0zQj0cRSnG5eeFCag0wrkvkh DJVSet7gYpj6IOm54B4r3R8lHk/A1oboIGHty/mtEjkDOfkGZZZxpsG4MLupqhil T9dw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm1; t=1653861985; x=1653948385; bh=o5Io0TbLicI9b F16Sf8cW9EWMZ3JMY7fjlIo1Z3Xc7o=; b=jKBR/C6gzd+WaOh+plsLpqQ4IZX91 po4sRDtLHDVzPpWLUDypf26UcKO3eYhP2r5df6O1f/+y4zChNQRFWSoYVarQUkHd 9YyYoFu48wB1CSUGaH5GjRaZPUQaizidYxs/t1rKSwtoFPn2Gs8eBrmysLww573S qlhFgjSfJpKbLX5dQQbpcUG8okeXYDVA1q32s6aIlLS0P+9AAeKUQJy+vwTPQTpw ZVSqvu7d7CsrXqlDMT7dow6knq0+8VMXsmbWu6bMAH75/wnnI0ETZ1eq/FAMx3Zt LZGiVMgbzt1dFA3ml3dqiF2YTqFWnd3lgNa0I1524DUku1jD5IoBHTWtQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvfedrkeehgddtgecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecufghrlhcuvffnffculdejtddmnecujfgurhephffvve fufffkofgjfhgggfestdekredtredttdenucfhrhhomhepffgrnhhivghlucgiuhcuoegu gihusegugihuuhhurdighiiiqeenucggtffrrghtthgvrhhnpefgfefggeejhfduieekvd euteffleeifeeuvdfhheejleejjeekgfffgefhtddtteenucevlhhushhtvghrufhiiigv pedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpegugihusegugihuuhhurdighiii X-ME-Proxy: Feedback-ID: i6a694271:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sun, 29 May 2022 18:06:25 -0400 (EDT) From: Daniel Xu To: bpf@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org Cc: Daniel Xu , linux-kernel@vger.kernel.org Subject: [PATCH bpf-next 2/2] selftests/bpf: Add PROG_TEST_RUN selftest for BPF_PROG_TYPE_KPROBE Date: Sun, 29 May 2022 17:06:06 -0500 Message-Id: X-Mailer: git-send-email 2.36.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net This commit adds a selftest to test that we can both PROG_TEST_RUN a kprobe prog and set its context. Signed-off-by: Daniel Xu Acked-by: Song Liu --- .../selftests/bpf/prog_tests/kprobe_ctx.c | 57 +++++++++++++++++++ .../testing/selftests/bpf/progs/kprobe_ctx.c | 33 +++++++++++ 2 files changed, 90 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/kprobe_ctx.c create mode 100644 tools/testing/selftests/bpf/progs/kprobe_ctx.c diff --git a/tools/testing/selftests/bpf/prog_tests/kprobe_ctx.c b/tools/testing/selftests/bpf/prog_tests/kprobe_ctx.c new file mode 100644 index 000000000000..260966fd4506 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/kprobe_ctx.c @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include "kprobe_ctx.skel.h" + +/* + * x86_64 happens to be one of the architectures that exports the + * kernel `struct pt_regs` to userspace ABI. For the architectures + * that don't, users will have to extract `struct pt_regs` from vmlinux + * BTF in order to use BPF_PROG_TYPE_KPROBE's BPF_PROG_RUN functionality. + * + * We choose to only test x86 here to keep the test simple. + */ +void test_kprobe_ctx(void) +{ +#ifdef __x86_64__ + struct pt_regs regs = { + .rdi = 1, + .rsi = 2, + .rdx = 3, + .rcx = 4, + .r8 = 5, + }; + + LIBBPF_OPTS(bpf_test_run_opts, tattr, + .ctx_in = ®s, + .ctx_size_in = sizeof(regs), + ); + + struct kprobe_ctx *skel = NULL; + int prog_fd; + int err; + + skel = kprobe_ctx__open_and_load(); + if (!ASSERT_OK_PTR(skel, "skel_open")) + return; + + skel->bss->expected_p1 = (void *)1; + skel->bss->expected_p2 = (void *)2; + skel->bss->expected_p3 = (void *)3; + skel->bss->expected_p4 = (void *)4; + skel->bss->expected_p5 = (void *)5; + + prog_fd = bpf_program__fd(skel->progs.prog); + err = bpf_prog_test_run_opts(prog_fd, &tattr); + if (!ASSERT_OK(err, "bpf_prog_test_run")) + goto cleanup; + + if (!ASSERT_TRUE(skel->bss->ret, "ret")) + goto cleanup; + + if (!ASSERT_GT(tattr.duration, 0, "duration")) + goto cleanup; +cleanup: + kprobe_ctx__destroy(skel); +#endif +} diff --git a/tools/testing/selftests/bpf/progs/kprobe_ctx.c b/tools/testing/selftests/bpf/progs/kprobe_ctx.c new file mode 100644 index 000000000000..98063c549930 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/kprobe_ctx.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include "vmlinux.h" +#include +#include + +volatile void *expected_p1; +volatile void *expected_p2; +volatile void *expected_p3; +volatile void *expected_p4; +volatile void *expected_p5; +volatile bool ret = false; + +SEC("kprobe/this_function_does_not_exist") +int prog(struct pt_regs *ctx) +{ + void *p1, *p2, *p3, *p4, *p5; + + p1 = (void *)PT_REGS_PARM1(ctx); + p2 = (void *)PT_REGS_PARM2(ctx); + p3 = (void *)PT_REGS_PARM3(ctx); + p4 = (void *)PT_REGS_PARM4(ctx); + p5 = (void *)PT_REGS_PARM5(ctx); + + if (p1 != expected_p1 || p2 != expected_p2 || p3 != expected_p3 || + p4 != expected_p4 || p5 != expected_p5) + return 0; + + ret = true; + return 0; +} + +char _license[] SEC("license") = "GPL";