From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-oi1-f174.google.com (mail-oi1-f174.google.com [209.85.167.174]) (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 7FFB22E736F for ; Sun, 7 Jun 2026 16:55:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.174 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780851353; cv=none; b=cytiLgI4vD1pDWbHhQsRWqzMyDdKIUzgLQBmluCwmN71dHI9XVPqn0fvVcfDbijrSa6i4MS/AZLIaYRP//0mH2m+e1R2Kv24Smrzuxwq/ESsZkpSN7vAgUIWRpRAl1lGcyhXbzRHcO0Clj3J68HGOgDeEEC0XIfgtV3dAEE985o= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780851353; c=relaxed/simple; bh=vq0VLS/ylpM3CmAEtZEwDI7OGBBgEUHxL8PTx+OEr9E=; h=Mime-Version:Content-Type:Date:Message-Id:Cc:Subject:From:To: References:In-Reply-To; b=jy23I6o7hKKA1+5LZvPMQeBTvLo3MRQZGMu6LJij0Gkybem6zsNu0lDIrYStKAS/kfJQU657xGJ+FB0PLwJdRBoAspOaoNg5biWlPKIBub1cJJZ6gfm+snDBjeKbnhXqyMGyV9hxmes20qF7mFJ7Me1acd5zTBEMR6pHftntEls= 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=myKldV5g; arc=none smtp.client-ip=209.85.167.174 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="myKldV5g" Received: by mail-oi1-f174.google.com with SMTP id 5614622812f47-486b93fc7c8so216170b6e.3 for ; Sun, 07 Jun 2026 09:55:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780851351; x=1781456151; darn=vger.kernel.org; h=in-reply-to:references:to:from:subject:cc:message-id:date :content-transfer-encoding:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=X3oVPDjM9UNiAad2kRETnB/VhLXES/+/2f8UxjTzkJ8=; b=myKldV5gKWkOayJ8U/ypJOEEHBRkDxE7v6Hy0Nq01Lqk/TwIAcjO028egEo65OTyAd DdXY3lBxFAmqNvqAMpFJZpI1kLLn6CTliJpCvgkWcTILaYNLTNffoGzCJL4Mgqzh0/cj 5vmXrKXmpT9VvguBA2uQ9qL70jxmJQczNqFOvBMuhHu1FZH/77JeKuw7/V8xQWaLzDx2 LK37ACEanT6iXhPrJseRltQm3oc32HBVCBjJkkCAjATaRy08+4xOpMqtBJR1ekg1o7wd 2V9ZNQj5FzVerFkOm7jSYpo7Dy5GpqWw688rx/WCOcbySVkzF+u5PVtMJ0zB1SvKRrp2 R1QQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780851351; x=1781456151; h=in-reply-to:references:to:from:subject:cc:message-id:date :content-transfer-encoding:mime-version:x-gm-gg:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=X3oVPDjM9UNiAad2kRETnB/VhLXES/+/2f8UxjTzkJ8=; b=go6XgTlklKwce7rHXWDBFnxHHejDQl98bnCknC926rULTfQ3hbvMxrmqC4osa+b8to Sj5FJbqqFKEwdevyrBgyXns9AKEwgoUIf+Xj7kgp4iYb2eV3K27gPB+1ouZVYmG4pKMb fUI/+x9aQzn1sQ5NNYYBfyVLkZ1itNZFkEEHEA29YVaEeSDrrnSaTU+qWYH2ulvDUGU3 ICVNKjpM3dJoRwz4pZI7vlhXeiN6ca0B7ZBkd3JYwWxjX9GDGZiHC6quXLWVwgFUuvy8 MrsiLnSUgix6NFRVTjhjV3GEPCb6Ahaif8ptVA93osdpScjeEuMQG+DLvDcL/H6Ipist w+Og== X-Forwarded-Encrypted: i=1; AFNElJ+0iMjvpTEx005ElGalUxA7xhYKbZMLM1kaQFsnd95gD5XIPq9zwdsGAMpMCs5SsqRdMfM=@vger.kernel.org X-Gm-Message-State: AOJu0YzA15TN2qd5jZEb/Kmi+Ne91G5oQL7xTRDMmQgxmxMwny+Xk+zv 4ctpcamTS+YE0AVOy32h2cVP4ZBtfzadmNegBe3RcmwBrBQaP7ArlN+9 X-Gm-Gg: Acq92OGb40aBQZ+WzlZskm+jBv8YzhOu/oupYuEBxf86mQmkSTH+kUOVKVaPmcEBhfq zj6bjp85l3eK+YbJ4es9rtfptBvLSgBDH7VWC8Nbm6RsEx52zFzhAgauAiHlQkhG6PSS2sqkc+i pGyItSv40S1KyFauGq8/j79HFhakigvQt+H7D2dLTGgfrkM3SewhdLaMgdvOnhTTjrWNYoikmg+ 2tuW2OcjE5KXweuuVfM8S57jMBrqip8i6TkynAEKQOYm+tnvo/wcMQSCZGkB7tqEyiCvn2I9D8S w/wO/Ir98lHThYvPR0FGkaFiJ/kkgyrGHgE4E8Jw1i0Zkv33hJhcrjTyWr46J0uy3gXB5vDvxYG enPYRAdjLBx5kLJidyXxMw+ngP0NXA2OOttNtlhDq2KjS1EhX/xlVb04RX1bHDtjDV/jv8skjJ1 h8qCQLlvf3wkVRU469fTM82EwCQ+uQQGvGcwA6qhsck1GvEwg+buVWHMey1sXtAyuO3ouulA11m eAl55Kut34rlRJ803UIHUdjsx7Y X-Received: by 2002:a05:6808:181c:b0:486:4bd0:9a29 with SMTP id 5614622812f47-4868df0166fmr6506417b6e.43.1780851351218; Sun, 07 Jun 2026 09:55:51 -0700 (PDT) Received: from localhost ([2a03:2880:10ff:52::]) by smtp.gmail.com with ESMTPSA id 586e51a60fabf-440d7263efcsm14254294fac.0.2026.06.07.09.55.48 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sun, 07 Jun 2026 09:55:49 -0700 (PDT) Precedence: bulk X-Mailing-List: bpf@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 Date: Sun, 07 Jun 2026 09:55:47 -0700 Message-Id: Cc: , , , , , Subject: Re: [PATCH bpf] bpf: Validate BTF repeated field counts before expansion From: "Alexei Starovoitov" To: "Kumar Kartikeya Dwivedi" , "Paul Moses" , , , , , , X-Mailer: aerc References: <20260605234301.1109063-1-p@1g4.org> In-Reply-To: On Sun Jun 7, 2026 at 1:59 AM PDT, Kumar Kartikeya Dwivedi wrote: > On Sat Jun 6, 2026 at 1:43 AM CEST, Paul Moses wrote: >> btf_parse_struct_metas() walks user-supplied BTF during BPF_BTF_LOAD, >> and btf_repeat_fields() expands repeatable fields from array elements >> into the fixed BTF_FIELDS_MAX scratch array used by btf_parse_fields(). >> >> The remaining-capacity check performs the expanded field count calculati= on >> in u32. A malformed BTF can wrap that calculation, causing the check to >> pass even when the expanded field count exceeds the scratch array >> capacity. The following memcpy() can then write past the end of the >> array. >> >> Use checked addition and multiplication before copying repeated fields >> and reject impossible counts. >> >> Fixes: 797d73ee232d ("bpf: Check the remaining info_cnt before repeating= btf fields") >> Cc: stable@vger.kernel.org >> Signed-off-by: Paul Moses >> --- > > Do you have an example where this actually occurred in practice? > >> kernel/bpf/btf.c | 9 ++++----- >> 1 file changed, 4 insertions(+), 5 deletions(-) >> >> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c >> index a62d78581207..510aa32847da 100644 >> --- a/kernel/bpf/btf.c >> +++ b/kernel/bpf/btf.c >> @@ -3668,7 +3668,7 @@ static int btf_get_field_type(const struct btf *bt= f, const struct btf_type *var_ >> static int btf_repeat_fields(struct btf_field_info *info, int info_cnt, >> u32 field_cnt, u32 repeat_cnt, u32 elem_size) >> { >> - u32 i, j; >> + u32 i, j, total_cnt, total_repeats; >> u32 cur; >> >> /* Ensure not repeating fields that should not be repeated. */ >> @@ -3686,10 +3686,9 @@ static int btf_repeat_fields(struct btf_field_inf= o *info, int info_cnt, >> } >> } >> >> - /* The type of struct size or variable size is u32, >> - * so the multiplication will not overflow. >> - */ >> - if (field_cnt * (repeat_cnt + 1) > info_cnt) >> + if (check_add_overflow(repeat_cnt, 1, &total_repeats) || >> + check_mul_overflow(field_cnt, total_repeats, &total_cnt) || >> + total_cnt > (u32)info_cnt) >> return -E2BIG; The callers of this function do: if (nelems > 1) { err =3D btf_repeat_fields(info, info_cnt, ret, nelems - 1, = t->size); so repeat_cnt cannot overflow. 'ret' (which is field_cnt) comes from btf_find_struct_field(). To overflow the struct needs to have 32k valid fields. Is this really what is happening? The issues is deeper. Please have a reliable reproducer first.