You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The x86_64 and aarch64 vararg helpers in memorysanitizer pass currently assume no non-vararg argument ends up in the overflow area - if that's not true, the data stored to __msan_va_arg_tls will be misaligned with the overflow pointer computed by va_start. Here's a testcase for x86_64:
#include <stdio.h>
#include <stdarg.h>
int passarg(int a, int b, int c, int d, int e, int f, int g, ...) {
va_list v;
va_start(v, g);
int res = va_arg(v, int);
va_end(v);
return res;
}
int main() {
int undef;
int res = passarg(undef, undef, undef, undef, undef, undef, undef, 2);
if (res)
printf("%d\n", res);
return 0;
}
Compiling with -fsanitize=memory and running results in:
==22438==WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x4889ef in main (/home/mwk/llvm/llvm/a.out+0x4889ef)
#1 0x7f78129fe70f in __libc_start_main (/usr/lib/libc.so.6+0x2070f)
#2 0x418e38 in _start (/home/mwk/llvm/llvm/a.out+0x418e38)
This is because va_arg effectively reads the shadow belonging to argument g.
aarch64 should be suspectible to the same issue, but I haven't checked it.
mips64 is even worse, since it assumes there's exactly one non-vararg argument.
The text was updated successfully, but these errors were encountered:
Scratch that, you have to add two more non-vararg parameters to trigger the bug for AArch64 - if you pass 8 non-varargs, the first one is ignored, due to code copied from mips64 helper (two wrongs make a right, apparently).
Extended Description
The x86_64 and aarch64 vararg helpers in memorysanitizer pass currently assume no non-vararg argument ends up in the overflow area - if that's not true, the data stored to __msan_va_arg_tls will be misaligned with the overflow pointer computed by va_start. Here's a testcase for x86_64:
#include <stdio.h>
#include <stdarg.h>
int passarg(int a, int b, int c, int d, int e, int f, int g, ...) {
va_list v;
va_start(v, g);
int res = va_arg(v, int);
va_end(v);
return res;
}
int main() {
int undef;
int res = passarg(undef, undef, undef, undef, undef, undef, undef, 2);
if (res)
printf("%d\n", res);
return 0;
}
Compiling with -fsanitize=memory and running results in:
==22438==WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x4889ef in main (/home/mwk/llvm/llvm/a.out+0x4889ef)
#1 0x7f78129fe70f in __libc_start_main (/usr/lib/libc.so.6+0x2070f)
#2 0x418e38 in _start (/home/mwk/llvm/llvm/a.out+0x418e38)
This is because va_arg effectively reads the shadow belonging to argument g.
aarch64 should be suspectible to the same issue, but I haven't checked it.
mips64 is even worse, since it assumes there's exactly one non-vararg argument.
The text was updated successfully, but these errors were encountered: