Received: by 2002:a05:7412:8d10:b0:f3:1519:9f41 with SMTP id bj16csp5651242rdb; Wed, 13 Dec 2023 15:30:57 -0800 (PST) X-Google-Smtp-Source: AGHT+IFH298eLyaaBdAhpeks9TM9ysg6zYQoZYbeeqbPMFkqgihy2bh6KaH41LMO/HTaw6jbtacW X-Received: by 2002:a05:6e02:18cc:b0:35d:7b69:85ed with SMTP id s12-20020a056e0218cc00b0035d7b6985edmr12448127ilu.7.1702510257289; Wed, 13 Dec 2023 15:30:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1702510257; cv=none; d=google.com; s=arc-20160816; b=GTaA7IGpfqjSowusu72X47I63GMJfyusbImVxRwbZWS4tXXetNAA5dLmxYiaQ8dm9R lYIy2uQU65I83og7cEq9fIisGMRe620N1+39felX9JJlisimZ+w9QykWRvYGy9lVueFf NBckULp5krELppqcw4Gj5k0ekRVPz4I20WHcmoa+1gxD2SZgpO5uv7/eqMgCOb69tNiC Bd2SG2fglI0ZRLAaFoYoEO9SFyatxkVUKzr8URSMYFsngJlHf23Yo1E19GPB+JM2ClJ6 SHl3H7G0XrprbBPCzxydVGaQUnTVOwJWYlmVKl1qjvbyG53ywzJ1pnw/AUmbN1xV2rn1 W9LQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:cc:to:subject :message-id:date:from:in-reply-to:references:mime-version :dkim-signature; bh=6ozznquyIJ/JaWIy+Ld4slYR/sYTFdj2kcAlWF/oGlQ=; fh=o8GAfn95lUzBpYfK/izBeLtn1erb69GFM3kHoXfNyHA=; b=iljA9/gYAZOdpqMFkzzon1VHvWwABF1WuBCwFpwujCYSHokfTomEVZxfrEFxoYLcvM b2DXc/djQw/Le9gdvpkkGUXzdsHXf+BztXOyKfvZs8JYbYlpoAOm28Teg3OEMlw+Tnj1 BFvOU+SoBvLu8a4abcnOyuR5XlJ8+iYuFQo4UUG24N7qMCk7M5Gn3mBVvFoEgbEQIDT4 5qMfjenrn/1ZcO7LO1Kxf1pt4Wq407HnZws51f7yMCOKvW27t6ew5KwW5l4AGHOi1KYe wxwhhhbAYYix+GPbDzUXxXO7wj9fFXPqylirQBFKi8CHmJ+kwEkiz45g9E7XsKzM9gXl MqUQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=XqwV6BP8; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:3 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from lipwig.vger.email (lipwig.vger.email. [2620:137:e000::3:3]) by mx.google.com with ESMTPS id e12-20020a65478c000000b005c16f26b1b4si10081061pgs.440.2023.12.13.15.30.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 Dec 2023 15:30:57 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:3 as permitted sender) client-ip=2620:137:e000::3:3; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=XqwV6BP8; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:3 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by lipwig.vger.email (Postfix) with ESMTP id 0C9D2807C648; Wed, 13 Dec 2023 15:30:39 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at lipwig.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230050AbjLMXaU (ORCPT + 99 others); Wed, 13 Dec 2023 18:30:20 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47624 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229896AbjLMXaT (ORCPT ); Wed, 13 Dec 2023 18:30:19 -0500 Received: from mail-ej1-x62b.google.com (mail-ej1-x62b.google.com [IPv6:2a00:1450:4864:20::62b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BAF5DA3; Wed, 13 Dec 2023 15:30:24 -0800 (PST) Received: by mail-ej1-x62b.google.com with SMTP id a640c23a62f3a-a1f33c13ff2so646913666b.3; Wed, 13 Dec 2023 15:30:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702510223; x=1703115023; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=6ozznquyIJ/JaWIy+Ld4slYR/sYTFdj2kcAlWF/oGlQ=; b=XqwV6BP8EmnjF9ztA8NBWkhjXsQWnZOiqgjbIUJ77Cd89KgffHtwBWSeU7CgGVuOXg NNOIk+vxEpp7GYPhjsPbf2CY4ZCNPHmap9FHsmriqvYOjnwlz4pQV7A4bGwp5Rib847J /sxKyqc228w+gc0//weq4EVn4b/sec00VCe3ZAXMzTl0H9uJ4uNdafFYqhDuPJdPeedG i1qJLHyk7vakE0D1XwKky4763B4Ok8zEOpo+RRLWuHz3KY8UWKxdMeYx5hCfLDmo5JtE MXx3crfD59G42+kh6FOxKolN0tyc15gJTuJu8D2+awQLqCovkU8fT+gNcl6K75+qgd4v ozdA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702510223; x=1703115023; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=6ozznquyIJ/JaWIy+Ld4slYR/sYTFdj2kcAlWF/oGlQ=; b=kXRRYGDaDvjbU1RfMUJhA/OEAQGWWWo+4MklGkF2fR7qNgZBtKLzzRRjC4qCPPD9aT VJtF3C+wKkSfmQ+9LaSExBNf/GXTPmuPAWbS0fZb9PO8bRgUwchYK1iSkZoIm471gWrh dNidOSVrKqPwss4PcE0yzGXUdVPQEVzoZVG8ZQ8FOgv2nNIdT7cf7V4lryaG8ZDGy2Ax vfnuWKfuBG98rO12VkxFM/XJffoRnZNhOD8YwMPYBRJTBkM/5I6vRzZr2Tt/2FEI6p8i PNzu5mOXEJbPMj2w5zapPrfnZ5bTdOhPwzj3UFmsMXt/k6fUovopPuavEgalEaz/0Ebi SlgQ== X-Gm-Message-State: AOJu0YzSCoS5c5cRq0VGdAAhLXhdTzrqvmW717IUd5+wM9ZnjBOf0Cd+ wEBGUo/dR7o7Z5SA7Ez255OqrqWZIDy1bE9lsF0= X-Received: by 2002:a17:906:cc96:b0:a1d:8259:98d2 with SMTP id oq22-20020a170906cc9600b00a1d825998d2mr4306898ejb.61.1702510222743; Wed, 13 Dec 2023 15:30:22 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Andrii Nakryiko Date: Wed, 13 Dec 2023 15:30:10 -0800 Message-ID: Subject: Re: [Bug Report] bpf: incorrectly pruning runtime execution path To: Hao Sun Cc: Alexei Starovoitov , Andrii Nakryiko , Daniel Borkmann , bpf , Linux Kernel Mailing List , Eduard Zingerman Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-0.6 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, 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 lipwig.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 (lipwig.vger.email [0.0.0.0]); Wed, 13 Dec 2023 15:30:39 -0800 (PST) On Wed, Dec 13, 2023 at 2:25=E2=80=AFAM Hao Sun wrote= : > > On Wed, Dec 13, 2023 at 1:51=E2=80=AFAM Andrii Nakryiko > wrote: > > > > On Mon, Dec 11, 2023 at 7:31=E2=80=AFAM Hao Sun w= rote: > > > > > > Hi, > > > > > > The verifier incorrectly prunes a path expected to be executed at > > > runtime. In the following program, the execution path is: > > > from 6 to 8 (taken) -> from 11 to 15 (taken) -> from 18 to 22 > > > (taken) -> from 26 to 27 (fall-through) -> from 29 to 30 > > > (fall-through) > > > The verifier prunes the checking path at #26, skipping the actual > > > execution path. > > > > > > 0: (18) r2 =3D 0x1a000000be > > > 2: (bf) r5 =3D r1 > > > 3: (bf) r8 =3D r2 > > > 4: (bc) w4 =3D w5 > > > 5: (85) call bpf_get_current_cgroup_id#680112 > > > 6: (36) if w8 >=3D 0x69 goto pc+1 > > > 7: (95) exit > > > 8: (18) r4 =3D 0x52 > > > 10: (84) w4 =3D -w4 > > > 11: (45) if r0 & 0xfffffffe goto pc+3 > > > 12: (1f) r8 -=3D r4 > > > 13: (0f) r0 +=3D r0 > > > 14: (2f) r4 *=3D r4 > > > 15: (18) r3 =3D 0x1f00000034 > > > 17: (c4) w4 s>>=3D 29 > > > 18: (56) if w8 !=3D 0xf goto pc+3 > > > 19: r3 =3D bswap32 r3 > > > 20: (18) r2 =3D 0x1c > > > 22: (67) r4 <<=3D 2 > > > 23: (bf) r5 =3D r8 > > > 24: (18) r2 =3D 0x4 > > > 26: (7e) if w8 s>=3D w0 goto pc+5 > > > 27: (4f) r8 |=3D r8 > > > 28: (0f) r8 +=3D r8 > > > 29: (d6) if w5 s<=3D 0x1d goto pc+2 > > > 30: (18) r0 =3D 0x4 ; incorrectly pruned here > > > > > > > > > 32: (95) exit > > > [...] > > > > > > Here is a reduced C repro, maybe someone else can shed some light on = this. > > > C repro: https://pastebin.com/raw/chrshhGQ > > > > So you claim is that > > > > 30: (18) r0 =3D 0x4 ; incorrectly pruned here > > > > > > Can you please show a detailed code patch in which we do reach 30 > > actually? I might have missed it, but so far it look like verifier is > > doing everything right. > > > > I tried to convert the repro to a valid test case in inline asm, but seem= s > JSET (if r0 & 0xfffffffe goto pc+3) is currently not supported in clang-1= 7. > Will try after clang-18 is released. JSET has nothing to do with the issue, it's just a distraction, I'm not sure why you bring JSET into the discussion at all. Your repro can be actually much smaller, as it was really hard to follow which parts are important and which weren't. If you can try to minimize repros, it will definitely help with analysis for future issues. > > #30 is expected to be executed, see below where everything after ";" is > the runtime value: > ... > 6: (36) if w8 >=3D 0x69 goto pc+1 ; w8 =3D 0xbe, always taken > ... > 11: (45) if r0 & 0xfffffffe goto pc+3 ; r0 =3D 0x616, taken > ... > 18: (56) if w8 !=3D 0xf goto pc+3 ; w8 not touched, taken > ... > 23: (bf) r5 =3D r8 ; w5 =3D 0xbe > 24: (18) r2 =3D 0x4 > 26: (7e) if w8 s>=3D w0 goto pc+5 ; non-taken > 27: (4f) r8 |=3D r8 > 28: (0f) r8 +=3D r8 > 29: (d6) if w5 s<=3D 0x1d goto pc+2 ; non-taken > 30: (18) r0 =3D 0x4 ; executed > > Since the verifier prunes at #26, #30 is dead and eliminated. So, #30 > is executed after manually commenting out the dead code rewrite pass. > > From my understanding, I think r0 should be marked as precise when > first backtrack from #29, because r5 range at this point depends on w0 > as r8 and r5 share the same id at #26. Yes, thanks, the execution trace above was helpful. Let's try to minimize the example here, I'll keep original instruction indices, though: 23: (bf) r5 =3D r8 ; here we link r5 and r8 together 26: (7e) if w8 s>=3D w0 goto pc+5 ; here it's not always/never taken, so w8 and w0 remain imprecise 28: (0f) r8 +=3D r8 ; here link between r8 and r5 is br= oken 29: (d6) if w5 s<=3D 0x1d goto pc+2 ; here we know value of w5 and so it's always/never taken, r5 is marked precise Now, if we look at r5's precision log at this instruction: 29: (d6) if w5 s<=3D 0x1d goto pc+2 mark_precise: frame0: last_idx 29 first_idx 26 subseq_idx -1 mark_precise: frame0: regs=3Dr5 stack=3D before 28: (0f) r8 +=3D r8 mark_precise: frame0: regs=3Dr5 stack=3D before 27: (4f) r8 |=3D r8 mark_precise: frame0: regs=3Dr5 stack=3D before 26: (7e) if w8 s>=3D w0 got= o pc+5 Note how at this instruction r5 and r8 *WERE* linked together, but we already lost this information for backtracking. So we don't mark w8 as precise. That's one part of the problem. The second part is that even if we knew that w8/r8 is precise, should we mark w0/r0 as precise? I actually need to think about this some more. Right now for conditional jumps we eagerly mark precision for both registers only in always/never taken scenarios. For now just narrowing down the issue, as I'm sure not many people followed all the above stuff carefully. P.S. For solving tracking of linked registers we can probably utilize instruction history, though technically they can be spread across multiple frames, between registers and stack slots, so that's a bit tricky.