LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 27646 - MemorySanitizer va arg helpers are broken if function has many parameters before vararg part.
Summary: MemorySanitizer va arg helpers are broken if function has many parameters bef...
Status: RESOLVED FIXED
Alias: None
Product: libraries
Classification: Unclassified
Component: Miscellaneous Instrumentation passes (show other bugs)
Version: trunk
Hardware: PC Linux
: P normal
Assignee: Marcin Kościelnicki
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-05-04 12:30 PDT by Marcin Kościelnicki
Modified: 2016-05-11 08:31 PDT (History)
2 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Marcin Kościelnicki 2016-05-04 12:30:16 PDT
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.
Comment 1 Marcin Kościelnicki 2016-05-04 17:50:30 PDT
aarch64 has the same issue, but you have to add one more non-vararg parameter (it passes 7 ints in registers, as opposed to x86_64's 6).
Comment 2 Marcin Kościelnicki 2016-05-04 17:59:53 PDT
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).
Comment 3 Marcin Kościelnicki 2016-05-11 08:31:28 PDT
Fixed in 268673, 268783, 268967.