Received: by 2002:a05:7412:8d10:b0:f3:1519:9f41 with SMTP id bj16csp3761038rdb; Sun, 10 Dec 2023 21:09:49 -0800 (PST) X-Google-Smtp-Source: AGHT+IEcWXHA4alFf6WTQZU0WoxAtLj4HQxtw/ZCSXh1JcWdeGkNoP43tACvIpHVH66mORufuKVy X-Received: by 2002:a17:903:25c2:b0:1d0:9c97:6fed with SMTP id jc2-20020a17090325c200b001d09c976fedmr1287763plb.44.1702271389338; Sun, 10 Dec 2023 21:09:49 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1702271389; cv=none; d=google.com; s=arc-20160816; b=Ys0IoXGFtARuzzcuxPeH1aRLsZLS+HSpg5ZkbCOIWE1RyW2xEnvtMYa4rQzh9A42Wq QP/x+amo9s5hcbhJ2qw8YjnWd29MxX0JLkDzF/cR31Se/ovwYv+SvRp2KyF7DjoQ7evk JBzomrirWUrJJxfbyDURGMr6u0Szd0MnlrRUPTTnjkQPQ64M8Evmj14mdV6xtPhVKWY4 yR1qvjsN20DLBfjVz4Y87kql/OUtFxYB+LVnR72Pza+R15ZNPVJe8PXvmUoW9YQwCQjS LDPWE9CeCbYfhp/CjqkQzBY4FjDJjl05n7mlfeKXhsM6/ElT4VNps9j/4SGzzj12n2US cFqw== 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=xHbu0t6RQovwgG4UpuUModKkP5V4juUKznEMDieJw5c=; fh=29QJZHWIVCO02J6jOMN0vUqLkk2froOo0+tatGMCho4=; b=uMOaSxQJM9fhjQvy/rqUHu5UvGni9RQ5cLUtZVIQHLdcoXhGYjgT9aoOS4bdf5tC1e bFCmM1i9chIop3Yk8/ajy5xSZsWl++fIcB2gTrXdwuzR+01FPEcTvJopPDr3pPkHzHpa gwaIUOxU6aC+J9P6IdTLhzvtq8kNqo9VIeQHymrSjsljY1+yz5BVWniaCaTX30SWhfvK UNlNfo330VXxnQJ1shgaEeB2xOXVwQ5ewfKN2HSMa3A1Na5XWqSkCeaiisfwwAmcJ/rU A3vxIBA+rXxdL3JUtrSmqTMjOGCCmOco4TZdQNiebh3ruL+7PO5KFgBY4NPlPkIm0eRw ZxaQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=RCiat+Uo; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 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 snail.vger.email (snail.vger.email. [2620:137:e000::3:7]) by mx.google.com with ESMTPS id p11-20020a170902eacb00b001cf50ef35besi5633827pld.51.2023.12.10.21.09.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 10 Dec 2023 21:09:49 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) client-ip=2620:137:e000::3:7; Authentication-Results: mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=RCiat+Uo; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 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 snail.vger.email (Postfix) with ESMTP id B6838809500E; Sun, 10 Dec 2023 21:09:47 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232982AbjLKFJj (ORCPT + 99 others); Mon, 11 Dec 2023 00:09:39 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60810 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229478AbjLKFJi (ORCPT ); Mon, 11 Dec 2023 00:09:38 -0500 Received: from out-182.mta0.migadu.com (out-182.mta0.migadu.com [IPv6:2001:41d0:1004:224b::b6]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 59674BB for ; Sun, 10 Dec 2023 21:09:43 -0800 (PST) Message-ID: <4457e84f-4417-4a60-a814-9288b0756d91@linux.dev> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1702271381; 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=xHbu0t6RQovwgG4UpuUModKkP5V4juUKznEMDieJw5c=; b=RCiat+Uo7cm2znHWbA9yCBo0bvR2PQHKM5fx4OOKc4eXxGrlfD3OgC3R3fod5AWvvSqa63 HHGJIXbVekzu+sj1SZGpMhwMIGSZ/bH+OgZjd/RTAbQCGONJxtzvaCB0jjFjH7IjIDDxlL Tz4ppcnpwzRSqRgYzDVAt9KqpV8Ql1g= Date: Sun, 10 Dec 2023 21:09:32 -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 , andrii@kernel.org Cc: 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> X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Yonghong Song In-Reply-To: <20231210130001.2050847-1-menglong8.dong@gmail.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Migadu-Flow: FLOW_OUT X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net 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 (snail.vger.email [0.0.0.0]); Sun, 10 Dec 2023 21:09:47 -0800 (PST) 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(). > > 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? > + 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))