From patchwork Fri Nov 13 17:17:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitrii Banshchikov X-Patchwork-Id: 11904343 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 X-Spam-Level: X-Spam-Status: No, score=-12.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3DF2CC388F7 for ; Fri, 13 Nov 2020 17:18:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C4B7A21D7F for ; Fri, 13 Nov 2020 17:18:02 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=ubique-spb-ru.20150623.gappssmtp.com header.i=@ubique-spb-ru.20150623.gappssmtp.com header.b="moGXPazp" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726268AbgKMRRs (ORCPT ); Fri, 13 Nov 2020 12:17:48 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57444 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726200AbgKMRRr (ORCPT ); Fri, 13 Nov 2020 12:17:47 -0500 Received: from mail-ej1-x642.google.com (mail-ej1-x642.google.com [IPv6:2a00:1450:4864:20::642]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7EC74C0617A6 for ; Fri, 13 Nov 2020 09:18:01 -0800 (PST) Received: by mail-ej1-x642.google.com with SMTP id o21so14566184ejb.3 for ; Fri, 13 Nov 2020 09:18:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ubique-spb-ru.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=YhCVPybufP4Udi2DHhySYxWlKgaOAdJWsU5QzruK82I=; b=moGXPazpO1VQB12tI7Vgdnkpc7XUXrfhNxI4gWC2p7h0/iOMpWlokk1QrMFfM3L+EK mQ4P+OaU5zAH8WYImPqiCvEidwdWy5c3zLm/TUoYhIDDuLxQpaL89iSEJh9hkQKrFjwH r1fQbFAP3kQW74QJHcsmGyOLIBpsyt6/oC6J8WsUb8SvwaC6VXmWScsv4aYB0NWhEVJw 9to0bJE9mxrXGZPdiK126G2LXIu1zpFMlN58RNPJ+k3+7wxMUiFBv7o3dX942pgoBe4Y iZfs1VCdLq9oLrxCiN+WDf/07eCH0RBOCgt3FowuQuh6f2p0NZnf3gxmZcNaLVamTaJf rbkA== 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:mime-version :content-transfer-encoding; bh=YhCVPybufP4Udi2DHhySYxWlKgaOAdJWsU5QzruK82I=; b=Pq7/H+wr4L+NiuoMAJ1razDLFVetNr1hRNTgAbDjNJHa/o3q/i80rfRdi8d663AICQ 4j76s5COAp/VdEiqEMTpD7fTDKRUalsqCs/+RuSW29hg4e5HqFgLqMGu271cT/66ePJu GBFwUOi0Fyd6MzLtrBgpfoutnPjbDgpg9u00ObhEQG6YVZ0V/SSGaVEoRNuyItgkv1FR wriBJhBMJ8fNUeJ3TQuOwwVR0PlViGUJaLj/xY7IXcVuysa9+YSyBLGH+0bDZh/L2YaR DWCOsILRLpdkaKRrndcCWdW60i/FKCQ3Prfw8UpvVFIbEbMsqxPp4FvxbuiuuIVrPtfG iMww== X-Gm-Message-State: AOAM5322v2Mbeu2j0HIU9XHD/f12bcRBPWRlYiAyWjvte6Oqq2PEaC5Q n/WInxhC4wuQd5ZJubQiBuKFTxVElTg/ngGshZU= X-Google-Smtp-Source: ABdhPJyUXHWYW/MtZAVdr3Am9alhpXEa0cgn6J9YamtmcHswf0N+3RanTzmhF0gQxViS+FOGWte5LQ== X-Received: by 2002:a17:906:4753:: with SMTP id j19mr2756166ejs.65.1605287879462; Fri, 13 Nov 2020 09:17:59 -0800 (PST) Received: from localhost ([2620:10d:c093:400::5:7b07]) by smtp.gmail.com with ESMTPSA id f19sm4222579ejk.116.2020.11.13.09.17.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 13 Nov 2020 09:17:58 -0800 (PST) From: Dmitrii Banshchikov To: bpf@vger.kernel.org Cc: kernel-team@fb.com, rdna@fb.com, ast@kernel.org, daniel@iogearbox.net, kafai@fb.com, songliubraving@fb.com, yhs@fb.com, andrii@kernel.org, john.fastabend@gmail.com, kpsingh@chromium.org, toke@redhat.com, netdev@vger.kernel.org, me@ubique.spb.ru Subject: [PATCH bpf v2] bpf: relax return code check for subprograms Date: Fri, 13 Nov 2020 17:17:56 +0000 Message-Id: <20201113171756.90594-1-me@ubique.spb.ru> X-Mailer: git-send-email 2.25.4 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net Currently verifier enforces return code checks for subprograms in the same manner as it does for program entry points. This prevents returning arbitrary scalar values from subprograms. Scalar type of returned values is checked by btf_prepare_func_args() and hence it should be safe to allow only scalars for now. Relax return code checks for subprograms and allow any correct scalar values. Signed-off-by: Dmitrii Banshchikov Fixes: 51c39bb1d5d10 (bpf: Introduce function-by-function verification) Acked-by: Andrii Nakryiko --- v1 -> v2: - Move is_subprog flag determination to check_return_code() - Remove unneeded intermediate function from tests - Use __noinline instead of __attribute__((noinline)) in tests kernel/bpf/verifier.c | 15 +++++++++++++-- .../bpf/prog_tests/test_global_funcs.c | 1 + .../selftests/bpf/progs/test_global_func8.c | 19 +++++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 tools/testing/selftests/bpf/progs/test_global_func8.c diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 6204ec705d80..1388bf733071 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -7786,9 +7786,11 @@ static int check_return_code(struct bpf_verifier_env *env) struct tnum range = tnum_range(0, 1); enum bpf_prog_type prog_type = resolve_prog_type(env->prog); int err; + const bool is_subprog = env->cur_state->frame[0]->subprogno; /* LSM and struct_ops func-ptr's return type could be "void" */ - if ((prog_type == BPF_PROG_TYPE_STRUCT_OPS || + if (!is_subprog && + (prog_type == BPF_PROG_TYPE_STRUCT_OPS || prog_type == BPF_PROG_TYPE_LSM) && !prog->aux->attach_func_proto->type) return 0; @@ -7808,6 +7810,16 @@ static int check_return_code(struct bpf_verifier_env *env) return -EACCES; } + reg = cur_regs(env) + BPF_REG_0; + if (is_subprog) { + if (reg->type != SCALAR_VALUE) { + verbose(env, "At subprogram exit the register R0 is not a scalar value (%s)\n", + reg_type_str[reg->type]); + return -EINVAL; + } + return 0; + } + switch (prog_type) { case BPF_PROG_TYPE_CGROUP_SOCK_ADDR: if (env->prog->expected_attach_type == BPF_CGROUP_UDP4_RECVMSG || @@ -7861,7 +7873,6 @@ static int check_return_code(struct bpf_verifier_env *env) return 0; } - reg = cur_regs(env) + BPF_REG_0; if (reg->type != SCALAR_VALUE) { verbose(env, "At program exit the register R0 is not a known value (%s)\n", reg_type_str[reg->type]); diff --git a/tools/testing/selftests/bpf/prog_tests/test_global_funcs.c b/tools/testing/selftests/bpf/prog_tests/test_global_funcs.c index 193002b14d7f..32e4348b714b 100644 --- a/tools/testing/selftests/bpf/prog_tests/test_global_funcs.c +++ b/tools/testing/selftests/bpf/prog_tests/test_global_funcs.c @@ -60,6 +60,7 @@ void test_test_global_funcs(void) { "test_global_func5.o" , "expected pointer to ctx, but got PTR" }, { "test_global_func6.o" , "modified ctx ptr R2" }, { "test_global_func7.o" , "foo() doesn't return scalar" }, + { "test_global_func8.o" }, }; libbpf_print_fn_t old_print_fn = NULL; int err, i, duration = 0; diff --git a/tools/testing/selftests/bpf/progs/test_global_func8.c b/tools/testing/selftests/bpf/progs/test_global_func8.c new file mode 100644 index 000000000000..d55a6544b1ab --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_global_func8.c @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright (c) 2020 Facebook */ +#include +#include +#include + +__noinline int foo(struct __sk_buff *skb) +{ + return bpf_get_prandom_u32(); +} + +SEC("cgroup_skb/ingress") +int test_cls(struct __sk_buff *skb) +{ + if (!foo(skb)) + return 0; + + return 1; +}