This is an archive of the discontinued LLVM Phabricator instance.

Fix AddressSanitizer on s390 (31-bit)
ClosedPublic

Authored by jakubjelinek on Feb 10 2017, 5:07 AM.

Details

Summary

GET_CALLER_PC doesn't work properly on 31-bit s390, as pointers are 31-bit, the MSB bit can be set when the return address is copied into integer.
This causes e.g. errors like:

#0 0xfdadb129  (<unknown module>)
#1 0x7da5e1d1 in __asan::GetStackTraceWithPcBpAndContext(__sanitizer::BufferedStackTrace*, unsigned long, unsigned long, unsigned long, void*, bool) ../../../../../libsanitizer/asan/asan_stack.h:50
#2 0x7da5e1d1 in __asan::ErrorGeneric::Print() ../../../../../libsanitizer/asan/asan_errors.cc:482
#3 0x7db178d5 in __asan::ErrorDescription::Print() ../../../../../libsanitizer/asan/asan_errors.h:360
#4 0x7db178d5 in __asan::ScopedInErrorReport::~ScopedInErrorReport() ../../../../../libsanitizer/asan/asan_report.cc:167
#5 0x7db178d5 in __asan::ReportGenericError(unsigned long, unsigned long, unsigned long, unsigned long, bool, unsigned long, unsigned int, bool) ../../../../../libsanitizer/asan/asan_report.cc:397
#6 0x7dadb14f in __interceptor_memcmp ../../../../../libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:626
#7 0x400cf5 in main /home/jakub/gcc/gcc/testsuite/c-c++-common/asan/memcmp-1.c:14
#8 0x7d807215 in __libc_start_main (/lib/libc.so.6+0x1a215)
#9 0x4007ed  (/home/jakub/gcc/obj/gcc/testsuite/memcmp-1.exe+0x4007ed)

The actual return PC inside __interceptor_memcmp was 0x7dadb129 rather than 0xfdadb129.

Diff Detail

Event Timeline

jakubjelinek created this revision.Feb 10 2017, 5:07 AM

Note, in theory __builtin_extract_return_addr should be used on all architectures, but not sure if it can't break anything, so I'm proposing to use it for now just on s390 31-bit.
In GCC, the builtin returns something other than its unmodified arguments on:
alpha-vms in certain cases
arm (for 26-bit mode)
mips (always masks off lsb)
hppa (always masks off 2 ls bits)
s390 31-bit mode (always masks off msb)
sparc adds 8 or 12 bytes to it
microblaze adds 8 bytes to it

While the masking is probably desirable everywhere, perhaps the sparc addition of 8/12 bytes is not desirable (builtin_return_address (0) alone returns the address of the call insn, while builtin_extract_return_addr returns the instruction the call will return to).

kcc edited edge metadata.Feb 10 2017, 2:26 PM

Is this change testable?

In D29824#674011, @kcc wrote:

Is this change testable?

In GCC testsuite yes. No idea how far is LLVM asan s390 31-bit port, on the asan side this was the only thing that was needed.

kcc accepted this revision.Feb 10 2017, 2:36 PM

LGTM

This revision is now accepted and ready to land.Feb 10 2017, 2:36 PM
kcc closed this revision.Feb 10 2017, 2:37 PM
koriakin edited edge metadata.Feb 13 2017, 5:45 AM
In D29824#674011, @kcc wrote:

Is this change testable?

In GCC testsuite yes. No idea how far is LLVM asan s390 31-bit port, on the asan side this was the only thing that was needed.

LLVM itself doesn't support 31-bit s390 CodeGen. I've added 31-bit support in some places in asan, but it's been completely untested so far (and can't be tested in LLVM unless you want to do a full CodeGen port), except for some quick compile-tests with gcc.