Received: by 2002:a25:c205:0:0:0:0:0 with SMTP id s5csp4638255ybf; Wed, 4 Mar 2020 07:48:35 -0800 (PST) X-Google-Smtp-Source: ADFU+vv0yTbgEO+/B/rgumvItrlcNaXMefB8fdCD51cc0GWtqikRGKdJ0Siq6NtkAU+C3/JZiZ53 X-Received: by 2002:a05:6808:3ae:: with SMTP id n14mr2222759oie.63.1583336914782; Wed, 04 Mar 2020 07:48:34 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1583336914; cv=none; d=google.com; s=arc-20160816; b=deWW5MFlkQmOwMCBU5HbahDdRGc/Oa31wQRMhFkZRMHLLy00OgJDJnWw+We6QmacKe xhZf0+1Aq7kWadnxEsdyHoxEu7z1SOMSDvnR5MOAgA+tdKwI4kwOGQhAlik+Kc7vV5bv 4pfOzi3Ve0V8SIUDPoLfoV0sUJ3oHiOTqOiXKvbttmQpx7Mwd80rG/ygc6pHywvu2tiv zdSKU8ab3IoDhzKCDocU/VvQNCkZodh31j4/eYxuBQvBw38uDz1vaZO864HvIMllwIMa JHS3cC62QbNeJeEUZRbZmTD0yyzxBj04H/zhaiq1bsfOj38qUixrM/yeqbskSKb0dViM N9tw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=JH3iKdoX60vBDf5RPVZX6I6Dg2qntJTjRhn9rqqRbkU=; b=JViBjXNpRNRjxUy+nSY/UgZK8vhGynY2wXBvuYj31ssN7t1m+KPqCvDK3KGKKUF4ep +RCe0DW/UgeQEQPl0p8mcQlTZNJKd91lp0vKdjlTNsdogBBOFPiklquBajJ7+Qb8Tq0v 4H66kKAQSSgLD72W7kbDIqczsqai2w9RYQaGKjmA/bqUVITxYBY827rx9VOsFvWuJxkB c6TMXKlnj2nrUvsJoQWxczb4oWt+uUDTzHEGnBKkgM6nORYkSpKRtpz+jpPZNOMAXFU0 qyLTuVH6xw8EoiCP9vjOVdfENTBtYgwiZxrmLdWvUxs69voysGUBAvkLJrQprF1Zwq0x fUYA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=ce65Ks4e; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d24si1387897otq.202.2020.03.04.07.48.23; Wed, 04 Mar 2020 07:48:34 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=ce65Ks4e; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388219AbgCDPsF (ORCPT + 99 others); Wed, 4 Mar 2020 10:48:05 -0500 Received: from mail-wr1-f67.google.com ([209.85.221.67]:45282 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388181AbgCDPsE (ORCPT ); Wed, 4 Mar 2020 10:48:04 -0500 Received: by mail-wr1-f67.google.com with SMTP id v2so2963293wrp.12 for ; Wed, 04 Mar 2020 07:48:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=JH3iKdoX60vBDf5RPVZX6I6Dg2qntJTjRhn9rqqRbkU=; b=ce65Ks4eMK1y7cjThJcC8xe2T0GpZxp0Y+G35ZaB+P0atYcbffyjFrn2rV5D+ghDVU A4GZnpbhNKizq6u4X16MSbcKPlq1vVvO3PSxW+87YBkymRC/1qwwWikmt8GEexTzo2tg B7RhyEdQ+sXdUVuV3tsaj+MgXW5XPgmLgFxzw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=JH3iKdoX60vBDf5RPVZX6I6Dg2qntJTjRhn9rqqRbkU=; b=BSerC21hOQHeCGGMNPMmkrTcrHbbwpwMlnaDphisR9Yvq3SHGxxm0oKSU2v4eYIczP zW821PVeRVGsHE/MOKB80+RsI0eFrjrwExeCDC1CBvJkBrTJ+7zIA/RwBK469r/T5Foj haDNbO26G+tfAsZ+lA5QasBdX0sb4zkbhYw67CLRs8+djPqzso58OwZLUsWHE1odg/PR wDEnMU7aOfhSodLc0yddqYbJjsrD4gtvsKGvjKCifS4AtsKD3e+u5IJkutinsuZ1siJ6 fajPpISJnROF2whJjb6LpMekDEFSX1kc4tNJovtlQOM2We2DXMQJj9Dvhg6mT7YqpjiZ 768A== X-Gm-Message-State: ANhLgQ3mlfQ+XjJGUPnuPKfAZC0x9uOQsRZwAkH9tP/OGBrPvmQdlEDx uVqVNRrdIhacA6+IcJ8jMPA9jQ== X-Received: by 2002:adf:c44a:: with SMTP id a10mr4453283wrg.279.1583336882040; Wed, 04 Mar 2020 07:48:02 -0800 (PST) Received: from kpsingh-kernel.localdomain ([2a00:79e1:abc:308:8ca0:6f80:af01:b24]) by smtp.gmail.com with ESMTPSA id u25sm4816091wml.17.2020.03.04.07.48.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Mar 2020 07:48:01 -0800 (PST) From: KP Singh To: linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org Cc: Andrii Nakryiko , Alexei Starovoitov , Daniel Borkmann , Paul Turner , Jann Horn , Florent Revest , Brendan Jackman Subject: [PATCH bpf-next v3 7/7] bpf: Add selftests for BPF_MODIFY_RETURN Date: Wed, 4 Mar 2020 16:47:47 +0100 Message-Id: <20200304154747.23506-8-kpsingh@chromium.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200304154747.23506-1-kpsingh@chromium.org> References: <20200304154747.23506-1-kpsingh@chromium.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: KP Singh Test for two scenarios: * When the fmod_ret program returns 0, the original function should be called along with fentry and fexit programs. * When the fmod_ret program returns a non-zero value, the original function should not be called, no side effect should be observed and fentry and fexit programs should be called. The result from the kernel function call and whether a side-effect is observed is returned via the retval attr of the BPF_PROG_TEST_RUN (bpf) syscall. Signed-off-by: KP Singh Acked-by: Andrii Nakryiko --- net/bpf/test_run.c | 22 ++++++- .../selftests/bpf/prog_tests/modify_return.c | 65 +++++++++++++++++++ .../selftests/bpf/progs/modify_return.c | 49 ++++++++++++++ 3 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/bpf/prog_tests/modify_return.c create mode 100644 tools/testing/selftests/bpf/progs/modify_return.c diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c index 3600f098e7c6..4c921f5154e0 100644 --- a/net/bpf/test_run.c +++ b/net/bpf/test_run.c @@ -10,6 +10,7 @@ #include #include #include +#include #define CREATE_TRACE_POINTS #include @@ -143,6 +144,14 @@ int noinline bpf_fentry_test6(u64 a, void *b, short c, int d, void *e, u64 f) return a + (long)b + c + d + (long)e + f; } +int noinline bpf_modify_return_test(int a, int *b) +{ + *b += 1; + return a + *b; +} + +ALLOW_ERROR_INJECTION(bpf_modify_return_test, ERRNO); + static void *bpf_test_init(const union bpf_attr *kattr, u32 size, u32 headroom, u32 tailroom) { @@ -168,7 +177,9 @@ int bpf_prog_test_run_tracing(struct bpf_prog *prog, const union bpf_attr *kattr, union bpf_attr __user *uattr) { - int err = -EFAULT; + u16 side_effect = 0, ret = 0; + int b = 2, err = -EFAULT; + u32 retval = 0; switch (prog->expected_attach_type) { case BPF_TRACE_FENTRY: @@ -181,10 +192,19 @@ int bpf_prog_test_run_tracing(struct bpf_prog *prog, bpf_fentry_test6(16, (void *)17, 18, 19, (void *)20, 21) != 111) goto out; break; + case BPF_MODIFY_RETURN: + ret = bpf_modify_return_test(1, &b); + if (b != 2) + side_effect = 1; + break; default: goto out; } + retval = ((u32)side_effect << 16) | ret; + if (copy_to_user(&uattr->test.retval, &retval, sizeof(retval))) + goto out; + err = 0; out: trace_bpf_test_finish(&err); diff --git a/tools/testing/selftests/bpf/prog_tests/modify_return.c b/tools/testing/selftests/bpf/prog_tests/modify_return.c new file mode 100644 index 000000000000..97fec70c600b --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/modify_return.c @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * Copyright 2020 Google LLC. + */ + +#include +#include "modify_return.skel.h" + +#define LOWER(x) ((x) & 0xffff) +#define UPPER(x) ((x) >> 16) + + +static void run_test(__u32 input_retval, __u16 want_side_effect, __s16 want_ret) +{ + struct modify_return *skel = NULL; + int err, prog_fd; + __u32 duration = 0, retval; + __u16 side_effect; + __s16 ret; + + skel = modify_return__open_and_load(); + if (CHECK(!skel, "skel_load", "modify_return skeleton failed\n")) + goto cleanup; + + err = modify_return__attach(skel); + if (CHECK(err, "modify_return", "attach failed: %d\n", err)) + goto cleanup; + + skel->bss->input_retval = input_retval; + prog_fd = bpf_program__fd(skel->progs.fmod_ret_test); + err = bpf_prog_test_run(prog_fd, 1, NULL, 0, NULL, 0, + &retval, &duration); + + CHECK(err, "test_run", "err %d errno %d\n", err, errno); + + side_effect = UPPER(retval); + ret = LOWER(retval); + + CHECK(ret != want_ret, "test_run", + "unexpected ret: %d, expected: %d\n", ret, want_ret); + CHECK(side_effect != want_side_effect, "modify_return", + "unexpected side_effect: %d\n", side_effect); + + CHECK(skel->bss->fentry_result != 1, "modify_return", + "fentry failed\n"); + CHECK(skel->bss->fexit_result != 1, "modify_return", + "fexit failed\n"); + CHECK(skel->bss->fmod_ret_result != 1, "modify_return", + "fmod_ret failed\n"); + +cleanup: + modify_return__destroy(skel); +} + +void test_modify_return(void) +{ + run_test(0 /* input_retval */, + 1 /* want_side_effect */, + 4 /* want_ret */); + run_test(-EINVAL /* input_retval */, + 0 /* want_side_effect */, + -EINVAL /* want_ret */); +} + diff --git a/tools/testing/selftests/bpf/progs/modify_return.c b/tools/testing/selftests/bpf/progs/modify_return.c new file mode 100644 index 000000000000..8b7466a15c6b --- /dev/null +++ b/tools/testing/selftests/bpf/progs/modify_return.c @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * Copyright 2020 Google LLC. + */ + +#include +#include +#include + +char _license[] SEC("license") = "GPL"; + +static int sequence = 0; +__s32 input_retval = 0; + +__u64 fentry_result = 0; +SEC("fentry/bpf_modify_return_test") +int BPF_PROG(fentry_test, int a, __u64 b) +{ + sequence++; + fentry_result = (sequence == 1); + return 0; +} + +__u64 fmod_ret_result = 0; +SEC("fmod_ret/bpf_modify_return_test") +int BPF_PROG(fmod_ret_test, int a, int *b, int ret) +{ + sequence++; + /* This is the first fmod_ret program, the ret passed should be 0 */ + fmod_ret_result = (sequence == 2 && ret == 0); + return input_retval; +} + +__u64 fexit_result = 0; +SEC("fexit/bpf_modify_return_test") +int BPF_PROG(fexit_test, int a, __u64 b, int ret) +{ + sequence++; + /* If the input_reval is non-zero a successful modification should have + * occurred. + */ + if (input_retval) + fexit_result = (sequence == 3 && ret == input_retval); + else + fexit_result = (sequence == 3 && ret == 4); + + return 0; +} -- 2.20.1