From: Jan Hendrik Farr <kernel@jfarr.cc>
To: Thorsten Blum <thorsten.blum@toblux.com>
Cc: Kees Cook <kees@kernel.org>,
kent.overstreet@linux.dev, regressions@lists.linux.dev,
linux-bcachefs@vger.kernel.org, linux-hardening@vger.kernel.org,
linux-kernel@vger.kernel.org, ardb@kernel.org, morbo@google.com
Subject: Re: [REGRESSION][BISECTED] erroneous buffer overflow detected in bch2_xattr_validate
Date: Thu, 3 Oct 2024 17:17:08 +0200 [thread overview]
Message-ID: <Zv61dCaxScXuOjZg@archlinux> (raw)
In-Reply-To: <E8E64A72-3C1C-40D2-9F07-415F6B8F476E@toblux.com>
On 03 15:07:52, Thorsten Blum wrote:
> On 3. Oct 2024, at 13:33, Jan Hendrik Farr <kernel@jfarr.cc> wrote:
> >> [...]
> >
> > This issue is now fixed on the llvm main branch:
> > https://github.com/llvm/llvm-project/commit/882457a2eedbe6d53161b2f78fcf769fc9a93e8a
>
> Thanks!
>
> Do you know if it also fixes the different sizes here:
> https://godbolt.org/z/vvK9PE1Yq
I have a patch for clang that changes the behavior to what gcc does and
what the kernel seems to be expecting right now, you can find it below.
I'm not 100% sure what if the gcc or the clang behavior is currently
correct. However, I'm gonna argue that gcc has it correct.
gcc currently says that the __bdos of struct containing a flexible array
member is:
sizeof(<whole struct>) + sizeof(<flexible array element>) * <count>
clang however does the following:
max(sizeof(<whole struct>), offsetof(<flexible array member>) + sizeof(<flexible array element>) * <count>)
The kernel assumes the gcc behvaior in places like linux/fs/posix_acl.c:
struct posix_acl *
posix_acl_clone(const struct posix_acl *acl, gfp_t flags)
{
struct posix_acl *clone = NULL;
if (acl) {
int size = sizeof(struct posix_acl) + acl->a_count *
sizeof(struct posix_acl_entry);
clone = kmemdup(acl, size, flags);
if (clone)
refcount_set(&clone->a_refcount, 1);
}
return clone;
}
EXPORT_SYMBOL_GPL(posix_acl_clone);
This is the code that triggers the problem in [1]. The way I see it, this
code should work, as you also allocate struct posix_acl with the same
sizeof(struct posix_acl) + acl->a_count * sizeof(struct posix_acl_entry)
as an argument to malloc (or in-kernel equivalent).
Based on the C standard the size of that object is the size passed to
malloc. See bottom of page 348 [2].
I'll put together another PR to llvm with this fix, just need to
add/change tests.
[1] https://lore.kernel.org/linux-kernel/3D0816D1-0807-4D37-8D5F-3C55CA910FAA@linux.dev/
[2] https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf
--
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index d739597de4c8..1d112aededbd 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -919,8 +919,7 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr *E, unsigned Type,
// 2) bdos of the whole struct, including the flexible array:
//
// __builtin_dynamic_object_size(p, 1) ==
- // max(sizeof(struct s),
- // offsetof(struct s, array) + p->count * sizeof(*p->array))
+ // sizeof(struct s) + p->count * sizeof(*p->array))
//
ASTContext &Ctx = getContext();
const Expr *Base = E->IgnoreParenImpCasts();
@@ -1052,22 +1051,13 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr *E, unsigned Type,
// The whole struct is specificed in the __bdos.
const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(OuterRD);
- // Get the offset of the FAM.
- llvm::Constant *FAMOffset = ConstantInt::get(ResType, Offset, IsSigned);
- Value *OffsetAndFAMSize =
- Builder.CreateAdd(FAMOffset, Res, "", !IsSigned, IsSigned);
// Get the full size of the struct.
llvm::Constant *SizeofStruct =
ConstantInt::get(ResType, Layout.getSize().getQuantity(), IsSigned);
- // max(sizeof(struct s),
- // offsetof(struct s, array) + p->count * sizeof(*p->array))
- Res = IsSigned
- ? Builder.CreateBinaryIntrinsic(llvm::Intrinsic::smax,
- OffsetAndFAMSize, SizeofStruct)
- : Builder.CreateBinaryIntrinsic(llvm::Intrinsic::umax,
- OffsetAndFAMSize, SizeofStruct);
+ // Add full size of struct and fam size
+ Res = Builder.CreateAdd(SizeofStruct, Res, "", !IsSigned, IsSigned);
}
// A negative \p IdxInst or \p CountedByInst means that the index lands
next prev parent reply other threads:[~2024-10-03 15:17 UTC|newest]
Thread overview: 62+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-26 15:14 [REGRESSION][BISECTED] erroneous buffer overflow detected in bch2_xattr_validate Jan Hendrik Farr
2024-09-26 15:28 ` Thorsten Blum
2024-09-26 16:09 ` Thorsten Blum
2024-09-26 16:37 ` Jan Hendrik Farr
2024-09-26 17:01 ` Jan Hendrik Farr
2024-09-26 17:45 ` Jan Hendrik Farr
2024-09-26 19:58 ` Ard Biesheuvel
2024-09-26 22:18 ` Bill Wendling
2024-09-27 1:30 ` Bill Wendling
2024-09-27 3:41 ` Jan Hendrik Farr
2024-09-28 20:50 ` Kees Cook
2024-09-28 23:33 ` Jan Hendrik Farr
2024-09-29 19:59 ` Jan Hendrik Farr
2024-09-28 17:36 ` Jan Hendrik Farr
2024-09-28 17:49 ` Jan Hendrik Farr
2024-09-28 20:34 ` Kees Cook
2024-10-02 9:18 ` Thorsten Blum
2024-10-03 11:33 ` Jan Hendrik Farr
2024-10-03 13:07 ` Thorsten Blum
2024-10-03 13:12 ` Jan Hendrik Farr
2024-10-03 15:02 ` Thorsten Blum
2024-10-03 15:22 ` Jan Hendrik Farr
2024-10-03 15:30 ` Thorsten Blum
2024-10-03 15:35 ` Jan Hendrik Farr
2024-10-03 15:43 ` Thorsten Blum
2024-10-03 16:32 ` Jan Hendrik Farr
2024-10-03 15:17 ` Jan Hendrik Farr [this message]
2024-10-03 21:28 ` Kees Cook
2024-10-03 21:48 ` Jan Hendrik Farr
2024-10-04 17:13 ` Kees Cook
2024-10-07 3:56 ` Jan Hendrik Farr
2024-10-07 15:10 ` Jan Hendrik Farr
2024-10-16 21:13 ` Kees Cook
2024-10-16 23:41 ` Bill Wendling
2024-10-17 0:09 ` Bill Wendling
2024-10-17 3:04 ` Jan Hendrik Farr
2024-10-17 16:55 ` Nathan Chancellor
2024-10-17 17:39 ` Miguel Ojeda
2024-10-17 18:55 ` Nathan Chancellor
2024-10-18 11:52 ` Miguel Ojeda
2024-10-21 1:33 ` Jan Hendrik Farr
2024-10-21 6:04 ` Miguel Ojeda
2024-10-21 17:01 ` Jan Hendrik Farr
2024-10-21 19:25 ` Nathan Chancellor
2024-10-24 13:16 ` Jan Hendrik Farr
2024-10-25 1:15 ` Nathan Chancellor
2024-10-25 8:10 ` Miguel Ojeda
2024-10-25 15:27 ` Jan Hendrik Farr
2025-05-01 14:30 ` Alan Huang
2025-05-01 16:45 ` Jan Hendrik Farr
2025-05-01 17:22 ` Jan Hendrik Farr
2025-05-01 17:28 ` Alan Huang
2025-05-01 17:58 ` Jan Hendrik Farr
2025-05-01 18:10 ` Kees Cook
2025-05-01 18:18 ` Alan Huang
2024-10-17 0:41 ` Jan Hendrik Farr
2024-10-14 21:39 ` Bill Wendling
2024-10-16 1:22 ` Bill Wendling
2024-10-16 2:18 ` Jan Hendrik Farr
2024-10-16 20:43 ` Kees Cook
2024-10-03 21:23 ` Kees Cook
2024-10-03 22:05 ` Jan Hendrik Farr
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Zv61dCaxScXuOjZg@archlinux \
--to=kernel@jfarr.cc \
--cc=ardb@kernel.org \
--cc=kees@kernel.org \
--cc=kent.overstreet@linux.dev \
--cc=linux-bcachefs@vger.kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=morbo@google.com \
--cc=regressions@lists.linux.dev \
--cc=thorsten.blum@toblux.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).