[clang] [Clang] Fix __builtin_dynamic_object_size off by 4 (PR #111015)
Jan Hendrik Farr via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 4 14:09:10 PDT 2024
Cydox wrote:
## Picture of the sizes involved to scale:
```
<-----------------malloc-max-------------->
<-----------------malloc-min------->
<------sizeof(posix_acl)------->
<-FAME-><(FAME)>
```
`FAME` = flexible array member element (aka `struct posix_acl_entry`)
`(FAME)` = hypothetical 2nd `FAME`
## Based on the C standard what do we know if `a_count` = 1?
### size of object `acl` points to
The size of the `acl` object is at least big enough to hold a single `FAME` (`malloc-min`). We also know that the largest size of the `acl` object is 1 byte smaller than would be necessary to hold 2 `FAME`s (`malloc-max`), because if it was larger `a_count` should be 2 (or larger).
### size of the flexible array element
We also know that the size of the flexible array member itself is always `a_count` multiplied by `sizeof(struct posix_acl_entry)`. No matter how much extra padding there is beyond the last `FAME` that would be padding in the struct, and not part of the flexible array member.
## What should `__bdos` return?
Here's what `__bdos` should be returning according to the documentation:
https://github.com/llvm/llvm-project/blob/3b88805ca20018ae202afd3aea39f4fa856a8c64/clang/docs/LanguageExtensions.rst?plain=1#L5502-L5507
### `__bdos(acl, 0)`:
What is "the least `n` [...] such that accesses to `(const char*)ptr + n` and beyond are **known** to be out of bounds?"
`n = malloc-max = offsetof(struct posix_acl, a_entries) + (acl->a_count + 1) * sizeof(struct posix_acl_entry) - 1 = 43`
If `alloc_size` is known that might be smaller.
### `__bdos(acl, 2)`:
What is "the greatest `n` [...] such that accesses to `(const char*)ptr + i` are *known* to be in bounds, for 0 <= `i` < `n`?"
`n = malloc-min = offsetof(struct posix_acl, a_entries) + acl->a_count * sizeof(struct posix_acl_entry) = 36`
If `alloc_size` is known that might be bigger.
### `__bdos(acl->a_entries, 0)` and `__bdos(acl->a_entries, 2)`:
Both should be:
`n = acl->a_count * sizeof(struct posix_acl_entry)`
https://github.com/llvm/llvm-project/pull/111015
More information about the cfe-commits
mailing list