From nobody Mon Jun 8 16:28:54 2026 Received: from mail-pf1-f173.google.com (mail-pf1-f173.google.com [209.85.210.173]) (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 8CD03260580 for ; Thu, 28 May 2026 06:22:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779949340; cv=none; b=KZAd5WwL3N8NJ8wwUjKtArkvPIItcy0hqee7zKJUo1cXfuh7O13CyiVHItKkDQKedyOTbY+LiDRjQ271FA9gOlP6TljzYOipHvbk1LdcKe6EGTuPQRlZDNaZV8w9/xQ8bqBJ7qdiPW+uRHssGNWih4sCva1gWk0kcaRY22tgVoI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779949340; c=relaxed/simple; bh=ncZ8PO1GcrR9iQGi0K+uqcRTqlKCxKBfU6IngjaQfJY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Vyi/2hEDcSrdmHUnuA/D7XV7QARtPjJc1okCD8d0ngFwXU+FCeqrw+/4XStIqD3jvCrAqR5JZwEo1/jZm6MLSf62lD1NW9SyR7+3te3npn7mY4IXDAnNG2wMo/R44JN6edliGyp+KnMaBAFfuudsLdWkKb2eFVz98R5LfUjT5nY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Fsk7+NkX; arc=none smtp.client-ip=209.85.210.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Fsk7+NkX" Received: by mail-pf1-f173.google.com with SMTP id d2e1a72fcca58-83975e992e1so5107596b3a.2 for ; Wed, 27 May 2026 23:22:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779949338; x=1780554138; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=s2xM/E7JCqF+aKvSO4PKrWVccq753Fk89T0nKpMlTyM=; b=Fsk7+NkX58PRBotqsC9yirToVjiCcv0Ms4ekU8P2ztfjv2XrRsnMKwekKzXfediCwO /NeHk/ORV7dMBaRt46MaxFWrjd25j2GoEBg4bZIe8tX68NpBXw6Kb9nsxGT89TqJqq3f q4PVy29HTCoKnjIwmZEK0p0nE8Js9HY0F122eh8SnydQ8W351gORwU5a0nEsK7OwWQXJ HMt0z6bVXr75Wev9b3q1LdDI/zPPH6Lq3TSBhNmr43oDM8jZb9bXunWYKRQypHfTkXkP J5pVA+3UDDnRoVcPmP3hn0P62XlC730mzpGfDYaLxRs4Fq/bjBjLeUP1/aKG/c0omKZ6 9VxA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779949338; x=1780554138; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=s2xM/E7JCqF+aKvSO4PKrWVccq753Fk89T0nKpMlTyM=; b=kOOw9FDt7ERDk2IVz+kxDMwtTsc6pPsR+Lytk0HiB7TYb/kwsluBgF0H073BC/8lip DlXDbAiiW4oIJrR1OukaHdk83c+4lUxLk6BiB+jxyQCtnK079x4PbfF91aIkeJHrS+uN BcNxjpXZaL4e1WBtK4AhqWq8e0+t0KAnHuflXiMltDHtyGpdAT90z+xP7X9TxX6wayp6 jYwvJpf8qmJLQSEIYDK7u/J0t2pK4UZj8HFf+q/vY0oAv2wwk1DASvVAsAOXNduFo6vK 4dvMt2TNDHDqPzwUK6+gOAG1GG1T7G74kQ3sHEWb7L3ILuhmznd5sBuHsol4HtW5b4xB bGrw== X-Forwarded-Encrypted: i=1; AFNElJ8L15n5tpLQdBFo6CWGiIZ3wpd+/S83zK2cK8XbLzlPpTdm1KbCz7gsUDFQl/c6mUMWX2JxDKIIWAUc7Gg=@vger.kernel.org X-Gm-Message-State: AOJu0Yycy4LabEwNhIGGcYCs+c60qD5Zz5ygCI2S85G5bFbt3oQ8Lasi dUGlHSVP/Y3G+FA6/4r0QpgQczof3LJGjXTc7oIYhZSKB1XS4WSumkTE X-Gm-Gg: Acq92OGlqWSmboiHyn5UhuWyTkcmm7C+FBNtcglmFTHNCBfnzawgh5kJgy/tkQjJDCT CYPPD1ht6TLmX0EkEORkjAfZqo1U2RTurRMxc3JZ3f9dWJVKxZiZ9CgUxRh0LkI+LOSs74MqGvh /bduINynTrDoEEM7ZKamU92kzyH9liWTMuiibXdeHOBwfmNWRURBv6w+LYkp7CMw2wkBNkBkaXz A9mAB7zne6dMHU8nx5z9uP4NU8XvHfxMq2z+m3fGqAv1sZwcM97MKHsYf1+ykey57jS7nq7dylD uQIClkm/dRrP2nCVWnn319PhQUNQoe0YDICQPfXUxZ6WmxwVau02trzH6ulr1KhVjeop8ARDRdh ZbpsZgb7qnpm8JbXRuhqcxETMA+///JwRkrw3wHcW7gZzkasmf/Nx4MCcgqNIO9pmWEVqchR3We XeDM5Hp+b54T2+FlgHiLfXlZYYkLNOaojnBYHScWd84CrN2glyvS2q2A== X-Received: by 2002:a05:6a00:7702:b0:841:dc7d:306a with SMTP id d2e1a72fcca58-841dc7d511cmr4529239b3a.25.1779949337883; Wed, 27 May 2026 23:22:17 -0700 (PDT) Received: from foxirain.tailf10b76.ts.net ([220.83.29.221]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-841ef4e9ec7sm964082b3a.24.2026.05.27.23.22.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 27 May 2026 23:22:17 -0700 (PDT) From: Taegu Ha To: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko Cc: Yonghong Song , Eduard Zingerman , Kumar Kartikeya Dwivedi , Shuah Khan , John Fastabend , Jiri Olsa , Stanislav Fomichev , Song Liu , Puranjay Mohan , Emil Tantilov , Martin KaFai Lau , bpf@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Taegu Ha Subject: [PATCH bpf-next v3] bpf: reject overlarge global subprog argument sizes Date: Thu, 28 May 2026 15:21:55 +0900 Message-ID: <20260528062155.3988156-1-hataegu0826@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260528052533.3940181-1-hataegu0826@gmail.com> References: <20260528052533.3940181-1-hataegu0826@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Global subprogram argument checking derives generic pointer sizes from BTF and passes the resolved size to check_mem_reg() as a u32. The access-size validation path then uses a signed int, and stack pointers negate the value before calling check_helper_mem_access(). This creates a wrap when BTF describes a pointee size larger than S32_MAX. For example, a global subprogram argument of type: int (*p)[0x3fffffff] has a BTF-resolved pointee size of 0xfffffffc bytes. At a call site the caller can pass a pointer to a 4-byte stack slot at fp-4. The current PTR_TO_STACK path computes: size =3D -(int)mem_size so 0xfffffffc becomes -4 as a signed int and the negation validates only a 4-byte stack range. That range is covered by the caller's stack slot, so the call is accepted. The callee is then verified independently with R1 as PTR_TO_MEM and mem_size 0xfffffffc. A small instruction such as: r0 =3D *(u32 *)(r1 + 4) is accepted as being inside that BTF-described memory region. At run time, however, the actual argument value is still fp-4, so r1 + 4 addresses fp+0, outside the 4-byte object that the caller provided. Reject sizes that cannot be represented by the verifier's signed access-size API before the stack-specific negation. Add a verifier regression test for the oversized BTF argument. Fixes: 2cb27158adb3 ("bpf: poison dead stack slots") Signed-off-by: Taegu Ha Acked-by: Yonghong Song --- v3: - Fix bpf-next build by using reg_arg_name(env, argno) in check_mem_reg(); v2 referenced a stale regno parameter name. - Keep the existing known-NULL fast path before the overlarge-size guard. - Send as a single bpf-next patch without a cover letter. v2: - Expanded the commit message with the BTF-derived size wrap details. - Kept the verifier fix to a mem_size > S32_MAX guard. kernel/bpf/verifier.c | 6 ++++++ .../bpf/progs/verifier_global_subprogs.c | 17 +++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index c8d980fdd709..3a270bc485c2 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -6927,6 +6927,12 @@ static int check_mem_reg(struct bpf_verifier_env *en= v, struct bpf_reg_state *reg if (bpf_register_is_null(reg)) return 0; =20 + if (mem_size > S32_MAX) { + verbose(env, "%s memory size %u is too large\n", + reg_arg_name(env, argno), mem_size); + return -EACCES; + } + /* Assuming that the register contains a value check if the memory * access is safe. Temporarily save and restore the register's state as * the conversion shouldn't be visible to a caller. diff --git a/tools/testing/selftests/bpf/progs/verifier_global_subprogs.c b= /tools/testing/selftests/bpf/progs/verifier_global_subprogs.c index dc09d0e2d8ad..75a2e3f48d0f 100644 --- a/tools/testing/selftests/bpf/progs/verifier_global_subprogs.c +++ b/tools/testing/selftests/bpf/progs/verifier_global_subprogs.c @@ -152,6 +152,23 @@ int anon_user_mem_valid(void *ctx) return subprog_user_anon_mem(&t); } =20 +__noinline __weak int subprog_user_anon_mem_huge(int (*p)[0x3fffffff]) +{ + return p ? (*p)[1] : 0; +} + +SEC("?tracepoint") +__failure __log_level(2) +__msg("R1 memory size 4294967292 is too large") +int anon_user_mem_huge_size_invalid(void *ctx) +{ + int (*p)[0x3fffffff]; + int tiny =3D 42; + + p =3D (void *)&tiny; + return subprog_user_anon_mem_huge(p) + tiny; +} + __noinline __weak int subprog_nonnull_ptr_good(int *p1 __arg_nonnull, int = *p2 __arg_nonnull) { return (*p1) * (*p2); /* good, no need for NULL checks */ --=20 2.43.0