Eliminate some flakes

- Get ASAN working on Windows.

- Deleting directories and then recreating them with the same name in a
  short period of time appears to be a no-no on Windows.

- There's no reason to call FlushFileBuffers on close() for pipes, and
  it's harmful since it might block indefinitely for no good reason.
This commit is contained in:
Justine Tunney
2021-02-03 06:22:51 -08:00
parent 27c899af56
commit 4e56d89dcd
60 changed files with 588 additions and 751 deletions

View File

@@ -20,17 +20,19 @@
#include "libc/bits/bits.h"
#include "libc/bits/weaken.h"
#include "libc/calls/calls.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/linux/exit.h"
#include "libc/linux/write.h"
#include "libc/log/log.h"
#include "libc/macros.h"
#include "libc/mem/hook/hook.h"
#include "libc/nt/enum/version.h"
#include "libc/nt/runtime.h"
#include "libc/runtime/directmap.h"
#include "libc/runtime/memtrack.h"
#include "libc/runtime/runtime.h"
#include "libc/sysv/consts/auxv.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/nr.h"
#include "libc/sysv/consts/prot.h"
#include "third_party/dlmalloc/dlmalloc.internal.h"
@@ -409,29 +411,40 @@ static const char *__asan_describe_access_poison(char *p) {
}
}
static textsyscall wontreturn void __asan_exit(int rc) {
if (!IsWindows()) {
asm volatile("syscall"
: /* no outputs */
: "a"(__NR_exit_group), "D"(rc)
: "memory");
unreachable;
} else {
ExitProcess(rc);
}
}
static textsyscall ssize_t __asan_write(const void *data, size_t size) {
ssize_t rc;
if (weaken(write)) {
if ((rc = weaken(write)(2, data, size)) != -1) {
return rc;
uint32_t wrote;
if (!IsWindows()) {
asm volatile("syscall"
: "=a"(rc)
: "0"(__NR_write), "D"(2), "S"(data), "d"(size)
: "rcx", "r11", "memory");
return rc;
} else {
if (WriteFile(GetStdHandle(kNtStdErrorHandle), data, size, &wrote, 0)) {
return wrote;
} else {
return -1;
}
}
return LinuxWrite(2, data, size);
}
static ssize_t __asan_write_string(const char *s) {
return __asan_write(s, __asan_strlen(s));
}
static textsyscall wontreturn void __asan_exit(int rc) {
if (weaken(_Exit)) {
weaken(_Exit)(rc);
} else {
LinuxExit(rc);
}
for (;;) asm("hlt");
}
static wontreturn void __asan_abort(void) {
if (weaken(__die)) weaken(__die)();
if (weaken(abort)) weaken(abort)();
@@ -640,7 +653,9 @@ void __asan_stack_free(char *p, size_t size, int classid) {
__asan_deallocate(p, kAsanStackFree);
}
void __asan_handle_no_return_impl(uintptr_t rsp) {
void __asan_handle_no_return(void) {
uintptr_t rsp;
rsp = (uintptr_t)__builtin_frame_address(0);
__asan_unpoison(rsp, ROUNDUP(rsp, STACKSIZE) - rsp);
}
@@ -660,11 +675,11 @@ void __asan_unregister_globals(struct AsanGlobal g[], int n) {
}
}
void __asan_report_load_impl(uint8_t *addr, int size) {
void __asan_report_load(uint8_t *addr, int size) {
__asan_report_memory_fault(addr, size, "load");
}
void __asan_report_store_impl(uint8_t *addr, int size) {
void __asan_report_store(uint8_t *addr, int size) {
__asan_report_memory_fault(addr, size, "store");
}
@@ -790,6 +805,10 @@ textstartup void __asan_init(int argc, char **argv, char **envp,
intptr_t *auxv) {
static bool once;
if (!cmpxchg(&once, false, true)) return;
if (IsWindows() && NtGetVersion() < kNtVersionWindows10) {
__asan_write_string("error: asan binaries require windows10\n");
__asan_exit(0); /* So `make MODE=dbg test` passes w/ Windows7 */
}
REQUIRE(_mmi);
REQUIRE(__mmap);
REQUIRE(MAP_ANONYMOUS);

View File

@@ -25,7 +25,9 @@ LIBC_INTRIN_A_CHECKS = \
LIBC_INTRIN_A_DIRECTDEPS = \
LIBC_STUBS \
LIBC_NEXGEN32E
LIBC_SYSV \
LIBC_NEXGEN32E \
LIBC_NT_KERNEL32
LIBC_INTRIN_A_DEPS := \
$(call uniq,$(foreach x,$(LIBC_INTRIN_A_DIRECTDEPS),$($(x))))

View File

@@ -0,0 +1,24 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2021 Justine Alexandra Roberts Tunney │
│ │
│ Permission to use, copy, modify, and/or distribute this software for │
│ any purpose with or without fee is hereby granted, provided that the │
│ above copyright notice and this permission notice appear in all copies. │
│ │
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/nt/struct/teb.h"
#include "libc/runtime/runtime.h"
textwindows noasan int NtGetVersion(void) {
return (NtGetPeb()->OSMajorVersion & 0xff) << 8 | NtGetPeb()->OSMinorVersion;
}

View File

@@ -25,6 +25,18 @@
/ since ASAN has the same stylistic hugeness as UBSAN.
/ We also guard all the functions, against reentrancy.
.rodata.cst4
__asan_option_detect_stack_use_after_return:
.long 0
.endobj __asan_option_detect_stack_use_after_return,globl
.previous
.bss
__asan_noreentry:
.byte 0
.endobj __asan_noreentry
.previous
__asan_report_load1:
push $1
jmp OnReportLoad
@@ -43,14 +55,18 @@ __asan_report_load8:
.endfn __asan_report_load8,globl
__asan_report_load16:
push $16
/ 𝑠𝑙𝑖𝑑𝑒
jmp OnReportLoad
.endfn __asan_report_load16,globl
__asan_report_load32:
push $32
/ 𝑠𝑙𝑖𝑑𝑒
.endfn __asan_report_load32,globl
OnReportLoad:
pop %rsi
/ 𝑠𝑙𝑖𝑑𝑒
.endfn OnReportLoad
__asan_report_load_n:
lea __asan_report_load_impl(%rip),%r11
lea __asan_report_load(%rip),%r11
jmp __asan_report_noreentry
.endfn __asan_report_load_n,globl
@@ -83,7 +99,7 @@ ReportStore:
/ 𝑠𝑙𝑖𝑑𝑒
.endfn ReportStore
__asan_report_store_n:
lea __asan_report_store_impl(%rip),%r11
lea __asan_report_store(%rip),%r11
/ 𝑠𝑙𝑖𝑑𝑒
.endfn __asan_report_store_n,globl
@@ -198,31 +214,6 @@ OnStackMalloc:
jmp __asan_stack_malloc
.endfn OnStackMalloc
__asan_handle_no_return:
push %rbp
mov %rsp,%rbp
lea 8(%rsp),%rdi
call __asan_handle_no_return_impl
pop %rbp
ret
.endfn __asan_handle_no_return,globl
__asan_before_dynamic_init:
push %rbp
mov %rsp,%rbp
ud2
pop %rbp
ret
.endfn __asan_before_dynamic_init,globl
__asan_after_dynamic_init:
push %rbp
mov %rsp,%rbp
ud2
pop %rbp
ret
.endfn __asan_after_dynamic_init,globl
__asan_version_mismatch_check_v8:
ret
.endfn __asan_version_mismatch_check_v8,globl
@@ -240,14 +231,76 @@ __asan_version_mismatch_check_v8:
pop %rdi
.init.end 301,_init_asan
.rodata.cst4
__asan_option_detect_stack_use_after_return:
.long 0
.endobj __asan_option_detect_stack_use_after_return,globl
.previous
__asan_before_dynamic_init:
push %rbp
mov %rsp,%rbp
ud2
.endfn __asan_before_dynamic_init,globl
.bss
__asan_noreentry:
.byte 0
.endobj __asan_noreentry
.previous
__asan_after_dynamic_init:
push %rbp
mov %rsp,%rbp
ud2
.endfn __asan_after_dynamic_init,globl
__asan_load1:
push %rbp
mov %rsp,%rbp
ud2
.endfn __asan_load1,globl
__asan_load2:
push %rbp
mov %rsp,%rbp
ud2
.endfn __asan_load2,globl
__asan_load4:
push %rbp
mov %rsp,%rbp
ud2
.endfn __asan_load4,globl
__asan_load8:
push %rbp
mov %rsp,%rbp
ud2
.endfn __asan_load8,globl
__asan_load16:
push %rbp
mov %rsp,%rbp
ud2
.endfn __asan_load16,globl
__asan_load32:
push %rbp
mov %rsp,%rbp
ud2
.endfn __asan_load32,globl
__asan_store1:
push %rbp
mov %rsp,%rbp
ud2
.endfn __asan_store1,globl
__asan_store2:
push %rbp
mov %rsp,%rbp
ud2
.endfn __asan_store2,globl
__asan_store4:
push %rbp
mov %rsp,%rbp
ud2
.endfn __asan_store4,globl
__asan_store8:
push %rbp
mov %rsp,%rbp
ud2
.endfn __asan_store8,globl
__asan_store16:
push %rbp
mov %rsp,%rbp
ud2
.endfn __asan_store16,globl
__asan_store32:
push %rbp
mov %rsp,%rbp
ud2
.endfn __asan_store32,globl