Received: by 2002:a05:7412:8d10:b0:f3:1519:9f41 with SMTP id bj16csp4028653rdb; Mon, 11 Dec 2023 07:04:20 -0800 (PST) X-Google-Smtp-Source: AGHT+IE5OoIUGmQNi1fB6Pfp99mTruRkaWIYUUXe6YPGhbRPJS0aUuuDu/U9Ob1/Dtq114JUwDRv X-Received: by 2002:a05:6a21:6da1:b0:18f:c6ac:807f with SMTP id wl33-20020a056a216da100b0018fc6ac807fmr2418619pzb.51.1702307060177; Mon, 11 Dec 2023 07:04:20 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1702307060; cv=none; d=google.com; s=arc-20160816; b=a080Aethr2F+KRBW+wEAUXLADT+p4yqMHEz3QlCjND2rquOeSkXPNUuoKD8DsSS7nC KMaisCodWtu2SIptPXMx/V50xDzhESMGx37vvP8EJbFQr+lEVZKI8yoyogdM6jY840A9 SMhMvqVo4QXxqG2QFEuJpDbm0VBiq2HITyNpg4f85/3iDeyJLupxRTe3H62BvlUlYr3+ 9XdN/aPADpHF/CzGQyrQniWb/7I1ST9vOE/v+aEe6C6pKr6QS5IMR9wupU8atwwkoSP1 766ws2lbH9bdP3NMdEty4lrLr7Jrf9OPPyMk1bGpJYcY8zEDDs/dKsPXDCNo3KAJlW9S bjOw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:in-reply-to:from :references:cc:to:content-language:subject:mime-version:date :dkim-signature:message-id; bh=1DFnlxZFggZVgkEskBvFOCKE4mVCcaVgt6sW9dWz+ac=; fh=BVP/S5bgD98xGlhLRHCdC8Rp9paHXgAfQY/fpZuailk=; b=Y1kkT50PkdspNst4MdyCUqcupsXPwsujBSfOcRwe6Qsplx7rkLPiGvP8lrRcqjrj06 mWuOqToM29yRzqEvbuVPPZk2gf5zKsOBMP8jX0pOWGedAtL8/8WpXOqwtBfrEeZHuHP5 K00AFg3/Entjv+h56qNyGcwWiDgjNiBGwxDDRfJ64t+KTGuUkO+50x/krRawU0jDSWVv TmKJKXmaKiwTPlfDewlDQtiXsv+qYfRJ7IPV8JnchikahiimLpo6OtcSVmkFq9SDwN8n 2wX0hs4DmKHzrF3UPrff8fIeuba32fPiGihqK97zJFfxqjCzsAstaWz1uQBj9B3cuRpX KvGw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=KU1IlMa4; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.32 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Return-Path: Received: from agentk.vger.email (agentk.vger.email. [23.128.96.32]) by mx.google.com with ESMTPS id w16-20020a63c110000000b005c2786b7e32si6131563pgf.812.2023.12.11.07.04.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 Dec 2023 07:04:20 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.32 as permitted sender) client-ip=23.128.96.32; Authentication-Results: mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=KU1IlMa4; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.32 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by agentk.vger.email (Postfix) with ESMTP id 0446F805C72E; Mon, 11 Dec 2023 07:04:15 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at agentk.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343701AbjLKPD6 (ORCPT + 99 others); Mon, 11 Dec 2023 10:03:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38562 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234925AbjLKPD4 (ORCPT ); Mon, 11 Dec 2023 10:03:56 -0500 Received: from out-182.mta1.migadu.com (out-182.mta1.migadu.com [95.215.58.182]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 427A8A9 for ; Mon, 11 Dec 2023 07:04:00 -0800 (PST) Message-ID: <96228ae1-a199-4f9a-8d40-d161a718c3c9@linux.dev> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1702307038; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=1DFnlxZFggZVgkEskBvFOCKE4mVCcaVgt6sW9dWz+ac=; b=KU1IlMa4KH/tAurEvOFH6yS0AfIw/e3AgOMZpmePwEknxIrBM6YdeaapLouRJyVjGsqRNa XzSemoDfk33OntFxwfM+pbRrVA0bWMeGhCAymW4usgRyDcCH6FqLnYWScjXfHiCERnMVbp YQKVN/O4gATDuCanBtLLjL3blIUS1q8= Date: Mon, 11 Dec 2023 07:03:49 -0800 MIME-Version: 1.0 Subject: Re: [PATCH bpf-next] bpf: make the verifier trace the "not qeual" for regs Content-Language: en-GB To: Menglong Dong Cc: andrii@kernel.org, ast@kernel.org, daniel@iogearbox.net, john.fastabend@gmail.com, martin.lau@linux.dev, song@kernel.org, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, jolsa@kernel.org, bpf@vger.kernel.org, linux-kernel@vger.kernel.org References: <20231210130001.2050847-1-menglong8.dong@gmail.com> <4457e84f-4417-4a60-a814-9288b0756d91@linux.dev> X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Yonghong Song In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Migadu-Flow: FLOW_OUT X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on agentk.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (agentk.vger.email [0.0.0.0]); Mon, 11 Dec 2023 07:04:15 -0800 (PST) On 12/11/23 1:39 AM, Menglong Dong wrote: > Hello, > > On Mon, Dec 11, 2023 at 1:09 PM Yonghong Song wrote: >> >> On 12/10/23 5:00 AM, Menglong Dong wrote: >>> We can derive some new information for BPF_JNE in regs_refine_cond_op(). >>> Take following code for example: >>> >>> /* The type of "a" is u16 */ >>> if (a > 0 && a < 100) { >>> /* the range of the register for a is [0, 99], not [1, 99], >>> * and will cause the following error: >>> * >>> * invalid zero-sized read >>> * >>> * as a can be 0. >>> */ >>> bpf_skb_store_bytes(skb, xx, xx, a, 0); >>> } >> Could you have a C test to demonstrate this example? >> Also, you should have a set of inline asm code (progs/verifier*.c) >> to test various cases as in mark_reg32_not_equal() and >> mark_reg_not_equal(). >> > Yeah! I found that this part is tested in the test_progs/reg_bounds_crafted > too, and this commit failed that test case, which I should fix in the next > version. > >>> In the code above, "a > 0" will be compiled to "jmp xxx if a == 0". In the >>> TRUE branch, the dst_reg will be marked as known to 0. However, in the >>> fallthrough(FALSE) branch, the dst_reg will not be handled, which makes >>> the [min, max] for a is [0, 99], not [1, 99]. >>> >>> For BPF_JNE, we can reduce the range of the dst reg if the src reg is a >>> const and is exactly the edge of the dst reg. >>> >>> Signed-off-by: Menglong Dong >>> --- >>> kernel/bpf/verifier.c | 45 ++++++++++++++++++++++++++++++++++++++++++- >>> 1 file changed, 44 insertions(+), 1 deletion(-) >>> >>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c >>> index 727a59e4a647..7b074ac93190 100644 >>> --- a/kernel/bpf/verifier.c >>> +++ b/kernel/bpf/verifier.c >>> @@ -1764,6 +1764,40 @@ static void __mark_reg_const_zero(struct bpf_reg_state *reg) >>> reg->type = SCALAR_VALUE; >>> } >>> >>> +#define CHECK_REG_MIN(value) \ >>> +do { \ >>> + if ((value) == (typeof(value))imm) \ >>> + value++; \ >>> +} while (0) >>> + >>> +#define CHECK_REG_MAX(value) \ >>> +do { \ >>> + if ((value) == (typeof(value))imm) \ >>> + value--; \ >>> +} while (0) >>> + >>> +static void mark_reg32_not_equal(struct bpf_reg_state *reg, u64 imm) >>> +{ >> What if reg->s32_min_value == imm and reg->s32_max_value == imm? >> Has this been handled in previous verifier logic? > Will such a case happen? In current code path, the src reg is a const, > and the is_branch_taken() will return 0 or 1 if the > dst_reg->s32_min_value == dst_reg->s32_max_value. > > Enn......maybe we can do more checking here in case that someone > calls this function in another place. I double checked the source code as well. Indeed, 'reg' should not be a constant as it has been handled in is_branch_taken() properly. Ignore my comments above then. Thanks! > > Thanks! > Menglong Dong > >>> + CHECK_REG_MIN(reg->s32_min_value); >>> + CHECK_REG_MAX(reg->s32_max_value); >>> + CHECK_REG_MIN(reg->u32_min_value); >>> + CHECK_REG_MAX(reg->u32_max_value); >>> +} >>> + >>> +static void mark_reg_not_equal(struct bpf_reg_state *reg, u64 imm) >>> +{ >>> + CHECK_REG_MIN(reg->smin_value); >>> + CHECK_REG_MAX(reg->smax_value); >>> + >>> + CHECK_REG_MIN(reg->umin_value); >>> + CHECK_REG_MAX(reg->umax_value); >>> + >>> + CHECK_REG_MIN(reg->s32_min_value); >>> + CHECK_REG_MAX(reg->s32_max_value); >>> + CHECK_REG_MIN(reg->u32_min_value); >>> + CHECK_REG_MAX(reg->u32_max_value); >>> +} >>> + >>> static void mark_reg_known_zero(struct bpf_verifier_env *env, >>> struct bpf_reg_state *regs, u32 regno) >>> { >>> @@ -14332,7 +14366,16 @@ static void regs_refine_cond_op(struct bpf_reg_state *reg1, struct bpf_reg_state >>> } >>> break; >>> case BPF_JNE: >>> - /* we don't derive any new information for inequality yet */ >>> + /* try to recompute the bound of reg1 if reg2 is a const and >>> + * is exactly the edge of reg1. >>> + */ >>> + if (is_reg_const(reg2, is_jmp32)) { >>> + val = reg_const_value(reg2, is_jmp32); >>> + if (is_jmp32) >>> + mark_reg32_not_equal(reg1, val); >>> + else >>> + mark_reg_not_equal(reg1, val); >>> + } >>> break; >>> case BPF_JSET: >>> if (!is_reg_const(reg2, is_jmp32))