From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mta1.migadu.com (out-251.mta1.migadu.com [95.215.58.251]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 39F6C48592D for ; Thu, 10 Sep 2026 12:23:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.251 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789043039; cv=none; b=IJ6LnC+eG/onM8RxbxVH/gbhbYbK0zt/eh7Fx0e6IMkZmORfC7NRKxNIJ5+V6s7j0ITX/LQRbSbMdFsrBVe5Bf5OSb6Njg6bqhTYd9ebo66OXuUZ7K6z0k7d3KbsX35v9CVDT+6BsQorx7JGY9PlMZdx2G0BdL9wNQ98mHunEgM= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789043039; c=relaxed/simple; bh=DohzmBQXhTc3W9IsG0RnpMnqXNv9xW9Kj1PEpt+9ROI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Q8+8prVSgJvYq8koZUf/WTcO0nMII+HZWAEQZl77wauxWfdQrSvdz0nld8GX1UHX8AJsG3J2kQbRmKntMCLXhCieph6BwE3cAcI4Fdmdne9Yt8ffEWe4qMIuD2hdtNorTaspyDn3L39egGl9/0Grr1m4I7ZLxls/UXPO7lsqI4I= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=dz/s32Yx; arc=none smtp.client-ip=95.215.58.251 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="dz/s32Yx" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=DohzmBQXhTc3W9IsG0RnpMnqXNv9xW9Kj1PEpt+9ROI=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1789043035; v=1; x=1789647835; b=dz/s32YxXbXGjOc8dD/qjJS/mM8SgHCH5vDU6KHEeLRaVW80ZMoWsB9VVwtrAlVKC1QaGQEt NAKuQQHoBEQ0gSozMR+Dx9cxHQ8DJESK9F6kZaG9xPZDZskFkbVhCcYvy3kl/+JP38Y1HUPdTt3 37SDUKCqatmAz0yD+QFr24tU= X-Envelope-To: linux-kernel@vger.kernel.org Received: by smtp.migadu.com with ESMTPS id f8d3cdd5053f8d02; Thu, 10 Sep 2026 12:23:54 +0000 X-Mizu-Trace-ID: f8d3cdd5053f8d02 X-Migadu-Flow: FLOW_OUT From: Jiayuan Chen To: bpf@vger.kernel.org Cc: Jiayuan Chen , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Eduard Zingerman , Kumar Kartikeya Dwivedi , Martin KaFai Lau , Song Liu , Yonghong Song , Jiri Olsa , Emil Tsalapatis , Ihor Solodrai , Shuah Khan , Yazhou Tang , Amery Hung , Matt Bobrowski , Tejun Heo , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH bpf 2/2] selftests/bpf: Test BTF walk into a flexible array of zero-sized elements Date: Thu, 10 Sep 2026 20:22:56 +0800 Message-ID: <20260910122316.186384-2-jiayuan.chen@linux.dev> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260910122316.186384-1-jiayuan.chen@linux.dev> References: <20260910122316.186384-1-jiayuan.chen@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit The program stashes a bpf_obj_new() object whose type ends with a flexible array of empty structs, then reads it back as an untrusted kptr. Without the previous patch this divides by zero in btf_struct_walk() instead of being rejected. # ./test_progs -t verifier_btf_flex_array ... #602 verifier_btf_flex_array:OK Summary: 1/1 PASSED, 0 SKIPPED, 0/0 FAILED Signed-off-by: Jiayuan Chen --- .../selftests/bpf/prog_tests/verifier.c | 2 + .../bpf/progs/verifier_btf_flex_array.c | 56 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 tools/testing/selftests/bpf/progs/verifier_btf_flex_array.c diff --git a/tools/testing/selftests/bpf/prog_tests/verifier.c b/tools/testing/selftests/bpf/prog_tests/verifier.c index f7f94ccebce2..33a5da37e3ad 100644 --- a/tools/testing/selftests/bpf/prog_tests/verifier.c +++ b/tools/testing/selftests/bpf/prog_tests/verifier.c @@ -24,6 +24,7 @@ #include "verifier_bpf_trap.skel.h" #include "verifier_bswap.skel.h" #include "verifier_btf_ctx_access.skel.h" +#include "verifier_btf_flex_array.skel.h" #include "verifier_btf_unreliable_prog.skel.h" #include "verifier_call_large_imm.skel.h" #include "verifier_cfg.skel.h" @@ -188,6 +189,7 @@ void test_verifier_bpf_get_stack(void) { RUN(verifier_bpf_get_stack); } void test_verifier_bpf_trap(void) { RUN(verifier_bpf_trap); } void test_verifier_bswap(void) { RUN(verifier_bswap); } void test_verifier_btf_ctx_access(void) { RUN(verifier_btf_ctx_access); } +void test_verifier_btf_flex_array(void) { RUN(verifier_btf_flex_array); } void test_verifier_btf_unreliable_prog(void) { RUN(verifier_btf_unreliable_prog); } void test_verifier_call_large_imm(void) { RUN(verifier_call_large_imm); } void test_verifier_cfg(void) { RUN(verifier_cfg); } diff --git a/tools/testing/selftests/bpf/progs/verifier_btf_flex_array.c b/tools/testing/selftests/bpf/progs/verifier_btf_flex_array.c new file mode 100644 index 000000000000..59b84261f622 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/verifier_btf_flex_array.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include + +#include "bpf_experimental.h" +#include "bpf_misc.h" + +struct test_empty_event {}; + +struct test_flex_batch { + int nr; + struct test_empty_event events[]; +}; + +struct map_value { + struct test_flex_batch __kptr *batch; +}; + +struct { + __uint(type, BPF_MAP_TYPE_ARRAY); + __type(key, int); + __type(value, struct map_value); + __uint(max_entries, 1); +} batches SEC(".maps"); + +SEC("syscall") +__description("btf walk into flexible array of zero-sized elements") +__failure __msg("access beyond struct test_flex_batch at off 4 size 1") +int stash_and_peek(void *ctx) +{ + struct test_flex_batch *b, *old; + struct map_value *v; + int key = 0; + + v = bpf_map_lookup_elem(&batches, &key); + if (!v) + return 0; + + b = bpf_obj_new(struct test_flex_batch); + if (!b) + return 0; + b->nr = 1; + + old = bpf_kptr_xchg(&v->batch, b); + if (old) + bpf_obj_drop(old); + + b = v->batch; + if (!b) + return 0; + + return b->nr + *(char *)&b->events[0]; +} + +char _license[] SEC("license") = "GPL"; -- 2.43.0