From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from out30-133.freemail.mail.aliyun.com (out30-133.freemail.mail.aliyun.com [115.124.30.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0D84F444718; Wed, 22 Jul 2026 07:39:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.133 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784705959; cv=none; b=CAkp7cLpWTRu9kUMse4ZPWfdISJ7LPSbPu8ctXxeJaxqL6VE0XUC45w5gO/n0OxgxwfL/V0JjqeRTC+8wU0di9gJSintVgt7MpcwpXNb7GR8LRFSYcPd2PkkMrEssvzgRbHlrxAmjhIhSvLcbcIYhOOUZg/kRarBxi4XMFm4SRQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784705959; c=relaxed/simple; bh=col8ZKRn90FdlPjWvt7PuSiQlnyoyzfPi+Jl+6BFmEQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=BC0zDTEyu7GxA4TY/QPrz7ctyJRh6I93TCRBAoiYkqa/SpuuHUb6aBs9k+rCP8AKgehc5OUUc0mydL1cqza4mzBKCsnYzErDpb1nSreW3FuBUQAN8yAH8BekiW4EeK+C6i3q+352Fv4sYONwtyxe/EqszBDY4YFZ42PhYb1bhak= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=l/5vE13O; arc=none smtp.client-ip=115.124.30.133 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="l/5vE13O" DKIM-Signature:v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1784705952; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=Era3ywJJCFB32TOQ7c2d2lF7a8jcJY7JsV++AGcg6Xs=; b=l/5vE13Oe7/qYPzrknaU02/oMjucwQZDY+deNPOr3yCxSVxaymZ99iOa+VBa6B/8Dh5+YZC8SA6V6NMCrWx2FgJ+IDKJ7TLF3YOECeM2/zARw7IaaIiWqL6Prjnjuh53/L++Ej7xG8I9mVPFa9NYbYzJkvZOtwMAnY5mi0j9kuE= X-Alimail-AntiSpam:AC=PASS;BC=-1|-1;BR=01201311R121e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=maildocker-contentspam011083073210;MF=lulie@linux.alibaba.com;NM=1;PH=DS;RN=20;SR=0;TI=SMTPD_---0X7caQLj_1784705950; Received: from localhost(mailfrom:lulie@linux.alibaba.com fp:SMTPD_---0X7caQLj_1784705950 cluster:ay36) by smtp.aliyun-inc.com; Wed, 22 Jul 2026 15:39:11 +0800 From: Philo Lu To: stable@vger.kernel.org Cc: daniel@iogearbox.net, info@starlabs.sg, ast@kernel.org, lulie@linux.alibaba.com, john.fastabend@gmail.com, andrii@kernel.org, martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, jolsa@kernel.org, bpf@vger.kernel.org, linux-kernel@vger.kernel.org, mykolal@fb.com, shuah@kernel.org, linux-kselftest@vger.kernel.org, dust.li@linux.alibaba.com Subject: [PATCH 6.6.y/6.12.y/6.18.y 2/2] selftests/bpf: Add tests for ld_{abs,ind} failure path in subprogs Date: Wed, 22 Jul 2026 15:39:08 +0800 Message-Id: <20260722073908.72382-3-lulie@linux.alibaba.com> X-Mailer: git-send-email 2.32.0.3.g01195cf9f In-Reply-To: <20260722073908.72382-1-lulie@linux.alibaba.com> References: <20260722073908.72382-1-lulie@linux.alibaba.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Daniel Borkmann commit e0fcb42bc6f41bab2895757d6610616b3820eff7 upstream. Extend the verifier_ld_ind BPF selftests with subprogs containing ld_{abs,ind} and craft the test in a way where the invalid register read is rejected in the fixed case. Also add a success case each, and add additional coverage related to the BTF return type enforcement. # LDLIBS=-static PKG_CONFIG='pkg-config --static' ./vmtest.sh -- ./test_progs -t verifier_ld_ind [...] #611/1 verifier_ld_ind/ld_ind: check calling conv, r1:OK #611/2 verifier_ld_ind/ld_ind: check calling conv, r1 @unpriv:OK #611/3 verifier_ld_ind/ld_ind: check calling conv, r2:OK #611/4 verifier_ld_ind/ld_ind: check calling conv, r2 @unpriv:OK #611/5 verifier_ld_ind/ld_ind: check calling conv, r3:OK #611/6 verifier_ld_ind/ld_ind: check calling conv, r3 @unpriv:OK #611/7 verifier_ld_ind/ld_ind: check calling conv, r4:OK #611/8 verifier_ld_ind/ld_ind: check calling conv, r4 @unpriv:OK #611/9 verifier_ld_ind/ld_ind: check calling conv, r5:OK #611/10 verifier_ld_ind/ld_ind: check calling conv, r5 @unpriv:OK #611/11 verifier_ld_ind/ld_ind: check calling conv, r7:OK #611/12 verifier_ld_ind/ld_ind: check calling conv, r7 @unpriv:OK #611/13 verifier_ld_ind/ld_abs: subprog early exit on ld_abs failure:OK #611/14 verifier_ld_ind/ld_ind: subprog early exit on ld_ind failure:OK #611/15 verifier_ld_ind/ld_abs: subprog with both paths safe:OK #611/16 verifier_ld_ind/ld_ind: subprog with both paths safe:OK #611/17 verifier_ld_ind/ld_abs: reject void return subprog:OK #611/18 verifier_ld_ind/ld_ind: reject void return subprog:OK #611 verifier_ld_ind:OK Summary: 1/18 PASSED, 0 SKIPPED, 0 FAILED Signed-off-by: Daniel Borkmann Link: https://lore.kernel.org/r/20260408191242.526279-4-daniel@iogearbox.net Signed-off-by: Alexei Starovoitov Signed-off-by: Philo Lu --- .../selftests/bpf/progs/verifier_ld_ind.c | 142 ++++++++++++++++++ 1 file changed, 142 insertions(+) diff --git a/tools/testing/selftests/bpf/progs/verifier_ld_ind.c b/tools/testing/selftests/bpf/progs/verifier_ld_ind.c index c925ba9a2e74c..09e81b99eecb4 100644 --- a/tools/testing/selftests/bpf/progs/verifier_ld_ind.c +++ b/tools/testing/selftests/bpf/progs/verifier_ld_ind.c @@ -107,4 +107,146 @@ __naked void ind_check_calling_conv_r7(void) : __clobber_all); } +/* + * ld_{abs,ind} subprog that always sets r0=1 on the success path. + * bpf_gen_ld_abs() emits a hidden exit with r0=0 when the load helper + * fails. The verifier must model this failure return so that callers + * account for r0=0 as a possible return value. + */ +__naked __noinline __used +static int ldabs_subprog(void) +{ + asm volatile ( + "r6 = r1;" + ".8byte %[ld_abs];" + "r0 = 1;" + "exit;" + : + : __imm_insn(ld_abs, BPF_LD_ABS(BPF_W, 0)) + : __clobber_all); +} + +__naked __noinline __used +static int ldind_subprog(void) +{ + asm volatile ( + "r6 = r1;" + "r7 = 0;" + ".8byte %[ld_ind];" + "r0 = 1;" + "exit;" + : + : __imm_insn(ld_ind, BPF_LD_IND(BPF_W, BPF_REG_7, 0)) + : __clobber_all); +} + +SEC("socket") +__description("ld_abs: subprog early exit on ld_abs failure") +__failure __msg("R9 !read_ok") +__naked void ld_abs_subprog_early_exit(void) +{ + asm volatile ( + "call ldabs_subprog;" + "if r0 != 0 goto l_exit_%=;" + "r0 = r9;" + "l_exit_%=:" + "r0 = 0;" + "exit;" + ::: __clobber_all); +} + +SEC("socket") +__description("ld_ind: subprog early exit on ld_ind failure") +__failure __msg("R9 !read_ok") +__naked void ld_ind_subprog_early_exit(void) +{ + asm volatile ( + "call ldind_subprog;" + "if r0 != 0 goto l_exit_%=;" + "r0 = r9;" + "l_exit_%=:" + "r0 = 0;" + "exit;" + ::: __clobber_all); +} + +SEC("socket") +__description("ld_abs: subprog with both paths safe") +__success +__naked void ld_abs_subprog_both_paths_safe(void) +{ + asm volatile ( + "call ldabs_subprog;" + "r0 = 0;" + "exit;" + ::: __clobber_all); +} + +SEC("socket") +__description("ld_ind: subprog with both paths safe") +__success +__naked void ld_ind_subprog_both_paths_safe(void) +{ + asm volatile ( + "call ldind_subprog;" + "r0 = 0;" + "exit;" + ::: __clobber_all); +} + +/* + * ld_{abs,ind} in subprogs require scalar (int) return type in BTF. + * A test with void return must be rejected. + */ +__naked __noinline __used +static void ldabs_void_subprog(void) +{ + asm volatile ( + "r6 = r1;" + ".8byte %[ld_abs];" + "r0 = 1;" + "exit;" + : + : __imm_insn(ld_abs, BPF_LD_ABS(BPF_W, 0)) + : __clobber_all); +} + +SEC("socket") +__description("ld_abs: reject void return subprog") +__failure __msg("LD_ABS is only allowed in functions that return 'int'") +__naked void ld_abs_void_subprog_reject(void) +{ + asm volatile ( + "call ldabs_void_subprog;" + "r0 = 0;" + "exit;" + ::: __clobber_all); +} + +__naked __noinline __used +static void ldind_void_subprog(void) +{ + asm volatile ( + "r6 = r1;" + "r7 = 0;" + ".8byte %[ld_ind];" + "r0 = 1;" + "exit;" + : + : __imm_insn(ld_ind, BPF_LD_IND(BPF_W, BPF_REG_7, 0)) + : __clobber_all); +} + +SEC("socket") +__description("ld_ind: reject void return subprog") +__failure __msg("LD_ABS is only allowed in functions that return 'int'") +__naked void ld_ind_void_subprog_reject(void) +{ + asm volatile ( + "call ldind_void_subprog;" + "r0 = 0;" + "exit;" + ::: __clobber_all); +} + char _license[] SEC("license") = "GPL"; -- 2.47.3