Cydox wrote:

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.

```C
int test(struct posix_acl *acl) {
    return __builtin_dynamic_object_size(acl, 0);
}
```
actually compiles to
```
test:
        mov     eax, -1
        ret
```
using gcc (trunk) on compiler explorer.

So the call to kmemdup in this function:
```C
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);
```

won't actually be bounds-checked currently when compiling the kernel with gcc. 
Compiling with clang will make this bounds-checked using the lower bound of 
possible sizes (max(sizeof(struct s), offsetof(struct s, array) + p->count * 
sizeof(*p->array)))

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