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-3c55ca910...@linux.dev/
[2] https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf

https://github.com/llvm/llvm-project/pull/111015
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to