From: Jan Hendrik Farr <kernel@jfarr.cc>
To: Kees Cook <kees@kernel.org>
Cc: Thorsten Blum <thorsten.blum@toblux.com>,
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 23:48:18 +0200 [thread overview]
Message-ID: <Zv8RIs-htdc-PtXB@archlinux> (raw)
In-Reply-To: <202410031424.45E5D19@keescook>
On 03 14:28:01, Kees Cook wrote:
> On Thu, Oct 03, 2024 at 05:17:08PM +0200, Jan Hendrik Farr wrote:
> > 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>)
>
> Clang's calculation seems very wrong. I would expect it to match GCC's.
>
I was on the very same train of thought, but I have since changed my
mind a bit. A struct containing a flexible array member can be allocated in
two ways:
(1):
struct posix_acl *acl = malloc(sizeof(struct posix_acl) + sizeof(struct posix_acl_entry) * 1);
acl.a_count = 1;
or (2):
struct posix_acl *acl = malloc(offsetof(struct posix_acl, a_entries) + sizeof(struct posix_acl_entry) * 1);
acl.a_count = 1;
Both are valid ways to allocate it. __bdos does not know which of these
methods was used to allocate the struct whose size it has to determine,
so it's giving the lower bound that doesn't include the (potential)
padding at the end.
So it comes down to false positives vs false negatives...
More details here:
https://github.com/llvm/llvm-project/pull/111015
Clangs current behavior would essentially force kernel code to always
assume option (2) is used. So
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);
from linux/fs/posix_acl.c would have to turn into something like:
struct posix_acl *
posix_acl_clone(const struct posix_acl *acl, gfp_t flags)
{
struct posix_acl *clone = NULL;
if (acl) {
int size = offsetof(struct posix_acl, a_entries) + 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);
Which is actually safer, because can you actually be sure this posix_acl
wasn't allocated using method (2)?
After looking at the assembly produced by gcc more, it actually looks
like it's using the allocation size if it's known in the current context
(for example if the struct was just malloced in the same function)
and otherwise returns INT_MAX for the __bdos of a struct containing a
flexible array member. It's only returning the size based on the
__counted_by attribute of you ask it for the __bdos of the flexible
array member itself.
next prev parent reply other threads:[~2024-10-03 21:48 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
2024-10-03 21:28 ` Kees Cook
2024-10-03 21:48 ` Jan Hendrik Farr [this message]
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=Zv8RIs-htdc-PtXB@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).