diff --git a/build/bootstrap/fixupobj.com b/build/bootstrap/fixupobj.com index 28bc765a2..4be3dda0d 100755 Binary files a/build/bootstrap/fixupobj.com and b/build/bootstrap/fixupobj.com differ diff --git a/libc/calls/wincrash.c b/libc/calls/wincrash.c index c1a444132..4c9753862 100644 --- a/libc/calls/wincrash.c +++ b/libc/calls/wincrash.c @@ -29,11 +29,11 @@ #include "libc/sysv/consts/sicode.h" #include "libc/sysv/consts/sig.h" -privileged unsigned __wincrash(struct NtExceptionPointers *ep) { +unsigned __wincrash(struct NtExceptionPointers *ep) { int64_t rip; int sig, code; ucontext_t ctx; - STRACE("__wincrash"); + STRACE("__wincrash rip=%lx", ep->ContextRecord->Rip); switch (ep->ExceptionRecord->ExceptionCode) { case kNtSignalBreakpoint: diff --git a/libc/runtime/fork-nt.c b/libc/runtime/fork-nt.c index 5f2735648..761999061 100644 --- a/libc/runtime/fork-nt.c +++ b/libc/runtime/fork-nt.c @@ -88,6 +88,7 @@ static inline textwindows ssize_t ForkIo(int64_t h, char *p, size_t n, static dontinline textwindows bool ForkIo2(int64_t h, void *buf, size_t n, bool32 (*fn)(), const char *sf) { ssize_t rc = ForkIo(h, buf, n, fn); + __tls_enabled = false; // prevent tls crash in kprintf NTTRACE("%s(%ld, %p, %'zu) → %'zd% m", sf, h, buf, n, rc); return rc != -1; } @@ -218,6 +219,9 @@ textwindows void WinMainForked(void) { AbortFork("CloseHandle"); } + // turn tls back on + __enable_tls(); + // rewrap the stdin named pipe hack // since the handles closed on fork struct Fds *fds = VEIL("r", &g_fds); diff --git a/third_party/xed/x86.h b/third_party/xed/x86.h index 6cfe397ef..c506c0b8c 100644 --- a/third_party/xed/x86.h +++ b/third_party/xed/x86.h @@ -27,6 +27,13 @@ #define XED_HINT_TAKEN 4 #define XED_HINT_ALTER 6 +#define XED_SEG_ES 1 +#define XED_SEG_CS 2 +#define XED_SEG_SS 3 +#define XED_SEG_DS 4 +#define XED_SEG_FS 5 +#define XED_SEG_GS 6 + #define xed_modrm_mod(M) (((M)&0xff) >> 6) #define xed_modrm_reg(M) (((M)&0b00111000) >> 3) #define xed_modrm_rm(M) ((M)&7) diff --git a/tool/build/fixupobj.c b/tool/build/fixupobj.c index 0e9e9d777..36f11fb27 100644 --- a/tool/build/fixupobj.c +++ b/tool/build/fixupobj.c @@ -26,6 +26,7 @@ #include "libc/elf/struct/sym.h" #include "libc/errno.h" #include "libc/fmt/itoa.h" +#include "libc/intrin/kprintf.h" #include "libc/intrin/safemacros.internal.h" #include "libc/log/check.h" #include "libc/log/log.h" @@ -36,6 +37,7 @@ #include "libc/sysv/consts/o.h" #include "libc/sysv/consts/prot.h" #include "third_party/getopt/getopt.h" +#include "third_party/xed/x86.h" /** * @fileoverview GCC Codegen Fixer-Upper. @@ -151,6 +153,41 @@ void OptimizeRelocations(Elf64_Ehdr *elf, size_t elfsize) { } } +void CheckForTlsInPrivileged(const char *path, Elf64_Ehdr *elf, + size_t elfsize) { + int err; + size_t m; + Elf64_Half i; + struct Op *op; + Elf64_Shdr *shdr; + unsigned char *p, *e; + Elf64_Xword symcount; + struct XedDecodedInst xedd; + for (i = 0; i < elf->e_shnum; ++i) { + shdr = GetElfSectionHeaderAddress(elf, elfsize, i); + if (shdr->sh_type == SHT_PROGBITS && + startswith(GetElfSectionName(elf, elfsize, shdr), ".privileged")) { + p = (unsigned char *)((uintptr_t)elf + shdr->sh_offset); + e = p + shdr->sh_size; + for (; p < e; p += m) { + xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_LONG_64); + err = xed_instruction_length_decode(&xedd, p, e - p); + if (err == XED_ERROR_NONE) { + m = xedd.length; + if (xedd.op.seg_ovd == XED_SEG_FS) { + kprintf("%s: thread local storage not allowed in privileged " + "functions\n", + path); + exit(1); + } + } else { + m = 1; + } + } + } + } +} + void RewriteObject(const char *path) { int fd; struct stat st; @@ -166,6 +203,7 @@ void RewriteObject(const char *path) { 0)) == MAP_FAILED) { SysExit(__COUNTER__ + 1, "mmap", path); } + CheckForTlsInPrivileged(path, elf, st.st_size); OptimizeRelocations(elf, st.st_size); if (msync(elf, st.st_size, MS_ASYNC | MS_INVALIDATE)) { SysExit(__COUNTER__ + 1, "msync", path);