[clang] [Clang] Fix __builtin_dynamic_object_size off by 4 (PR #111015)
Jan Hendrik Farr via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 3 09:30:00 PDT 2024
Cydox wrote:
I'm not 100% sure 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:
```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].
[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
https://github.com/llvm/llvm-project/pull/111015
More information about the cfe-commits
mailing list