From 9f149e1de3cb42cb58cfa39ed2b307c7efdb7c58 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sat, 6 Feb 2021 03:17:41 -0800 Subject: [PATCH] Elevate .text.syscall to .privileged It turns out adding OpenBSD msyscall() origin verification broke the --ftrace flag. The executable needs to issue raw syscalls while it's rewriting itself. So they need to be in the same section, and that's just plain simpler too. --- ape/ape.lds | 10 ++++------ examples/tiny-raw-linux-tutorial.S | 2 +- libc/calls/mprotect.greg.c | 2 +- libc/calls/netbsdtramp.S | 2 +- libc/elf/elf.lds | 10 ++++------ libc/integral/c.inc | 1 - libc/intrin/asan.c | 4 ++-- libc/macros.internal.inc | 3 --- libc/runtime/abort.S | 2 +- libc/runtime/arch_prctl.c | 4 ++-- libc/runtime/assertfail.c | 6 +++--- libc/runtime/exit3.S | 2 +- libc/runtime/print.greg.c | 2 +- libc/runtime/stackchkfail.c | 2 +- libc/runtime/vfork.S | 2 +- libc/sysv/restorert.S | 2 +- libc/sysv/systemfive.S | 10 +++++----- third_party/gcc/unbundle.sh | 1 + tool/emacs/cosmo-c-keywords.el | 1 - 19 files changed, 30 insertions(+), 38 deletions(-) diff --git a/ape/ape.lds b/ape/ape.lds index bb9c51876..f81165bb1 100644 --- a/ape/ape.lds +++ b/ape/ape.lds @@ -283,9 +283,6 @@ SECTIONS { KEEP(*(.textwindowsepilogue)) *(SORT_BY_ALIGNMENT(.text.modernity)) *(SORT_BY_ALIGNMENT(.text.modernity.*)) - HIDDEN(__text_syscall_start = .); - *(.text.syscall .text.syscall.*) - HIDDEN(__text_syscall_end = .); *(SORT_BY_ALIGNMENT(.text.hot)) *(SORT_BY_ALIGNMENT(.text.hot.*)) KEEP(*(.keep.text)) @@ -309,6 +306,7 @@ SECTIONS { HIDDEN(__test_end = .); . += 1; *(.privileged) + HIDDEN(__privileged_end = .); /*BEGIN: Read Only Data */ @@ -487,9 +485,9 @@ SHSTUB2(.Lape.macho.dd.skip, RVA(ape.macho) / 8); SHSTUB2(.Lape.macho.dd.count, (.Lape.macho.end - ape.macho) / 8); PFSTUB4(.Lape.pe.offset, ape.pe - ape.mz); -HIDDEN(__text_syscall_addr = ROUNDDOWN(__text_syscall_start, PAGESIZE)); -HIDDEN(__text_syscall_size = (ROUNDUP(__text_syscall_end, PAGESIZE) - - ROUNDDOWN(__text_syscall_start, PAGESIZE))); +HIDDEN(__privileged_addr = ROUNDDOWN(__privileged_start, PAGESIZE)); +HIDDEN(__privileged_size = (ROUNDUP(__privileged_end, PAGESIZE) - + ROUNDDOWN(__privileged_start, PAGESIZE))); HIDDEN(.Lape.pe.optsz = .Lape.pe.sections - (ape.pe + 24)); HIDDEN(.Lape.pe.shnum = (.Lape.pe.sections_end - .Lape.pe.sections) / 40); diff --git a/examples/tiny-raw-linux-tutorial.S b/examples/tiny-raw-linux-tutorial.S index 2ae9f035e..9ad07f149 100644 --- a/examples/tiny-raw-linux-tutorial.S +++ b/examples/tiny-raw-linux-tutorial.S @@ -17,7 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.h" -.text.syscall +.privileged / Tiny Raw Linux Binary Tutorial / diff --git a/libc/calls/mprotect.greg.c b/libc/calls/mprotect.greg.c index c2a755d90..f2ff0b7fc 100644 --- a/libc/calls/mprotect.greg.c +++ b/libc/calls/mprotect.greg.c @@ -34,7 +34,7 @@ extern __msabi typeof(VirtualProtect) *const __imp_VirtualProtect; * @return 0 on success, or -1 w/ errno * @see mmap() */ -textsyscall int mprotect(void *addr, uint64_t len, int prot) { +privileged int mprotect(void *addr, uint64_t len, int prot) { bool cf; int64_t rc; uint32_t oldprot; diff --git a/libc/calls/netbsdtramp.S b/libc/calls/netbsdtramp.S index 572b3807b..80211c8b4 100644 --- a/libc/calls/netbsdtramp.S +++ b/libc/calls/netbsdtramp.S @@ -17,7 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.h" -.text.syscall +.privileged __restore_rt_netbsd: mov %r15,%rdi diff --git a/libc/elf/elf.lds b/libc/elf/elf.lds index 87e553221..a934ef115 100644 --- a/libc/elf/elf.lds +++ b/libc/elf/elf.lds @@ -67,9 +67,6 @@ SECTIONS { .text : { *(SORT_BY_ALIGNMENT(.text.hot)) KEEP(*(.keep.text)) - HIDDEN(__text_syscall_start = .); - *(.text.syscall .text.syscall.*) - HIDDEN(__text_syscall_end = .); *(.text .text.*) KEEP(*(SORT_BY_NAME(.sort.text.*))) } @@ -84,6 +81,7 @@ SECTIONS { . = ALIGN(DEFINED(ftrace_init) ? PAGESIZE : 1); HIDDEN(__privileged_start = .); *(.privileged) + HIDDEN(__privileged_end = .); } .rodata : { @@ -212,6 +210,6 @@ SECTIONS { } } -HIDDEN(__text_syscall_addr = ROUNDDOWN(__text_syscall_start, PAGESIZE)); -HIDDEN(__text_syscall_size = (ROUNDUP(__text_syscall_end, PAGESIZE) - - ROUNDDOWN(__text_syscall_start, PAGESIZE))); +HIDDEN(__privileged_addr = ROUNDDOWN(__privileged_start, PAGESIZE)); +HIDDEN(__privileged_size = (ROUNDUP(__privileged_end, PAGESIZE) - + ROUNDDOWN(__privileged_start, PAGESIZE))); diff --git a/libc/integral/c.inc b/libc/integral/c.inc index b4347d57a..cb520b943 100644 --- a/libc/integral/c.inc +++ b/libc/integral/c.inc @@ -620,7 +620,6 @@ typedef uint64_t uintmax_t; #define textexit _Section(".text.exit") noinstrument #define textreal _Section(".text.real") #define textwindows _Section(".text.windows") -#define textsyscall _Section(".text.syscall") noinline #define antiquity _Section(".text.antiquity") #else #define testonly diff --git a/libc/intrin/asan.c b/libc/intrin/asan.c index d36b744a9..48c539ee9 100644 --- a/libc/intrin/asan.c +++ b/libc/intrin/asan.c @@ -411,7 +411,7 @@ static const char *__asan_describe_access_poison(char *p) { } } -static textsyscall wontreturn void __asan_exit(int rc) { +static privileged noinline wontreturn void __asan_exit(int rc) { if (!IsWindows()) { asm volatile("syscall" : /* no outputs */ @@ -423,7 +423,7 @@ static textsyscall wontreturn void __asan_exit(int rc) { } } -static textsyscall ssize_t __asan_write(const void *data, size_t size) { +static privileged noinline ssize_t __asan_write(const void *data, size_t size) { ssize_t rc; uint32_t wrote; if (!IsWindows()) { diff --git a/libc/macros.internal.inc b/libc/macros.internal.inc index 90c5aac7d..26a333f32 100644 --- a/libc/macros.internal.inc +++ b/libc/macros.internal.inc @@ -33,9 +33,6 @@ .macro .text.exit .section .text.exit,"ax",@progbits .endm -.macro .text.syscall - .section .text.syscall,"ax",@progbits -.endm .macro .firstclass .section .text.hot,"ax",@progbits .endm diff --git a/libc/runtime/abort.S b/libc/runtime/abort.S index d43631663..3acfb998e 100644 --- a/libc/runtime/abort.S +++ b/libc/runtime/abort.S @@ -21,7 +21,7 @@ #include "libc/sysv/consts/sig.h" #include "libc/sysv/consts/nr.h" #include "libc/macros.h" -.text.syscall +.privileged .source __FILE__ / Terminates program abnormally. diff --git a/libc/runtime/arch_prctl.c b/libc/runtime/arch_prctl.c index 42df89147..4dfa5bbb5 100644 --- a/libc/runtime/arch_prctl.c +++ b/libc/runtime/arch_prctl.c @@ -111,7 +111,7 @@ static int arch_prctl_freebsd(int code, int64_t addr) { } } -static textsyscall int arch_prctl_xnu(int code, int64_t addr) { +static privileged noinline int arch_prctl_xnu(int code, int64_t addr) { int ax; switch (code) { case ARCH_SET_GS: @@ -129,7 +129,7 @@ static textsyscall int arch_prctl_xnu(int code, int64_t addr) { } } -static textsyscall int arch_prctl_openbsd(int code, int64_t addr) { +static privileged noinline int arch_prctl_openbsd(int code, int64_t addr) { int64_t rax; switch (code) { case ARCH_GET_FS: diff --git a/libc/runtime/assertfail.c b/libc/runtime/assertfail.c index 215f1ece5..319c3b9e3 100644 --- a/libc/runtime/assertfail.c +++ b/libc/runtime/assertfail.c @@ -41,7 +41,7 @@ static noasan char *__assert_stpcpy(char *d, const char *s) { } } -static textsyscall noasan wontreturn void __assert_exit(int rc) { +static privileged noinline noasan wontreturn void __assert_exit(int rc) { if (!IsWindows()) { asm volatile("syscall" : /* no outputs */ @@ -53,8 +53,8 @@ static textsyscall noasan wontreturn void __assert_exit(int rc) { } } -static textsyscall noasan ssize_t __assert_write(const void *data, - size_t size) { +static privileged noinline noasan ssize_t __assert_write(const void *data, + size_t size) { ssize_t rc; uint32_t wrote; if (!IsWindows()) { diff --git a/libc/runtime/exit3.S b/libc/runtime/exit3.S index 421977f67..5b12aa34e 100644 --- a/libc/runtime/exit3.S +++ b/libc/runtime/exit3.S @@ -19,7 +19,7 @@ #include "libc/dce.h" #include "libc/runtime/internal.h" #include "libc/macros.h" -.text.syscall +.privileged .source __FILE__ / Terminates process, ignoring destructors and atexit() handlers. diff --git a/libc/runtime/print.greg.c b/libc/runtime/print.greg.c index 469a152a2..2b9dc0ee3 100644 --- a/libc/runtime/print.greg.c +++ b/libc/runtime/print.greg.c @@ -48,7 +48,7 @@ static void __sys_print_nt(const void *data, size_t len) { * @param len can be computed w/ tinystrlen() * @clob nothing except flags */ -textsyscall void __print(const void *data, size_t len) { +privileged noinline void __print(const void *data, size_t len) { int64_t ax, ordinal; if (WasImported(__imp_WriteFile)) { __sys_print_nt(data, len); diff --git a/libc/runtime/stackchkfail.c b/libc/runtime/stackchkfail.c index 48f245a81..1d1901750 100644 --- a/libc/runtime/stackchkfail.c +++ b/libc/runtime/stackchkfail.c @@ -28,7 +28,7 @@ /** * Aborts program under enemy fire to avoid being taken alive. */ -textsyscall noasan void __stack_chk_fail(void) { +privileged noasan void __stack_chk_fail(void) { size_t len; const char *msg; int64_t ax, cx, si; diff --git a/libc/runtime/vfork.S b/libc/runtime/vfork.S index 5d66a9e7d..61dcf99b3 100644 --- a/libc/runtime/vfork.S +++ b/libc/runtime/vfork.S @@ -18,7 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/dce.h" #include "libc/macros.h" -.text.syscall +.privileged / Forks process without copying page tables. / diff --git a/libc/sysv/restorert.S b/libc/sysv/restorert.S index 299bbb6b2..c1eafdcae 100644 --- a/libc/sysv/restorert.S +++ b/libc/sysv/restorert.S @@ -17,7 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.h" -.text.syscall +.privileged .source __FILE__ / Linux Signal Trampoline (HOLY CODE) diff --git a/libc/sysv/systemfive.S b/libc/sysv/systemfive.S index abbe0ebc4..492f89214 100644 --- a/libc/sysv/systemfive.S +++ b/libc/sysv/systemfive.S @@ -103,7 +103,7 @@ __systemfive: .endobj __systemfive,globl,hidden .previous - .text.syscall + .privileged .Lanchorpoint: systemfive.linux: and $0xfff,%eax @@ -332,10 +332,10 @@ systemfive.init.syscall: js systemfive.init.done push %rdi push %rsi - .weak __text_syscall_addr - .weak __text_syscall_size - mov $__text_syscall_addr,%edi - mov $__text_syscall_size,%esi + .weak __privileged_addr + .weak __privileged_size + mov $__privileged_addr,%edi + mov $__privileged_size,%esi syscall pop %rsi pop %rdi diff --git a/third_party/gcc/unbundle.sh b/third_party/gcc/unbundle.sh index a819d47d4..77bfb0168 100755 --- a/third_party/gcc/unbundle.sh +++ b/third_party/gcc/unbundle.sh @@ -1,3 +1,4 @@ +#!/bin/sh #-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ #───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ mkdir -p o/third_party diff --git a/tool/emacs/cosmo-c-keywords.el b/tool/emacs/cosmo-c-keywords.el index ad8a5243e..1af8f1ca3 100644 --- a/tool/emacs/cosmo-c-keywords.el +++ b/tool/emacs/cosmo-c-keywords.el @@ -176,7 +176,6 @@ "interruptfn" "nocallback" "textstartup" - "textsyscall" "warnifused" "attributeallocsize" "attributeallocalign"