Received: by 2002:a25:c205:0:0:0:0:0 with SMTP id s5csp4013168ybf; Tue, 3 Mar 2020 17:57:27 -0800 (PST) X-Google-Smtp-Source: ADFU+vuLsLnLRkleHLXmfGhOTAPj80j0NTVSXm5zaa7QBKD/AMj8VsOGLABTYJyjw/U4G1ApgJtb X-Received: by 2002:a9d:3e89:: with SMTP id b9mr615684otc.3.1583287047827; Tue, 03 Mar 2020 17:57:27 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1583287047; cv=none; d=google.com; s=arc-20160816; b=xkP8YZJjwIG31oSaETvtxqN3FaY8Mf0isWZff9DDPBvyEz6IlQ2Wkj4uskEpaKECUY o3B5JcaW7bdzuazTyRQpcgYyOvDhri42fB/Anmvi4fLldI7tTkH48AeJz1N6A/nK/9Fg /zZX2CFPVCPUkP0FOJ/euhU9YZBzkJeoXXk7TOAFKEZEFEgm05SwKt1HrRB/eeGSZYWM 4aewJMAroeyNdvAyOiXN7UDTk/okjWELCZnSYYOSwe9sRie1T9VcdexAEQoT7xAaISWS 6wN0dVAc3tVOYPTVP44VDGBQ03ab57ZBFOPt3KXA1ZhTRLZm32iVz19XsqVAaI7oZBq0 C/kA== 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=LcymWsBAdk5me+NoqRNTXLpLzAaL1XwKUZqnG1jLu9Ag9u1EW8bUlZcamPjd1WOjpL PLYs9fKVPfFuOy30mHVwWSIpTAmkPPzzLGExBUq8DnE4dDLilTe6LvymNHYvd5rrMC2N OUFWDvZO2bA35t+dzd8UtJKDosIxOt9LduRFX+aEpSC/b5YRVc4qGfXr55YZBP98Yq9l dQi1TkoLh0jmOTlOGZdBOyHB93BKi6csyMuuS3nqN3YtiQ7LW9TUkTzQIQvZv7ek/8zm QKhWcLCRpRdV7wACV+/qISOyG1DjHanMa0QCQ4QfG4b2LKlOZb1C9JtwMwViOnthHakI /bXw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=jScRWgx6; 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 a16si323226oid.4.2020.03.03.17.57.16; Tue, 03 Mar 2020 17:57:27 -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=jScRWgx6; 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 S2387656AbgCDBzv (ORCPT + 99 others); Tue, 3 Mar 2020 20:55:51 -0500 Received: from mail-wm1-f66.google.com ([209.85.128.66]:38001 "EHLO mail-wm1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387626AbgCDBzr (ORCPT ); Tue, 3 Mar 2020 20:55:47 -0500 Received: by mail-wm1-f66.google.com with SMTP id u9so152065wml.3 for ; Tue, 03 Mar 2020 17:55:45 -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=jScRWgx6NIDkPAYeaC4QqY/IZhA8mvih8Ll0QSkH7y+l1pJCP+vUNNHH+9X/vqAaB9 uBLAdVHqz/2V8+u031cLaYemYSYOUSPj4ysqSwxEihvRnwNu42jfXQ4S/u2wsDRVu9td V4PLYbAKzHo9KUMrY9ADT450K0z+nVRoPST/4= 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=C4ydUwxLAta2apYv6jSPzfjJAnPHOddppAhfUZVpH0M4DwCxihPycBq3srNLInkovo RmJqLT9sTHIPIftJaEIY5d2+k7MrwsGkqh1GcrVVWVXAheSCGdZh7nmLxhwMrhMlnKsb 9usidkTPWDk8n3JazCzLvawSNtsDVFEtEqqgL5l57GwDQwOhK/vr3X+IrJsTjzcCHLW6 OR7Y2s3TyCRmrJgsx/syGDlAr4V0wZUEFZCfkKcrSraTcH2eZfYxt9zpmP2FCWVTKbKL 2Mn/14NfDuIayRtqbcMXzVBLaSLRGLzbS7T+Rtah3xwbW5xKRNQ4Y+oW4NynXjpN//s2 /0GA== X-Gm-Message-State: ANhLgQ2wlLEcQCTECe1K6pCYCqD8aKHRCvSvxRN2nu1GaU43V3Jwgvqr NsNgMwkDJiech3RvhZJHaKYaZQ== X-Received: by 2002:a1c:a515:: with SMTP id o21mr588522wme.124.1583286945086; Tue, 03 Mar 2020 17:55:45 -0800 (PST) Received: from kpsingh-kernel.localdomain (77-56-209-237.dclient.hispeed.ch. [77.56.209.237]) by smtp.gmail.com with ESMTPSA id a184sm1475444wmf.29.2020.03.03.17.55.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 Mar 2020 17:55:44 -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 v2 7/7] bpf: Add selftests for BPF_MODIFY_RETURN Date: Wed, 4 Mar 2020 02:55:28 +0100 Message-Id: <20200304015528.29661-8-kpsingh@chromium.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200304015528.29661-1-kpsingh@chromium.org> References: <20200304015528.29661-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