[llvm] [llvm] Improve llvm.objectsize computation by computing GEP, alloca a… (PR #117849)
Martin Storsjö via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 18 01:48:09 PST 2024
mstorsjo wrote:
This causes some cases of buffer overflow checks to fail - we ran into this in https://github.com/llvm/llvm-test-suite/pull/188.
I've managed to reduce the issue down to a small standalone reproducer:
```c
void *checkasm_check_func(void *func, const char *name, ...);
void randomize_loopfilter_buffers(int lineoff, int str,
int dir, int flim_E, int flim_I,
int hev_thresh, unsigned char *buf,
int force_hev);
void fill_loopfilter_buffers(unsigned char *buf, int stride, int w, int h);
void func(void *ptr);
#define memcpy(dst, src, n) __builtin___memcpy_chk((dst), (src), (n), __builtin_object_size((dst), 0))
void check_loopfilter_16y(void)
{
unsigned char base0[32 + 16 * 16];
unsigned char base1[32 + 16 * 16];
int dir, edge, force_hev;
int flim_E = 20, flim_I = 10, hev_thresh = 7;
for (dir = 0; dir < 2; dir++) {
int midoff = dir ? 4 * 16 : 4;
int midoff_aligned = dir ? 4 * 16 : 16;
unsigned char *buf0 = base0 + midoff_aligned;
unsigned char *buf1 = base1 + midoff_aligned;
for (edge = 0; edge < 2; edge++) {
if (checkasm_check_func(func, "vp8_loop_filter16y")) {
for (force_hev = -1; force_hev <= 1; force_hev++) {
fill_loopfilter_buffers(buf0, 16, 16, 16);
randomize_loopfilter_buffers(0, 16, dir, flim_E, flim_I, hev_thresh, buf0, force_hev);
memcpy(buf1 - midoff, base0, 16 * 16);
func(buf1 - midoff);
}
}
}
}
}
```
If we compile this with e.g. `clang --target=aarch64-linux-gnu -O2 repro.c -S -o -` before this change, the whole `memcpy` and `__builtin_memcpy_chk` gets expanded into an inline memcpy with no call to `__memcpy_chk`.
After this change, we instead get this:
```
add x0, x23, x22
add x1, sp, #296
mov w2, #256 // =0x100
mov x3, xzr
bl __memcpy_chk
```
Parameter `x3` here is the buffer size parameter to `__memcpy_chk`, which gets passed as zero - i.e. we're doing memcpy to a zero byte output buffer, which will fail as soon as we're copying more than zero bytes into it.
The same reproduces for `arm64-apple-darwin` and `x86_64-linux-gnu` too, and presumably any target, just pick whichever you're most comfortable with reading :-)
Can we revert this until this issue is fixed?
https://github.com/llvm/llvm-project/pull/117849
More information about the llvm-commits
mailing list