Delete ASAN

It hasn't been helpful enough to be justify the maintenance burden. What
actually does help is mprotect(), kprintf(), --ftrace and --strace which
can always be counted upon to work correctly. We aren't losing much with
this change. Support for ASAN on AARCH64 was never implemented. Applying
ASAN to the core libc runtimes was disabled many months ago. If there is
some way to have an ASAN runtime for user programs that is less invasive
we can potentially consider reintroducing support. But now is premature.
This commit is contained in:
Justine Tunney 2024-06-22 05:45:49 -07:00
parent 6ffed14b9c
commit d1d4388201
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
198 changed files with 130 additions and 2954 deletions

View file

@ -33,12 +33,6 @@ void SetUpOnce(void) {
ASSERT_SYS(0, 0, pledge("stdio rpath wpath cpath fattr", 0));
}
TEST(access, efault) {
if (IsWindows() || !IsAsan())
return; // not possible
ASSERT_SYS(EFAULT, -1, access((void *)77, F_OK));
}
TEST(access, enoent) {
ASSERT_SYS(ENOENT, -1, access("", F_OK));
ASSERT_SYS(ENOENT, -1, access("doesnotexist", F_OK));

View file

@ -29,9 +29,6 @@ void SetUpOnce(void) {
TEST(chdir, efault) {
ASSERT_SYS(EFAULT, -1, chdir(0));
if (IsWindows() || !IsAsan())
return; // not possible
ASSERT_SYS(EFAULT, -1, chdir((void *)77));
}
TEST(chdir, enoent) {

View file

@ -47,9 +47,6 @@ void SetUpOnce(void) {
TEST(open, efault) {
ASSERT_SYS(EFAULT, -1, open(0, O_RDONLY));
if (IsWindows() || !IsAsan())
return; // not possible
ASSERT_SYS(EFAULT, -1, open((void *)77, O_RDONLY));
}
TEST(open, enoent) {

View file

@ -131,8 +131,6 @@ TEST(setrlimit, testMemoryLimit) {
int i, wstatus;
if (IsXnu())
return;
if (IsAsan())
return; /* b/c we use sys_mmap */
ASSERT_NE(-1, (wstatus = xspawn(0)));
if (wstatus == -2) {
ASSERT_EQ(0, SetKernelEnforcedMemoryLimit(MEM));
@ -162,8 +160,6 @@ TEST(setrlimit, testMemoryLimit) {
TEST(setrlimit, testVirtualMemoryLimit) {
char *p;
int i, wstatus;
if (IsAsan())
return;
if (IsXnu())
return; /* doesn't work on darwin */
if (IsOpenbsd())
@ -194,8 +190,6 @@ TEST(setrlimit, testVirtualMemoryLimit) {
TEST(setrlimit, testDataMemoryLimit) {
char *p;
int i, wstatus;
if (IsAsan())
return;
if (IsXnu())
return; /* doesn't work on darwin */
if (IsNetbsd())

View file

@ -374,7 +374,7 @@ void OnSegfault(int sig) {
}
}
dontubsan dontasan int Segfault(char *p) {
dontubsan int Segfault(char *p) {
return *p;
}

View file

@ -30,9 +30,6 @@ void SetUpOnce(void) {
TEST(unlink, efault) {
ASSERT_SYS(EFAULT, -1, unlink(0));
if (IsWindows() || !IsAsan())
return; // not possible
ASSERT_SYS(EFAULT, -1, unlink((void *)77));
}
TEST(unlink, enoent) {

View file

@ -66,9 +66,6 @@ TEST(write, readOnlyFd_ebadf) {
TEST(write, badMemory_efault) {
ASSERT_SYS(EFAULT, -1, write(1, 0, 1));
if (!IsAsan())
return;
ASSERT_SYS(EFAULT, -1, write(1, (void *)1, 1));
}
TEST(write, brokenPipe_raisesSigpipe) {

View file

@ -96,30 +96,6 @@ TEST(writev, big_fullCompletion) {
EXPECT_NE(-1, close(fd));
}
TEST(writev, asanError_efaults) {
if (!IsAsan())
return;
void *malloc_(size_t) asm("malloc");
void free_(void *) asm("free");
void *p;
int fd;
p = malloc_(32);
EXPECT_NE(-1, (fd = open("asan", O_RDWR | O_CREAT | O_TRUNC, 0644)));
EXPECT_EQ(32, write(fd, p, 32));
EXPECT_NE(-1, lseek(fd, 0, SEEK_SET));
EXPECT_EQ(32, read(fd, p, 32));
EXPECT_EQ(-1, write(fd, p, 33));
EXPECT_EQ(EFAULT, errno);
EXPECT_EQ(-1, write(fd, p, -1));
EXPECT_EQ(EFAULT, errno);
free_(p);
EXPECT_EQ(-1, write(fd, p, 32));
EXPECT_EQ(EFAULT, errno);
EXPECT_EQ(-1, read(fd, p, 32));
EXPECT_EQ(EFAULT, errno);
close(fd);
}
TEST(writev, empty_stillPerformsIoOperation) {
int fd;
struct iovec iov[] = {{"", 0}, {NULL, 0}};

View file

@ -17,7 +17,6 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/mem/gc.h"
#include "libc/mem/mem.h"
#include "libc/stdio/rand.h"
@ -25,10 +24,8 @@
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
static dontasan void *golden(void *p, int c, size_t n) {
static void *golden(void *p, int c, size_t n) {
size_t i;
if (IsAsan())
__asan_verify(p, n);
for (i = 0; i < n; ++i)
((char *)p)[i] = c;
return p;

View file

@ -22,7 +22,6 @@
#include "libc/calls/ucontext.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/atomic.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/safemacros.internal.h"
@ -146,17 +145,6 @@ TEST(mmap, smallerThanPage_mapsRemainder) {
EXPECT_FALSE(testlib_memoryexists(map + (pagesz - 1)));
}
TEST(mmap, smallerThanPage_remainderIsPoisoned) {
if (!IsAsan())
return;
char *map;
ASSERT_NE(MAP_FAILED, (map = mmap(0, 1, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)));
EXPECT_TRUE(__asan_is_valid(map, 1));
EXPECT_FALSE(__asan_is_valid(map + 1, 1));
EXPECT_SYS(0, 0, munmap(map, 1));
}
TEST(mmap, testMapFile) {
int fd;
char *p;

View file

@ -35,10 +35,6 @@ void SetUpOnce(void) {
TEST(munmap, doesntExist_doesntCare) {
EXPECT_SYS(0, 0, munmap(0, granularity * 8));
if (IsAsan()) {
// make sure it didn't unmap the null pointer shadow memory
EXPECT_TRUE(testlib_memoryexists((char *)0x7fff8000));
}
}
TEST(munmap, invalidParams) {
@ -142,38 +138,6 @@ TEST(munmap, memoryGone) {
EXPECT_SYS(0, 0, munmap(p, granularity));
}
TEST(munmap, testTooSmallToUnmapAsan) {
if (!IsAsan())
return;
char *p;
ASSERT_NE(MAP_FAILED, (p = mmap(0, granularity, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)));
EXPECT_TRUE(testlib_memoryexists((char *)(((intptr_t)p >> 3) + 0x7fff8000)));
EXPECT_SYS(0, 0, munmap(p, granularity));
EXPECT_TRUE(testlib_memoryexists((char *)(((intptr_t)p >> 3) + 0x7fff8000)));
}
TEST(munmap, testLargeEnoughToUnmapAsan) {
if (!IsAsan())
return;
if (IsWindows()) {
// we're unfortunately never able to unmap asan pages on windows
// because the memtrack array items always have to be 64kb so we
// we're able to store a handle for each
return;
}
char *p;
size_t n;
n = granularity * 8 * 2;
ASSERT_NE(MAP_FAILED, (p = mmap(0, n, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)));
EXPECT_SYS(0, 0, munmap(p, n));
#if 0
EXPECT_FALSE(
testlib_memoryexists((char *)(((intptr_t)(p + n / 2) >> 3) + 0x7fff8000)));
#endif
}
TEST(munmap, tinyFile_roundupUnmapSize) {
char *p;
ASSERT_SYS(0, 3, open("doge", O_WRONLY | O_CREAT | O_TRUNC, 0644));

View file

@ -21,7 +21,6 @@
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/fmt/conv.h"
#include "libc/intrin/asan.internal.h"
#include "libc/limits.h"
#include "libc/log/libfatal.internal.h"
#include "libc/log/log.h"
@ -86,10 +85,6 @@ TEST(ShowCrashReports, testMemoryLeakCrash) {
ssize_t rc;
int ws, pid, fds[2];
char *output, buf[512];
if (!IsAsan()) {
/* TODO(jart): How can we make this work without ASAN? */
return;
}
ASSERT_NE(-1, pipe2(fds, O_CLOEXEC));
ASSERT_NE(-1, (pid = fork()));
if (!pid) {
@ -254,53 +249,6 @@ TEST(ShowCrashReports, testDivideByZero) {
free(output);
}
// clang-format off
//
// test/libc/log/backtrace_test.c:59: ubsan error: 'int' index 10 into 'char [10]' out of bounds
// 0x000000000040a352: __die at libc/log/die.c:40
// 0x0000000000489bc8: __ubsan_abort at libc/intrin/ubsan.c:196
// 0x0000000000489e1c: __ubsan_handle_out_of_bounds at libc/intrin/ubsan.c:242
// 0x0000000000423666: BssOverrunCrash at test/libc/log/backtrace_test.c:59
// 0x0000000000423e0a: SetUp at test/libc/log/backtrace_test.c:115
// 0x000000000049350b: testlib_runtestcases at libc/testlib/testrunner.c:98
// 0x000000000048ab50: testlib_runalltests at libc/testlib/runner.c:37
// 0x00000000004028d0: main at libc/testlib/testmain.c:94
// 0x0000000000403977: cosmo at libc/runtime/cosmo.S:69
// 0x00000000004021ae: _start at libc/crt/crt.S:78
//
// asan error: global redzone 1-byte store at 0x00000048cf2a shadow 0x0000800899e5
// x
// ........................................OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
// |0 |0 |0 |0 |2 |-6 |-6 |-6 |-6
//                                ☺☻♥♦♣♠•◘○                                        
// 000000400000-000000460000 .text
// 000000460000-000000468000 .data
// 00007fff0000-00008000ffff
// 000080070000-00008009ffff ←shadow
// 02008fff0000-02009001ffff
// 020090060000-02009007ffff
// 0e007ffb0000-0e008000ffff
// 1000286b0000-1000286cffff
// 100080000000-10008009ffff
// 100080350000-10008036ffff
// 100080380000-10008038ffff
// 6fffffe00000-6fffffffffff
// 0x0000000000407af6: __die at libc/log/die.c:36
// 0x0000000000444f13: __asan_die at libc/intrin/asan.c:318
// 0x0000000000445bc8: __asan_report at libc/intrin/asan.c:667
// 0x0000000000445e41: __asan_report_memory_fault at libc/intrin/asan.c:672
// 0x0000000000446312: __asan_report_store at libc/intrin/asan.c:1008
// 0x0000000000444442: __asan_report_store1 at libc/intrin/somanyasan.S:118
// 0x0000000000416216: BssOverrunCrash at test/libc/log/backtrace_test.c:52
// 0x000000000041642a: SetUp at test/libc/log/backtrace_test.c:73
// 0x00000000004513eb: testlib_runtestcases at libc/testlib/testrunner.c:98
// 0x000000000044bbe0: testlib_runalltests at libc/testlib/runner.c:37
// 0x00000000004026db: main at libc/testlib/testmain.c:155
// 0x000000000040323f: cosmo at libc/runtime/cosmo.S:64
// 0x000000000040219b: _start at libc/crt/crt.S:67
//
// clang-format on
TEST(ShowCrashReports, testBssOverrunCrash) {
if (!IsAsan()) return;
size_t got;
@ -348,78 +296,6 @@ TEST(ShowCrashReports, testBssOverrunCrash) {
free(output);
}
// clang-format off
// asan error: null pointer dereference 1-byte load at 0x000000000000 shadow 0x00007fff8000
// x
// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM∅∅∅∅∅∅∅∅∅∅∅∅∅∅∅∅∅∅∅∅∅∅∅∅∅∅∅∅∅∅∅∅∅∅∅∅∅∅∅∅
// |-17 |-17 |-17 |-17 |-17 |-1 |-1 |-1 |-1 |-1
// ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
// 000000400000-000000464000 .text
// 000000464000-00000046d000 .data
// 00007fff0000-00008000ffff ←shadow
// 000080070000-00008009ffff
// 02008fff0000-02009001ffff
// 020090060000-02009007ffff
// 0e007fff0000-0e008000ffff
// 10000d3e0000-10000d3fffff
// 100080000000-10008009ffff
// 100080370000-10008038ffff
// 1000803a0000-1000803affff
// 6ffffffe0000-6fffffffffff
// 0x0000000000407c84: __die at libc/log/die.c:37
// 0x000000000040b1ee: __asan_report_load at libc/intrin/asan.c:1083
// 0x000000000041639e: NpeCrash at test/libc/log/backtrace_test.c:87
// 0x0000000000416733: SetUp at test/libc/log/backtrace_test.c:120
// 0x00000000004541fb: testlib_runtestcases at libc/testlib/testrunner.c:98
// 0x000000000044d000: testlib_runalltests at libc/testlib/runner.c:37
// 0x00000000004026db: main at libc/testlib/testmain.c:94
// 0x000000000040327f: cosmo at libc/runtime/cosmo.S:64
// 0x000000000040219b: _start at libc/crt/crt.S:67
// clang-format on
TEST(ShowCrashReports, testNpeCrash) {
if (!IsAsan()) return;
size_t got;
ssize_t rc;
int ws, pid, fds[2];
char *output, buf[512];
ASSERT_NE(-1, pipe2(fds, O_CLOEXEC));
ASSERT_NE(-1, (pid = fork()));
if (!pid) {
dup2(fds[1], 1);
dup2(fds[1], 2);
execv("bin/backtrace", (char *const[]){"bin/backtrace", "7", 0});
_Exit(127);
}
close(fds[1]);
output = 0;
appends(&output, "");
for (;;) {
rc = read(fds[0], buf, sizeof(buf));
if (rc == -1) {
ASSERT_EQ(EINTR, errno);
continue;
}
if ((got = rc)) {
appendd(&output, buf, got);
} else {
break;
}
}
close(fds[0]);
ASSERT_NE(-1, wait(&ws));
// tinyprint(2, gc(IndentLines(output, -1, 0, 4)), "\n", NULL);
EXPECT_EQ(77 << 8, ws);
/* NULL is stopgap until we can copy symbol tables into binary */
ASSERT_TRUE(!!strstr(output, "null pointer"));
#ifdef __FNO_OMIT_FRAME_POINTER__
ASSERT_TRUE(OutputHasSymbol(output, "NpeCrash"));
#endif
if (!strstr(output, "null pointer access")) { // ubsan
ASSERT_TRUE(!!strstr(output, "∅∅∅∅")); // asan
}
free(output);
}
TEST(ShowCrashReports, testDataOverrunCrash) {
if (!IsAsan()) return;
size_t got;

View file

@ -21,7 +21,6 @@
#include "libc/calls/struct/timespec.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/cxaatexit.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/safemacros.internal.h"
@ -50,46 +49,26 @@
TEST(malloc, zero) {
char *p;
ASSERT_NE(NULL, (p = malloc(0)));
if (IsAsan())
ASSERT_FALSE(__asan_is_valid(p, 1));
free(p);
}
TEST(realloc, bothAreZero_createsMinimalAllocation) {
char *p;
ASSERT_NE(NULL, (p = realloc(0, 0)));
if (IsAsan())
ASSERT_FALSE(__asan_is_valid(p, 1));
free(p);
}
TEST(realloc, ptrIsZero_createsAllocation) {
char *p;
ASSERT_NE(NULL, (p = realloc(0, 1)));
if (IsAsan())
ASSERT_TRUE(__asan_is_valid(p, 1));
if (IsAsan())
ASSERT_FALSE(__asan_is_valid(p + 1, 1));
ASSERT_EQ(p, realloc(p, 0));
if (IsAsan())
ASSERT_FALSE(__asan_is_valid(p, 1));
if (IsAsan())
ASSERT_FALSE(__asan_is_valid(p + 1, 1));
free(p);
}
TEST(realloc, sizeIsZero_shrinksAllocation) {
char *p;
ASSERT_NE(NULL, (p = malloc(1)));
if (IsAsan())
ASSERT_TRUE(__asan_is_valid(p, 1));
if (IsAsan())
ASSERT_FALSE(__asan_is_valid(p + 1, 1));
ASSERT_EQ(p, realloc(p, 0));
if (IsAsan())
ASSERT_FALSE(__asan_is_valid(p, 1));
if (IsAsan())
ASSERT_FALSE(__asan_is_valid(p + 1, 1));
free(p);
}

View file

@ -18,7 +18,6 @@
*/
#include "libc/thread/tls.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/testlib/testlib.h"
#include "libc/thread/thread.h"
@ -35,9 +34,6 @@ dontubsan void *Worker(void *arg) {
ASSERT_EQ(0, (uintptr_t)&a & (_Alignof(a) - 1));
ASSERT_EQ(42, x + y[0] + z);
ASSERT_EQ(0, (intptr_t)&a & (A - 1));
if (IsAsan()) {
ASSERT_EQ(kAsanProtected, __asan_check(y + 1, sizeof(long)).kind);
}
return 0;
}
@ -53,8 +49,4 @@ TEST(tls, test) {
ASSERT_EQ(0, (intptr_t)&a & (A - 1));
ASSERT_EQ(0, pthread_create(&t, 0, Worker, 0));
ASSERT_EQ(0, pthread_join(t, 0));
if (IsAsan()) {
// TODO(jart): Why isn't it poisoned?
// ASSERT_EQ(kAsanProtected, __asan_check(y + 1, sizeof(long)).kind);
}
}

View file

@ -19,7 +19,6 @@
#include "libc/calls/calls.h"
#include "libc/calls/struct/stat.h"
#include "libc/errno.h"
#include "libc/intrin/asan.internal.h"
#include "libc/limits.h"
#include "libc/mem/gc.h"
#include "libc/mem/mem.h"

View file

@ -60,9 +60,6 @@ void SetUp(void) {
TEST(opendir, efault) {
ASSERT_SYS(EFAULT, NULL, opendir(0));
if (!IsAsan())
return; // not possible
ASSERT_SYS(EFAULT, NULL, opendir((void *)77));
}
TEST(opendir, enoent) {

View file

@ -19,7 +19,6 @@
#include "libc/assert.h"
#include "libc/calls/struct/timespec.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/mem/gc.h"
#include "libc/mem/mem.h"
#include "libc/nexgen32e/crc32.h"

View file

@ -76,7 +76,7 @@ TEST(makecontext, args) {
EXPECT_TRUE(gotsome);
}
dontasan dontubsan void itsatrap(int x, int y) {
dontubsan void itsatrap(int x, int y) {
*(int *)(intptr_t)x = scalbn(x, y);
}