On 11/15/22 11:07, Jakub Jelinek wrote: > On Tue, Nov 15, 2022 at 11:02:53AM +0100, Martin Liška wrote: >>> Is it allowed to merge libsanitizer from LLVM in stage 3? If not I'd >>> like to cherry pick some commits from LLVM [to fix some stupid errors >>> I've made in LoongArch libasan :(]. >> >> I'm sorry but I was really busy with the porting of the documentation to >> Sphinx. >> >> Anyway, yes, we should make one one libsanitizer merge, but RM should likely >> approve it: Richi, Jakub, do you support it? > > Could you please prepare a patch, so that we can see how much actually > changed and decide based on that whether to go for a merge or cherry-picking > one or more commits?
Sure, there it is. There's a minor change in output format that I address in 0003 patch. Apart from that, I was able to run all tests on x86_64-linux-gnu. Patch statistics: 46 files changed, 524 insertions(+), 252 deletions(-) I'm running build on ppc64le and if you're fine, I'm going to finish a proper libsanitizer testing procedure. Martin > I think last merge was done by you at the end of August, so we have > 2.5 months of changes to potentially merge. > > Jakub >
From b9da933ec8860e0c217e2f6fc08f08687d40725f Mon Sep 17 00:00:00 2001 From: Martin Liska <mli...@suse.cz> Date: Tue, 15 Nov 2022 12:02:36 +0100 Subject: [PATCH 3/3] asan: update expected format based on ASAN gcc/testsuite/ChangeLog: * c-c++-common/asan/global-overflow-1.c: Update expected format. * c-c++-common/asan/heap-overflow-1.c: Likewise. * c-c++-common/asan/strlen-overflow-1.c: Likewise. * c-c++-common/asan/strncpy-overflow-1.c: Likewise. * c-c++-common/hwasan/heap-overflow.c: Likewise. * g++.dg/asan/asan_mem_test.cc: Likewise. * g++.dg/asan/asan_oob_test.cc: Likewise. * g++.dg/asan/asan_str_test.cc: Likewise. * g++.dg/asan/asan_test.cc: Likewise. * g++.dg/asan/large-func-test-1.C: Likewise. --- .../c-c++-common/asan/global-overflow-1.c | 2 +- .../c-c++-common/asan/heap-overflow-1.c | 2 +- .../c-c++-common/asan/strlen-overflow-1.c | 2 +- .../c-c++-common/asan/strncpy-overflow-1.c | 2 +- .../c-c++-common/hwasan/heap-overflow.c | 2 +- gcc/testsuite/g++.dg/asan/asan_mem_test.cc | 20 +++++------ gcc/testsuite/g++.dg/asan/asan_oob_test.cc | 12 +++---- gcc/testsuite/g++.dg/asan/asan_str_test.cc | 4 +-- gcc/testsuite/g++.dg/asan/asan_test.cc | 36 +++++++++---------- gcc/testsuite/g++.dg/asan/large-func-test-1.C | 2 +- 10 files changed, 42 insertions(+), 42 deletions(-) diff --git a/gcc/testsuite/c-c++-common/asan/global-overflow-1.c b/gcc/testsuite/c-c++-common/asan/global-overflow-1.c index ec412231be0..b97801da2b7 100644 --- a/gcc/testsuite/c-c++-common/asan/global-overflow-1.c +++ b/gcc/testsuite/c-c++-common/asan/global-overflow-1.c @@ -25,5 +25,5 @@ int main() { /* { dg-skip-if "inaccurate debug info" { mips*-*-* } { "*" } { "-O0" } } */ /* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */ /* { dg-output " #0 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*global-overflow-1.c:20|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\])\[^\n\r]*(\n|\r\n|\r).*" } */ -/* { dg-output "0x\[0-9a-f\]+ is located 0 bytes to the right of global variable" } */ +/* { dg-output "0x\[0-9a-f\]+ is located 0 bytes after global variable" } */ /* { dg-output ".*YYY\[^\n\r]* of size 10\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c b/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c index 7ef048e636f..7d8744852ae 100644 --- a/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c +++ b/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c @@ -25,7 +25,7 @@ int main(int argc, char **argv) { /* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */ /* { dg-output " #0 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*heap-overflow-1.c:21|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\]).*(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 0 bytes to the right of 10-byte region\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 0 bytes after 10-byte region\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output "\[^\n\r]*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #0 0x\[0-9a-f\]+ +(in _*(interceptor_|wrap_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*heap-overflow-1.c:19|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/asan/strlen-overflow-1.c b/gcc/testsuite/c-c++-common/asan/strlen-overflow-1.c index 86a79fd5d06..34c20c8ed50 100644 --- a/gcc/testsuite/c-c++-common/asan/strlen-overflow-1.c +++ b/gcc/testsuite/c-c++-common/asan/strlen-overflow-1.c @@ -21,4 +21,4 @@ int main () { /* { dg-output "READ of size 2 at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */ /* { dg-output " #1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*strlen-overflow-1.c:19|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 0 bytes to the right of global variable" } */ +/* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 0 bytes after global variable" } */ diff --git a/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c b/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c index 3d439160b7e..834284722f9 100644 --- a/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c +++ b/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c @@ -16,7 +16,7 @@ int main(int argc, char **argv) { /* { dg-output "WRITE of size \[0-9\]* at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #0 0x\[0-9a-f\]+ +(in _*(interceptor_|wrap_|)strncpy|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*strncpy-overflow-1.c:12|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\]).*(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 0 bytes to the right of 9-byte region\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 0 bytes after 9-byte region\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output "\[^\n\r]*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #0 0x\[0-9a-f\]+ +(in _*(interceptor_|wrap_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*strncpy-overflow-1.c:11|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/hwasan/heap-overflow.c b/gcc/testsuite/c-c++-common/hwasan/heap-overflow.c index bddb38c81f1..a5a37715925 100644 --- a/gcc/testsuite/c-c++-common/hwasan/heap-overflow.c +++ b/gcc/testsuite/c-c++-common/hwasan/heap-overflow.c @@ -24,6 +24,6 @@ int main(int argc, char **argv) { /* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */ /* { dg-output "READ of size 1 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/\[\[:xdigit:\]\]\[\[:xdigit:\]\].* \\(ptr/mem\\) in thread T0.*" } */ -/* { dg-output "located 0 bytes to the right of 10-byte region.*" } */ +/* { dg-output "located 0 bytes after 10-byte region.*" } */ /* { dg-output "allocated here:.*" } */ /* { dg-output "#1 0x\[0-9a-f\]+ +in _*main \[^\n\r]*heap-overflow.c:18" } */ diff --git a/gcc/testsuite/g++.dg/asan/asan_mem_test.cc b/gcc/testsuite/g++.dg/asan/asan_mem_test.cc index 5fc4af7e9e3..7f6f3f4c1f8 100644 --- a/gcc/testsuite/g++.dg/asan/asan_mem_test.cc +++ b/gcc/testsuite/g++.dg/asan/asan_mem_test.cc @@ -31,18 +31,18 @@ void MemSetOOBTestTemplate(size_t length) { MEMSET(array + length, 0, zero); MEMSET(array + length + 1, 0, zero); - // try to memset bytes to the right of array + // try to memset bytes after array EXPECT_DEATH(MEMSET(array, 0, size + 1), RightOOBWriteMessage(0)); EXPECT_DEATH(MEMSET((char*)(array + length) - 1, element, 6), RightOOBWriteMessage(0)); EXPECT_DEATH(MEMSET(array + 1, element, size + sizeof(T)), RightOOBWriteMessage(0)); - // whole interval is to the right + // whole interval is after EXPECT_DEATH(MEMSET(array + length + 1, 0, 10), RightOOBWriteMessage(sizeof(T))); - // try to memset bytes to the left of array + // try to memset bytes before array EXPECT_DEATH(MEMSET((char*)array - 1, element, size), LeftOOBWriteMessage(1)); EXPECT_DEATH(MEMSET((char*)array - 5, 0, 6), @@ -52,11 +52,11 @@ void MemSetOOBTestTemplate(size_t length) { EXPECT_DEATH(memset(array - 5, element, size + 5 * sizeof(T)), LeftOOBWriteMessage(5 * sizeof(T))); } - // whole interval is to the left + // whole interval is before EXPECT_DEATH(MEMSET(array - 2, 0, sizeof(T)), LeftOOBWriteMessage(2 * sizeof(T))); - // try to memset bytes both to the left & to the right + // try to memset bytes both before & after EXPECT_DEATH(MEMSET((char*)array - 2, element, size + 4), LeftOOBWriteMessage(2)); @@ -108,7 +108,7 @@ TEST(AddressSanitizer, LargeOOBInMemset) { // fprintf(stderr, " large oob memset: %p %p %zd\n", x1, x2, size); // Do a memset on x1 with huge out-of-bound access that will end up in x2. EXPECT_DEATH(Ident(memset)(x1, 0, size * 2), - "is located 0 bytes to the right"); + "is located 0 bytes after"); delete [] x1; delete [] x2; return; @@ -137,25 +137,25 @@ void MemTransferOOBTestTemplate(size_t length) { M::transfer(dest, src - 1, zero); M::transfer(dest, src, zero); - // try to change mem to the right of dest + // try to change mem after dest EXPECT_DEATH(M::transfer(dest + 1, src, size), RightOOBWriteMessage(0)); EXPECT_DEATH(M::transfer((char*)(dest + length) - 1, src, 5), RightOOBWriteMessage(0)); - // try to change mem to the left of dest + // try to change mem before dest EXPECT_DEATH(M::transfer(dest - 2, src, size), LeftOOBWriteMessage(2 * sizeof(T))); EXPECT_DEATH(M::transfer((char*)dest - 3, src, 4), LeftOOBWriteMessage(3)); - // try to access mem to the right of src + // try to access mem after src EXPECT_DEATH(M::transfer(dest, src + 2, size), RightOOBReadMessage(0)); EXPECT_DEATH(M::transfer(dest, (char*)(src + length) - 3, 6), RightOOBReadMessage(0)); - // try to access mem to the left of src + // try to access mem before src EXPECT_DEATH(M::transfer(dest, src - 1, size), LeftOOBReadMessage(sizeof(T))); EXPECT_DEATH(M::transfer(dest, (char*)src - 6, 7), diff --git a/gcc/testsuite/g++.dg/asan/asan_oob_test.cc b/gcc/testsuite/g++.dg/asan/asan_oob_test.cc index 7d3f55785f0..05fa7229486 100644 --- a/gcc/testsuite/g++.dg/asan/asan_oob_test.cc +++ b/gcc/testsuite/g++.dg/asan/asan_oob_test.cc @@ -33,7 +33,7 @@ void OOBTest() { for (int size = sizeof(T); size < 20; size += 5) { for (int i = -5; i < 0; i++) { const char *str = - "is located.*%d byte.*to the left"; + "is located.*%d byte.*before"; sprintf(expected_str, str, abs(i)); EXPECT_DEATH(oob_test<T>(size, i), expected_str); } @@ -43,7 +43,7 @@ void OOBTest() { for (int i = size - sizeof(T) + 1; i <= (int)(size + 2 * sizeof(T)); i++) { const char *str = - "is located.*%d byte.*to the right"; + "is located.*%d byte.*after"; int off = i >= size ? (i - size) : 0; // we don't catch unaligned partially OOB accesses. if (i % sizeof(T)) continue; @@ -53,9 +53,9 @@ void OOBTest() { } EXPECT_DEATH(oob_test<T>(kLargeMalloc, -1), - "is located.*1 byte.*to the left"); + "is located.*1 byte.*before"); EXPECT_DEATH(oob_test<T>(kLargeMalloc, kLargeMalloc), - "is located.*0 byte.*to the right"); + "is located.*0 byte.*after"); } // TODO(glider): the following tests are EXTREMELY slow on Darwin: @@ -89,7 +89,7 @@ TEST(AddressSanitizer, OOBRightTest) { } else { int outside_bytes = offset > alloc_size ? (offset - alloc_size) : 0; const char *str = - "is located.%d *byte.*to the right"; + "is located.%d *byte.*after"; char expected_str[100]; sprintf(expected_str, str, outside_bytes); EXPECT_DEATH(asan_write_sized_aligned(addr, access_size), @@ -106,7 +106,7 @@ TEST(AddressSanitizer, LargeOOBRightTest) { for (size_t i = 16; i <= 256; i *= 2) { size_t size = large_power_of_two - i; char *p = Ident(new char[size]); - EXPECT_DEATH(p[size] = 0, "is located 0 bytes to the right"); + EXPECT_DEATH(p[size] = 0, "is located 0 bytes after"); delete [] p; } } diff --git a/gcc/testsuite/g++.dg/asan/asan_str_test.cc b/gcc/testsuite/g++.dg/asan/asan_str_test.cc index 207de422316..56e136930e4 100644 --- a/gcc/testsuite/g++.dg/asan/asan_str_test.cc +++ b/gcc/testsuite/g++.dg/asan/asan_str_test.cc @@ -19,7 +19,7 @@ static char global_string[] = "global"; static size_t global_string_length = 6; // Input to a test is a zero-terminated string str with given length -// Accesses to the bytes to the left and to the right of str +// Accesses to the bytes to the left and after str // are presumed to produce OOB errors void StrLenOOBTestTemplate(char *str, size_t length, bool is_global) { // Normal strlen calls @@ -30,7 +30,7 @@ void StrLenOOBTestTemplate(char *str, size_t length, bool is_global) { } // Arg of strlen is not malloced, OOB access if (!is_global) { - // We don't insert RedZones to the left of global variables + // We don't insert RedZones before global variables EXPECT_DEATH(Ident(strlen(str - 1)), LeftOOBReadMessage(1)); EXPECT_DEATH(Ident(strlen(str - 5)), LeftOOBReadMessage(5)); } diff --git a/gcc/testsuite/g++.dg/asan/asan_test.cc b/gcc/testsuite/g++.dg/asan/asan_test.cc index dbf1a6ac0a5..0d976801cf1 100644 --- a/gcc/testsuite/g++.dg/asan/asan_test.cc +++ b/gcc/testsuite/g++.dg/asan/asan_test.cc @@ -286,7 +286,7 @@ TEST(AddressSanitizer, SignalTest) { static void TestLargeMalloc(size_t size) { char buff[1024]; - sprintf(buff, "is located 1 bytes to the left of %lu-byte", (long)size); + sprintf(buff, "is located 1 bytes before %lu-byte", (long)size); EXPECT_DEATH(Ident((char*)malloc(size))[-1] = 0, buff); } @@ -301,7 +301,7 @@ TEST(AddressSanitizer, HugeMallocTest) { if (SANITIZER_WORDSIZE != 64 || ASAN_AVOID_EXPENSIVE_TESTS) return; size_t n_megs = 4100; EXPECT_DEATH(Ident((char*)malloc(n_megs << 20))[-1] = 0, - "is located 1 bytes to the left|" + "is located 1 bytes before|" "AddressSanitizer failed to allocate"); } @@ -316,9 +316,9 @@ TEST(AddressSanitizer, memalign) { for (int align = 16; align <= (1 << 23); align *= 2) { size_t size = align * 5; EXPECT_DEATH(MemalignRun(align, size, -1), - "is located 1 bytes to the left"); + "is located 1 bytes before"); EXPECT_DEATH(MemalignRun(align, size, size + 1), - "is located 1 bytes to the right"); + "is located 1 bytes after"); } } #endif // SANITIZER_TEST_HAS_MEMALIGN @@ -696,7 +696,7 @@ TEST(AddressSanitizer, Store128Test) { EXPECT_DEATH(_mm_store_si128((__m128i*)p, value_wide), "WRITE of size 16"); EXPECT_DEATH(_mm_store_si128((__m128i*)p, value_wide), - "located 0 bytes to the right of 12-byte"); + "located 0 bytes after 12-byte"); free(a); } #endif @@ -709,7 +709,7 @@ string RightOOBErrorMessage(int oob_distance, bool is_write) { #if !GTEST_USES_SIMPLE_RE "buffer-overflow.*%s.*" #endif - "located %d bytes to the right", + "located %d bytes after", #if !GTEST_USES_SIMPLE_RE is_write ? "WRITE" : "READ", #endif @@ -733,7 +733,7 @@ string LeftOOBErrorMessage(int oob_distance, bool is_write) { #if !GTEST_USES_SIMPLE_RE ASAN_PCRE_DOTALL "%s.*" #endif - "located %d bytes to the left", + "located %d bytes before", #if !GTEST_USES_SIMPLE_RE is_write ? "WRITE" : "READ", #endif @@ -752,7 +752,7 @@ string LeftOOBReadMessage(int oob_distance) { string LeftOOBAccessMessage(int oob_distance) { assert(oob_distance > 0); char expected_str[100]; - sprintf(expected_str, "located %d bytes to the left", oob_distance); + sprintf(expected_str, "located %d bytes before", oob_distance); return string(expected_str); } @@ -774,7 +774,7 @@ char* MallocAndMemsetString(size_t size) { EXPECT_DEATH(READ_N_BYTES, \ ASAN_PCRE_DOTALL \ "AddressSanitizer: heap-buffer-overflow" \ - ".* is located 0 bytes to the right of 10-byte region"); \ + ".* is located 0 bytes after 10-byte region"); \ close(fd); \ delete [] x; \ @@ -976,23 +976,23 @@ TEST(AddressSanitizer, GlobalTest) { glob5[Ident(4)] = 0; EXPECT_DEATH(glob5[Ident(5)] = 0, - "0 bytes to the right of global variable.*glob5.* size 5"); + "0 bytes after global variable.*glob5.* size 5"); EXPECT_DEATH(glob5[Ident(5+6)] = 0, - "6 bytes to the right of global variable.*glob5.* size 5"); + "6 bytes after global variable.*glob5.* size 5"); Ident(static110); // avoid optimizations static110[Ident(0)] = 0; static110[Ident(109)] = 0; EXPECT_DEATH(static110[Ident(110)] = 0, - "0 bytes to the right of global variable"); + "0 bytes after global variable"); EXPECT_DEATH(static110[Ident(110+7)] = 0, - "7 bytes to the right of global variable"); + "7 bytes after global variable"); Ident(func_static15); // avoid optimizations func_static15[Ident(0)] = 0; EXPECT_DEATH(func_static15[Ident(15)] = 0, - "0 bytes to the right of global variable"); + "0 bytes after global variable"); EXPECT_DEATH(func_static15[Ident(15 + 9)] = 0, - "9 bytes to the right of global variable"); + "9 bytes after global variable"); Ident(fs1); Ident(fs2); @@ -1000,12 +1000,12 @@ TEST(AddressSanitizer, GlobalTest) { // We don't create left redzones, so this is not 100% guaranteed to fail. // But most likely will. - EXPECT_DEATH(fs2[Ident(-1)] = 0, "is located.*of global variable"); + EXPECT_DEATH(fs2[Ident(-1)] = 0, "is located.*global variable"); EXPECT_DEATH(Ident(Ident(ConstGlob)[8]), - "is located 1 bytes to the right of .*ConstGlob"); + "is located 1 bytes after .*ConstGlob"); EXPECT_DEATH(Ident(Ident(StaticConstGlob)[5]), - "is located 2 bytes to the right of .*StaticConstGlob"); + "is located 2 bytes after .*StaticConstGlob"); // call stuff from another file. GlobalsTest(0); diff --git a/gcc/testsuite/g++.dg/asan/large-func-test-1.C b/gcc/testsuite/g++.dg/asan/large-func-test-1.C index ac9deb898c8..a43235ba1cb 100644 --- a/gcc/testsuite/g++.dg/asan/large-func-test-1.C +++ b/gcc/testsuite/g++.dg/asan/large-func-test-1.C @@ -40,7 +40,7 @@ int main() { // { dg-output "0x\[0-9a-f\]+ at pc 0x\[0-9a-f\]+ bp 0x\[0-9a-f\]+ sp 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } // { dg-output "\[^\n\r]*READ of size 4 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } // { dg-output " #0 0x\[0-9a-f\]+ +(in \[^\n\r]*LargeFunction\[^\n\r]*(large-func-test-1.C:18|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\]).*(\n|\r\n|\r)" } -// { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 44 bytes to the right of 400-byte region.*(\n|\r\n|\r)" } +// { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 44 bytes after 400-byte region.*(\n|\r\n|\r)" } // { dg-output "\[^\n\r]*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } // { dg-output " #0( 0x\[0-9a-f\]+ +(in _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } // { dg-output " #1|) 0x\[0-9a-f\]+ +(in (operator new|(wrap|)_*_Zn\[aw\]\[mj\])|\[(\])\[^\n\r]*(\n|\r\n|\r)" } -- 2.38.1
From ddfa73af85a7dd86639ca433327498cbc93757b5 Mon Sep 17 00:00:00 2001 From: Martin Liska <mli...@suse.cz> Date: Thu, 5 May 2022 12:52:44 +0200 Subject: [PATCH 2/3] libsanitizer: Apply local patches --- libsanitizer/asan/asan_globals.cpp | 19 ------ libsanitizer/asan/asan_interceptors.h | 7 ++- libsanitizer/asan/asan_mapping.h | 2 +- .../sanitizer_linux_libcdep.cpp | 4 ++ .../sanitizer_common/sanitizer_mac.cpp | 12 +++- libsanitizer/sanitizer_common/sanitizer_mac.h | 20 ++++++ .../sanitizer_platform_limits_linux.cpp | 5 +- .../sanitizer_procmaps_mac.cpp | 62 +++---------------- .../sanitizer_common/sanitizer_stacktrace.cpp | 17 +++-- libsanitizer/tsan/tsan_rtl_ppc64.S | 1 + libsanitizer/ubsan/ubsan_flags.cpp | 1 + libsanitizer/ubsan/ubsan_handlers.cpp | 15 +++++ libsanitizer/ubsan/ubsan_handlers.h | 8 +++ libsanitizer/ubsan/ubsan_platform.h | 2 + 14 files changed, 94 insertions(+), 81 deletions(-) diff --git a/libsanitizer/asan/asan_globals.cpp b/libsanitizer/asan/asan_globals.cpp index b780128c9ad..8f3491f0199 100644 --- a/libsanitizer/asan/asan_globals.cpp +++ b/libsanitizer/asan/asan_globals.cpp @@ -154,23 +154,6 @@ static void CheckODRViolationViaIndicator(const Global *g) { } } -// Check ODR violation for given global G by checking if it's already poisoned. -// We use this method in case compiler doesn't use private aliases for global -// variables. -static void CheckODRViolationViaPoisoning(const Global *g) { - if (__asan_region_is_poisoned(g->beg, g->size_with_redzone)) { - // This check may not be enough: if the first global is much larger - // the entire redzone of the second global may be within the first global. - for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) { - if (g->beg == l->g->beg && - (flags()->detect_odr_violation >= 2 || g->size != l->g->size) && - !IsODRViolationSuppressed(g->name)) - ReportODRViolation(g, FindRegistrationSite(g), - l->g, FindRegistrationSite(l->g)); - } - } -} - // Clang provides two different ways for global variables protection: // it can poison the global itself or its private alias. In former // case we may poison same symbol multiple times, that can help us to @@ -216,8 +199,6 @@ static void RegisterGlobal(const Global *g) { // where two globals with the same name are defined in different modules. if (UseODRIndicator(g)) CheckODRViolationViaIndicator(g); - else - CheckODRViolationViaPoisoning(g); } if (CanPoisonMemory()) PoisonRedZones(*g); diff --git a/libsanitizer/asan/asan_interceptors.h b/libsanitizer/asan/asan_interceptors.h index c4bf087ea17..9a6c22c764a 100644 --- a/libsanitizer/asan/asan_interceptors.h +++ b/libsanitizer/asan/asan_interceptors.h @@ -81,7 +81,12 @@ void InitializePlatformInterceptors(); #if ASAN_HAS_EXCEPTIONS && !SANITIZER_WINDOWS && !SANITIZER_SOLARIS && \ !SANITIZER_NETBSD # define ASAN_INTERCEPT___CXA_THROW 1 -# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 1 +# if ! defined(ASAN_HAS_CXA_RETHROW_PRIMARY_EXCEPTION) \ + || ASAN_HAS_CXA_RETHROW_PRIMARY_EXCEPTION +# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 1 +# else +# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 0 +# endif # if defined(_GLIBCXX_SJLJ_EXCEPTIONS) || (SANITIZER_IOS && defined(__arm__)) # define ASAN_INTERCEPT__UNWIND_SJLJ_RAISEEXCEPTION 1 # else diff --git a/libsanitizer/asan/asan_mapping.h b/libsanitizer/asan/asan_mapping.h index c5f95c07a21..47ccf8444d3 100644 --- a/libsanitizer/asan/asan_mapping.h +++ b/libsanitizer/asan/asan_mapping.h @@ -190,7 +190,7 @@ # elif defined(__aarch64__) # define ASAN_SHADOW_OFFSET_CONST 0x0000001000000000 # elif defined(__powerpc64__) -# define ASAN_SHADOW_OFFSET_CONST 0x0000100000000000 +# define ASAN_SHADOW_OFFSET_CONST 0x0000020000000000 # elif defined(__s390x__) # define ASAN_SHADOW_OFFSET_CONST 0x0010000000000000 # elif SANITIZER_FREEBSD diff --git a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp index d74851c43e1..56d231643ba 100644 --- a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp @@ -822,9 +822,13 @@ u32 GetNumberOfCPUs() { #elif SANITIZER_SOLARIS return sysconf(_SC_NPROCESSORS_ONLN); #else +#if defined(CPU_COUNT) cpu_set_t CPUs; CHECK_EQ(sched_getaffinity(0, sizeof(cpu_set_t), &CPUs), 0); return CPU_COUNT(&CPUs); +#else + return 1; +#endif #endif } diff --git a/libsanitizer/sanitizer_common/sanitizer_mac.cpp b/libsanitizer/sanitizer_common/sanitizer_mac.cpp index 23c4c6619de..a2591e996e7 100644 --- a/libsanitizer/sanitizer_common/sanitizer_mac.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_mac.cpp @@ -38,7 +38,7 @@ extern char **environ; #endif -#if defined(__has_include) && __has_include(<os/trace.h>) +#if defined(__has_include) && __has_include(<os/trace.h>) && defined(__BLOCKS__) #define SANITIZER_OS_TRACE 1 #include <os/trace.h> #else @@ -71,7 +71,15 @@ extern "C" { #include <mach/mach_time.h> #include <mach/vm_statistics.h> #include <malloc/malloc.h> -#include <os/log.h> +#if defined(__has_builtin) && __has_builtin(__builtin_os_log_format) +# include <os/log.h> +#else + /* Without support for __builtin_os_log_format, fall back to the older + method. */ +# define OS_LOG_DEFAULT 0 +# define os_log_error(A,B,C) \ + asl_log(nullptr, nullptr, ASL_LEVEL_ERR, "%s", (C)); +#endif #include <pthread.h> #include <pthread/introspection.h> #include <sched.h> diff --git a/libsanitizer/sanitizer_common/sanitizer_mac.h b/libsanitizer/sanitizer_common/sanitizer_mac.h index f0a97d098ee..1cf2e298cc9 100644 --- a/libsanitizer/sanitizer_common/sanitizer_mac.h +++ b/libsanitizer/sanitizer_common/sanitizer_mac.h @@ -14,6 +14,26 @@ #include "sanitizer_common.h" #include "sanitizer_platform.h" + +/* TARGET_OS_OSX is not present in SDKs before Darwin16 (macOS 10.12) use + TARGET_OS_MAC (we have no support for iOS in any form for these versions, + so there's no ambiguity). */ +#if !defined(TARGET_OS_OSX) && TARGET_OS_MAC +# define TARGET_OS_OSX 1 +#endif + +/* Other TARGET_OS_xxx are not present on earlier versions, define them to + 0 (we have no support for them; they are not valid targets anyway). */ +#ifndef TARGET_OS_IOS +#define TARGET_OS_IOS 0 +#endif +#ifndef TARGET_OS_TV +#define TARGET_OS_TV 0 +#endif +#ifndef TARGET_OS_WATCH +#define TARGET_OS_WATCH 0 +#endif + #if SANITIZER_APPLE #include "sanitizer_posix.h" diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp b/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp index bf0f355847c..c278c8797f7 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp @@ -26,7 +26,10 @@ // With old kernels (and even new kernels on powerpc) asm/stat.h uses types that // are not defined anywhere in userspace headers. Fake them. This seems to work -// fine with newer headers, too. +// fine with newer headers, too. Beware that with <sys/stat.h>, struct stat +// takes the form of struct stat64 on 32-bit platforms if _FILE_OFFSET_BITS=64. +// Also, for some platforms (e.g. mips) there are additional members in the +// <sys/stat.h> struct stat:s. #include <linux/posix_types.h> # if defined(__x86_64__) || defined(__mips__) || defined(__hexagon__) # include <sys/stat.h> diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp b/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp index 4b0e6781976..ba4259acd46 100644 --- a/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp @@ -146,8 +146,13 @@ static bool IsDyldHdr(const mach_header *hdr) { // until we hit a Mach header matching dyld instead. These recurse // calls are expensive, but the first memory map generation occurs // early in the process, when dyld is one of the only images loaded, -// so it will be hit after only a few iterations. These assumptions don't hold -// on macOS 13+ anymore (dyld itself has moved into the shared cache). +// so it will be hit after only a few iterations. These assumptions don't +// hold on macOS 13+ anymore (dyld itself has moved into the shared cache). + +// FIXME: Unfortunately, the upstream revised version to deal with macOS 13+ +// is incompatible with GCC and also uses APIs not available on earlier +// systems which we support; backed out for now. + static mach_header *GetDyldImageHeaderViaVMRegion() { vm_address_t address = 0; @@ -171,64 +176,17 @@ static mach_header *GetDyldImageHeaderViaVMRegion() { } } -extern "C" { -struct dyld_shared_cache_dylib_text_info { - uint64_t version; // current version 2 - // following fields all exist in version 1 - uint64_t loadAddressUnslid; - uint64_t textSegmentSize; - uuid_t dylibUuid; - const char *path; // pointer invalid at end of iterations - // following fields all exist in version 2 - uint64_t textSegmentOffset; // offset from start of cache -}; -typedef struct dyld_shared_cache_dylib_text_info - dyld_shared_cache_dylib_text_info; - -extern bool _dyld_get_shared_cache_uuid(uuid_t uuid); -extern const void *_dyld_get_shared_cache_range(size_t *length); -extern int dyld_shared_cache_iterate_text( - const uuid_t cacheUuid, - void (^callback)(const dyld_shared_cache_dylib_text_info *info)); -} // extern "C" - -static mach_header *GetDyldImageHeaderViaSharedCache() { - uuid_t uuid; - bool hasCache = _dyld_get_shared_cache_uuid(uuid); - if (!hasCache) - return nullptr; - - size_t cacheLength; - __block uptr cacheStart = (uptr)_dyld_get_shared_cache_range(&cacheLength); - CHECK(cacheStart && cacheLength); - - __block mach_header *dyldHdr = nullptr; - int res = dyld_shared_cache_iterate_text( - uuid, ^(const dyld_shared_cache_dylib_text_info *info) { - CHECK_GE(info->version, 2); - mach_header *hdr = - (mach_header *)(cacheStart + info->textSegmentOffset); - if (IsDyldHdr(hdr)) - dyldHdr = hdr; - }); - CHECK_EQ(res, 0); - - return dyldHdr; -} - const mach_header *get_dyld_hdr() { if (!dyld_hdr) { // On macOS 13+, dyld itself has moved into the shared cache. Looking it up // via vm_region_recurse_64() causes spins/hangs/crashes. + // FIXME: find a way to do this compatible with GCC. if (GetMacosAlignedVersion() >= MacosVersion(13, 0)) { - dyld_hdr = GetDyldImageHeaderViaSharedCache(); - if (!dyld_hdr) { VReport(1, - "Failed to lookup the dyld image header in the shared cache on " - "macOS 13+ (or no shared cache in use). Falling back to " + "looking up the dyld image header in the shared cache on " + "macOS 13+ is not yet supported. Falling back to " "lookup via vm_region_recurse_64().\n"); dyld_hdr = GetDyldImageHeaderViaVMRegion(); - } } else { dyld_hdr = GetDyldImageHeaderViaVMRegion(); } diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp index d24fae98213..661495e2340 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp @@ -87,8 +87,8 @@ static inline uhwptr *GetCanonicFrame(uptr bp, // Nope, this does not look right either. This means the frame after next does // not have a valid frame pointer, but we can still extract the caller PC. // Unfortunately, there is no way to decide between GCC and LLVM frame - // layouts. Assume LLVM. - return bp_prev; + // layouts. Assume GCC. + return bp_prev - 1; #else return (uhwptr*)bp; #endif @@ -111,14 +111,21 @@ void BufferedStackTrace::UnwindFast(uptr pc, uptr bp, uptr stack_top, IsAligned((uptr)frame, sizeof(*frame)) && size < max_depth) { #ifdef __powerpc__ - // PowerPC ABIs specify that the return address is saved at offset - // 16 of the *caller's* stack frame. Thus we must dereference the - // back chain to find the caller frame before extracting it. + // PowerPC ABIs specify that the return address is saved on the + // *caller's* stack frame. Thus we must dereference the back chain + // to find the caller frame before extracting it. uhwptr *caller_frame = (uhwptr*)frame[0]; if (!IsValidFrame((uptr)caller_frame, stack_top, bottom) || !IsAligned((uptr)caller_frame, sizeof(uhwptr))) break; + // For most ABIs the offset where the return address is saved is two + // register sizes. The exception is the SVR4 ABI, which uses an + // offset of only one register size. +#ifdef _CALL_SYSV + uhwptr pc1 = caller_frame[1]; +#else uhwptr pc1 = caller_frame[2]; +#endif #elif defined(__s390__) uhwptr pc1 = frame[14]; #elif defined(__loongarch__) || defined(__riscv) diff --git a/libsanitizer/tsan/tsan_rtl_ppc64.S b/libsanitizer/tsan/tsan_rtl_ppc64.S index 8285e21aa1e..9e533a71a9c 100644 --- a/libsanitizer/tsan/tsan_rtl_ppc64.S +++ b/libsanitizer/tsan/tsan_rtl_ppc64.S @@ -1,5 +1,6 @@ #include "tsan_ppc_regs.h" + .machine altivec .section .text .hidden __tsan_setjmp .globl _setjmp diff --git a/libsanitizer/ubsan/ubsan_flags.cpp b/libsanitizer/ubsan/ubsan_flags.cpp index 25cefd46ce2..9a66bd37518 100644 --- a/libsanitizer/ubsan/ubsan_flags.cpp +++ b/libsanitizer/ubsan/ubsan_flags.cpp @@ -50,6 +50,7 @@ void InitializeFlags() { { CommonFlags cf; cf.CopyFrom(*common_flags()); + cf.print_summary = false; cf.external_symbolizer_path = GetFlag("UBSAN_SYMBOLIZER_PATH"); OverrideCommonFlags(cf); } diff --git a/libsanitizer/ubsan/ubsan_handlers.cpp b/libsanitizer/ubsan/ubsan_handlers.cpp index 410292a0d53..970075e69a6 100644 --- a/libsanitizer/ubsan/ubsan_handlers.cpp +++ b/libsanitizer/ubsan/ubsan_handlers.cpp @@ -894,6 +894,21 @@ void __ubsan_handle_cfi_bad_type(CFICheckFailData *Data, ValueHandle Vtable, } // namespace __ubsan +void __ubsan::__ubsan_handle_cfi_bad_icall(CFIBadIcallData *CallData, + ValueHandle Function) { + GET_REPORT_OPTIONS(false); + CFICheckFailData Data = {CFITCK_ICall, CallData->Loc, CallData->Type}; + handleCFIBadIcall(&Data, Function, Opts); +} + +void __ubsan::__ubsan_handle_cfi_bad_icall_abort(CFIBadIcallData *CallData, + ValueHandle Function) { + GET_REPORT_OPTIONS(true); + CFICheckFailData Data = {CFITCK_ICall, CallData->Loc, CallData->Type}; + handleCFIBadIcall(&Data, Function, Opts); + Die(); +} + void __ubsan::__ubsan_handle_cfi_check_fail(CFICheckFailData *Data, ValueHandle Value, uptr ValidVtable) { diff --git a/libsanitizer/ubsan/ubsan_handlers.h b/libsanitizer/ubsan/ubsan_handlers.h index 219fb15de55..9f412353fc0 100644 --- a/libsanitizer/ubsan/ubsan_handlers.h +++ b/libsanitizer/ubsan/ubsan_handlers.h @@ -215,12 +215,20 @@ enum CFITypeCheckKind : unsigned char { CFITCK_VMFCall, }; +struct CFIBadIcallData { + SourceLocation Loc; + const TypeDescriptor &Type; +}; + struct CFICheckFailData { CFITypeCheckKind CheckKind; SourceLocation Loc; const TypeDescriptor &Type; }; +/// \brief Handle control flow integrity failure for indirect function calls. +RECOVERABLE(cfi_bad_icall, CFIBadIcallData *Data, ValueHandle Function) + /// \brief Handle control flow integrity failures. RECOVERABLE(cfi_check_fail, CFICheckFailData *Data, ValueHandle Function, uptr VtableIsValid) diff --git a/libsanitizer/ubsan/ubsan_platform.h b/libsanitizer/ubsan/ubsan_platform.h index d2cc2e10bd2..ad3e883f0f3 100644 --- a/libsanitizer/ubsan/ubsan_platform.h +++ b/libsanitizer/ubsan/ubsan_platform.h @@ -12,6 +12,7 @@ #ifndef UBSAN_PLATFORM_H #define UBSAN_PLATFORM_H +#ifndef CAN_SANITIZE_UB // Other platforms should be easy to add, and probably work as-is. #if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \ defined(__NetBSD__) || defined(__DragonFly__) || \ @@ -21,5 +22,6 @@ #else # define CAN_SANITIZE_UB 0 #endif +#endif //CAN_SANITIZE_UB #endif -- 2.38.1
0001-libsanitizer-merge-from-upstream-ae59131d3ef311fb4b1.patch.gz
Description: application/gzip