mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-26 12:30:30 +00:00
Add torture test for zipos file descriptors
This change hardens the code for opening /zip/ files using the system call interface. Thread safety and signal safety has been improved for file descriptors in general. We now document fixed addresses that are needed for low level allocations.
This commit is contained in:
parent
579080cd4c
commit
e466dd0553
44 changed files with 2981 additions and 307 deletions
|
@ -1210,38 +1210,26 @@ void __asan_unregister_globals(struct AsanGlobal g[], int n) {
|
|||
}
|
||||
}
|
||||
|
||||
void __asan_evil(uint8_t *addr, int size, const char *s1, const char *s2) {
|
||||
void __asan_evil(uint8_t *addr, int size, const char *s) {
|
||||
struct AsanTrace tr;
|
||||
__asan_rawtrace(&tr, __builtin_frame_address(0));
|
||||
kprintf(
|
||||
"WARNING: ASAN %s %s bad %d byte %s at %x bt %x %x %x\n",
|
||||
__asan_noreentry == gettid() ? "error during" : "multi-threaded crash",
|
||||
s1, size, s2, addr, tr.p[0], tr.p[1], tr.p[2], tr.p[3]);
|
||||
kprintf("WARNING: ASAN bad %d byte %s at %x bt %x %x %x\n", size, s, addr,
|
||||
tr.p[0], tr.p[1], tr.p[2], tr.p[3]);
|
||||
}
|
||||
|
||||
void __asan_report_load(uint8_t *addr, int size) {
|
||||
if (_lockcmpxchg(&__asan_noreentry, 0, gettid())) {
|
||||
if (!__vforked) {
|
||||
__asan_report_memory_fault(addr, size, "load")();
|
||||
__asan_unreachable();
|
||||
} else {
|
||||
__asan_evil(addr, size, "vfork()", "load");
|
||||
}
|
||||
} else {
|
||||
__asan_evil(addr, size, "ASAN Reporting", "load");
|
||||
__asan_evil(addr, size, "load");
|
||||
if (!__vforked && _lockcmpxchg(&__asan_noreentry, 0, 1)) {
|
||||
__asan_report_memory_fault(addr, size, "load")();
|
||||
__asan_unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
void __asan_report_store(uint8_t *addr, int size) {
|
||||
if (_lockcmpxchg(&__asan_noreentry, 0, gettid())) {
|
||||
if (!__vforked) {
|
||||
__asan_report_memory_fault(addr, size, "store")();
|
||||
__asan_unreachable();
|
||||
} else {
|
||||
__asan_evil(addr, size, "vfork()", "store");
|
||||
}
|
||||
} else {
|
||||
__asan_evil(addr, size, "ASAN reporting", "store");
|
||||
__asan_evil(addr, size, "store");
|
||||
if (!__vforked && _lockcmpxchg(&__asan_noreentry, 0, 1)) {
|
||||
__asan_report_memory_fault(addr, size, "store")();
|
||||
__asan_unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ textstartup void InitializeFileDescriptors(void) {
|
|||
struct Fds *fds;
|
||||
fds = VEIL("r", &g_fds);
|
||||
pushmov(&fds->n, ARRAYLEN(fds->__init_p));
|
||||
fds->f = 3;
|
||||
fds->p = fds->__init_p;
|
||||
if (IsMetal()) {
|
||||
pushmov(&fds->f, 3ull);
|
||||
|
|
|
@ -21,9 +21,8 @@
|
|||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/pthread.h"
|
||||
#include "libc/nexgen32e/gettls.h"
|
||||
#include "libc/linux/futex.h"
|
||||
#include "libc/nexgen32e/threaded.h"
|
||||
#include "libc/sysv/consts/futex.h"
|
||||
|
||||
/**
|
||||
* Locks mutex.
|
||||
|
@ -43,16 +42,15 @@ int pthread_mutex_lock(pthread_mutex_t *mutex) {
|
|||
return EDEADLK;
|
||||
}
|
||||
}
|
||||
atomic_fetch_add(&mutex->waits, +1);
|
||||
if (!IsLinux() ||
|
||||
sys_futex((void *)&mutex->owner, FUTEX_WAIT, owner, 0, 0)) {
|
||||
atomic_fetch_add(&mutex->waits, 1);
|
||||
if (!IsLinux() || LinuxFutexWait((void *)&mutex->owner, owner, 0)) {
|
||||
if (++tries & 7) {
|
||||
__builtin_ia32_pause();
|
||||
} else {
|
||||
sched_yield();
|
||||
}
|
||||
}
|
||||
atomic_fetch_add(&mutex->waits, -1);
|
||||
atomic_fetch_sub(&mutex->waits, 1);
|
||||
}
|
||||
++mutex->reent;
|
||||
return 0;
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/pthread.h"
|
||||
#include "libc/linux/futex.h"
|
||||
#include "libc/nexgen32e/threaded.h"
|
||||
#include "libc/sysv/consts/futex.h"
|
||||
|
||||
/**
|
||||
* Releases mutex.
|
||||
|
@ -38,7 +38,7 @@ int pthread_mutex_unlock(pthread_mutex_t *mutex) {
|
|||
atomic_store_explicit(&mutex->owner, 0, memory_order_relaxed);
|
||||
if (IsLinux() &&
|
||||
atomic_load_explicit(&mutex->waits, memory_order_acquire)) {
|
||||
sys_futex((void *)&mutex->owner, FUTEX_WAKE, 1, 0, 0);
|
||||
LinuxFutexWake(&mutex->owner, 1);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -18,10 +18,11 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
void __releasefd_unlocked(int fd) {
|
||||
if (0 <= fd && fd < g_fds.n) {
|
||||
g_fds.p[fd].kind = 0;
|
||||
bzero(g_fds.p + fd, sizeof(*g_fds.p));
|
||||
g_fds.f = MIN(fd, g_fds.f);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,18 +61,30 @@ privileged void *__initialize_tls(char tib[64]) {
|
|||
* Installs thread information block on main process.
|
||||
*
|
||||
* For example, to set up TLS correctly for the main thread, without
|
||||
* creating any threads using `clone` (which does this automatically),
|
||||
* it is sufficient to say:
|
||||
* creating any threads, then it's sufficient to say:
|
||||
*
|
||||
* __attribute__((__constructor__)) static void InitTls(void) {
|
||||
* static char tls[64];
|
||||
* __initialize_tls(tls);
|
||||
* __threaded = *(int *)(tls + 0x38) = gettid();
|
||||
* *(int *)(tls + 0x38) = gettid();
|
||||
* *(int *)(tls + 0x3c) = __errno;
|
||||
* __install_tls(tls);
|
||||
* }
|
||||
*
|
||||
* Since that'll ensure it happens exactly once.
|
||||
* We use a constructor here to make sure it only happens once. Please
|
||||
* note that calling `clone` will do this automatically.
|
||||
*
|
||||
* Installing TLS causes the `__tls_enabled` variable to be set. This
|
||||
* causes C library features such as `errno` and `gettid()` to use TLS.
|
||||
* This can help things like recursive mutexes go significantly faster.
|
||||
*
|
||||
* To access your TLS storage, you can call `__get_tls()` or
|
||||
* __get_tls_inline()` which return the address of the `tib`.
|
||||
*
|
||||
* @param tib is your thread information block, which must have at least
|
||||
* 64 bytes on the righthand side of the tib pointer since those are
|
||||
* the values your C library reserves for itself. memory on the left
|
||||
* side of the pointer is reserved by the linker for _Thread_local.
|
||||
*/
|
||||
privileged void __install_tls(char tib[64]) {
|
||||
int ax, dx;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue