From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mx0b-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EA49910E0 for ; Tue, 5 Dec 2023 10:43:15 -0800 (PST) Received: from pps.filterd (m0109332.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 3B5IfKTh015622 for ; Tue, 5 Dec 2023 10:43:14 -0800 Received: from mail.thefacebook.com ([163.114.132.120]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3usxjtn4ds-10 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Tue, 05 Dec 2023 10:43:14 -0800 Received: from twshared15991.38.frc1.facebook.com (2620:10d:c085:108::8) by mail.thefacebook.com (2620:10d:c085:11d::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.34; Tue, 5 Dec 2023 10:43:08 -0800 Received: by devbig019.vll3.facebook.com (Postfix, from userid 137359) id 6A5193CA16FC7; Tue, 5 Dec 2023 10:42:54 -0800 (PST) From: Andrii Nakryiko To: , , , CC: , , Eduard Zingerman Subject: [PATCH v4 bpf-next 02/10] selftests/bpf: add stack access precision test Date: Tue, 5 Dec 2023 10:42:40 -0800 Message-ID: <20231205184248.1502704-3-andrii@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231205184248.1502704-1-andrii@kernel.org> References: <20231205184248.1502704-1-andrii@kernel.org> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-FB-Internal: Safe Content-Type: text/plain X-Proofpoint-GUID: TSYYfX3G4uL29vfZ92aH_sFj9882FfNk X-Proofpoint-ORIG-GUID: TSYYfX3G4uL29vfZ92aH_sFj9882FfNk X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.997,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-12-05_14,2023-12-05_01,2023-05-22_02 Add a new selftests that validates precision tracking for stack access instruction, using both r10-based and non-r10-based accesses. For non-r10 ones we also make sure to have non-zero var_off to validate that final stack offset is tracked properly in instruction history information inside verifier. Acked-by: Eduard Zingerman Signed-off-by: Andrii Nakryiko --- .../bpf/progs/verifier_subprog_precision.c | 64 +++++++++++++++++-- 1 file changed, 59 insertions(+), 5 deletions(-) diff --git a/tools/testing/selftests/bpf/progs/verifier_subprog_precision= .c b/tools/testing/selftests/bpf/progs/verifier_subprog_precision.c index eba98fab2f54..6f5d19665cf6 100644 --- a/tools/testing/selftests/bpf/progs/verifier_subprog_precision.c +++ b/tools/testing/selftests/bpf/progs/verifier_subprog_precision.c @@ -641,14 +641,68 @@ __naked int subprog_spill_into_parent_stack_slot_pr= ecise(void) ); } =20 -__naked __noinline __used -static __u64 subprog_with_checkpoint(void) +SEC("?raw_tp") +__success __log_level(2) +__msg("17: (0f) r1 +=3D r0") +__msg("mark_precise: frame0: last_idx 17 first_idx 0 subseq_idx -1") +__msg("mark_precise: frame0: regs=3Dr0 stack=3D before 16: (bf) r1 =3D r= 7") +__msg("mark_precise: frame0: regs=3Dr0 stack=3D before 15: (27) r0 *=3D = 4") +__msg("mark_precise: frame0: regs=3Dr0 stack=3D before 14: (79) r0 =3D *= (u64 *)(r10 -16)") +__msg("mark_precise: frame0: regs=3D stack=3D-16 before 13: (7b) *(u64 *= )(r7 -8) =3D r0") +__msg("mark_precise: frame0: regs=3Dr0 stack=3D before 12: (79) r0 =3D *= (u64 *)(r8 +16)") +__msg("mark_precise: frame0: regs=3D stack=3D-16 before 11: (7b) *(u64 *= )(r8 +16) =3D r0") +__msg("mark_precise: frame0: regs=3Dr0 stack=3D before 10: (79) r0 =3D *= (u64 *)(r7 -8)") +__msg("mark_precise: frame0: regs=3D stack=3D-16 before 9: (7b) *(u64 *)= (r10 -16) =3D r0") +__msg("mark_precise: frame0: regs=3Dr0 stack=3D before 8: (07) r8 +=3D -= 32") +__msg("mark_precise: frame0: regs=3Dr0 stack=3D before 7: (bf) r8 =3D r1= 0") +__msg("mark_precise: frame0: regs=3Dr0 stack=3D before 6: (07) r7 +=3D -= 8") +__msg("mark_precise: frame0: regs=3Dr0 stack=3D before 5: (bf) r7 =3D r1= 0") +__msg("mark_precise: frame0: regs=3Dr0 stack=3D before 21: (95) exit") +__msg("mark_precise: frame1: regs=3Dr0 stack=3D before 20: (bf) r0 =3D r= 1") +__msg("mark_precise: frame1: regs=3Dr1 stack=3D before 4: (85) call pc+1= 5") +__msg("mark_precise: frame0: regs=3Dr1 stack=3D before 3: (bf) r1 =3D r6= ") +__msg("mark_precise: frame0: regs=3Dr6 stack=3D before 2: (b7) r6 =3D 1"= ) +__naked int stack_slot_aliases_precision(void) { asm volatile ( - "r0 =3D 0;" - /* guaranteed checkpoint if BPF_F_TEST_STATE_FREQ is used */ - "goto +0;" + "r6 =3D 1;" + /* pass r6 through r1 into subprog to get it back as r0; + * this whole chain will have to be marked as precise later + */ + "r1 =3D r6;" + "call identity_subprog;" + /* let's setup two registers that are aliased to r10 */ + "r7 =3D r10;" + "r7 +=3D -8;" /* r7 =3D r10 - 8 */ + "r8 =3D r10;" + "r8 +=3D -32;" /* r8 =3D r10 - 32 */ + /* now spill subprog's return value (a r6 -> r1 -> r0 chain) + * a few times through different stack pointer regs, making + * sure to use r10, r7, and r8 both in LDX and STX insns, and + * *importantly* also using a combination of const var_off and + * insn->off to validate that we record final stack slot + * correctly, instead of relying on just insn->off derivation, + * which is only valid for r10-based stack offset + */ + "*(u64 *)(r10 - 16) =3D r0;" + "r0 =3D *(u64 *)(r7 - 8);" /* r7 - 8 =3D=3D r10 - 16 */ + "*(u64 *)(r8 + 16) =3D r0;" /* r8 + 16 =3D r10 - 16 */ + "r0 =3D *(u64 *)(r8 + 16);" + "*(u64 *)(r7 - 8) =3D r0;" + "r0 =3D *(u64 *)(r10 - 16);" + /* get ready to use r0 as an index into array to force precision */ + "r0 *=3D 4;" + "r1 =3D %[vals];" + /* here r0->r1->r6 chain is forced to be precise and has to be + * propagated back to the beginning, including through the + * subprog call and all the stack spills and loads + */ + "r1 +=3D r0;" + "r0 =3D *(u32 *)(r1 + 0);" "exit;" + : + : __imm_ptr(vals) + : __clobber_common, "r6" ); } =20 --=20 2.34.1