From dd04aeba1cf22632a1042298cfdd59688f10a50e Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sun, 18 Dec 2022 22:58:29 -0800 Subject: [PATCH] Increase stack size to 128k and guard size to 16k This improves our compatibility with Apple M1. --- libc/calls/calls.mk | 11 +------- libc/calls/readlinkat-nt.c | 3 ++- libc/integral/c.inc | 40 ++++++++++++++--------------- libc/integral/normalize.inc | 3 ++- libc/intrin/asan.c | 4 +-- libc/intrin/extend.c | 1 + libc/log/oncrash.c | 2 +- libc/mem/balloc.c | 2 +- libc/runtime/clone-linux.S | 5 ++++ libc/runtime/clone.c | 1 + libc/runtime/mmap.c | 8 +++--- libc/runtime/stack.h | 2 +- libc/str/memmem.c | 2 +- libc/str/str.mk | 4 --- libc/thread/pthread_attr_init.c | 2 +- libc/thread/pthread_create.c | 6 ++--- net/turfwar/turfwar.c | 13 ++++++---- test/libc/calls/setrlimit_test.c | 18 ++++++------- test/libc/intrin/kprintf_test.c | 6 ++--- test/libc/intrin/popcnt_test.c | 4 +-- test/libc/runtime/brk_test.c | 14 +++++----- test/libc/runtime/mprotect_test.c | 32 +++++++++++------------ third_party/dlmalloc/init.inc | 4 +-- third_party/lua/lua.mk | 4 --- third_party/lua/luaencodejsondata.c | 4 +-- third_party/lua/luaencodeluadata.c | 2 +- third_party/make/make.mk | 2 +- third_party/mbedtls/test/test.mk | 4 --- third_party/quickjs/quickjs.mk | 4 --- third_party/quickjs/unicode_gen.c | 2 +- third_party/stb/stb.mk | 2 +- third_party/zip/zip.mk | 7 ----- third_party/zip/zipup.c | 3 +++ tool/emacs/cosmo-cpp-constants.el | 1 + tool/net/ljson.c | 2 +- tool/viz/life.c | 10 ++++---- 36 files changed, 109 insertions(+), 125 deletions(-) diff --git a/libc/calls/calls.mk b/libc/calls/calls.mk index eae3c1fac..51d5fb2e7 100644 --- a/libc/calls/calls.mk +++ b/libc/calls/calls.mk @@ -121,21 +121,12 @@ o/$(MODE)/libc/calls/execlp.o \ o/$(MODE)/libc/calls/statfs.o \ o/$(MODE)/libc/calls/fstatfs.o \ o/$(MODE)/libc/calls/execve-sysv.o \ +o/$(MODE)/libc/calls/readlinkat-nt.o \ o/$(MODE)/libc/calls/execve-nt.greg.o \ o/$(MODE)/libc/calls/mkntenvblock.o: private \ OVERRIDE_CPPFLAGS += \ -DSTACK_FRAME_UNLIMITED -# we must disable static stack safety because: -# PATH_MAX*sizeof(char16_t)*2 exceeds 4096 byte frame limit -o/$(MODE)/libc/calls/copyfile.o \ -o/$(MODE)/libc/calls/symlinkat-nt.o \ -o/$(MODE)/libc/calls/readlinkat-nt.o \ -o/$(MODE)/libc/calls/linkat-nt.o \ -o/$(MODE)/libc/calls/renameat-nt.o: private \ - OVERRIDE_CPPFLAGS += \ - -DSTACK_FRAME_UNLIMITED - # we must segregate codegen because: # file contains multiple independently linkable apis o/$(MODE)/libc/calls/ioctl-siocgifconf.o \ diff --git a/libc/calls/readlinkat-nt.c b/libc/calls/readlinkat-nt.c index 204567b30..67589f02a 100644 --- a/libc/calls/readlinkat-nt.c +++ b/libc/calls/readlinkat-nt.c @@ -28,6 +28,7 @@ #include "libc/nt/files.h" #include "libc/nt/runtime.h" #include "libc/nt/struct/reparsedatabuffer.h" +#include "libc/runtime/stack.h" #include "libc/str/str.h" #include "libc/str/utf16.h" #include "libc/sysv/errfuns.h" @@ -45,7 +46,7 @@ textwindows ssize_t sys_readlinkat_nt(int dirfd, const char *path, char *buf, if (__mkntpathat(dirfd, path, 0, path16) == -1) return -1; mem = 16384; memory = alloca(mem); - for (i = 0; i < mem; i += PAGESIZE) memory[i] = 0; + CheckLargeStackAllocation(memory, mem); rdb = (struct NtReparseDataBuffer *)memory; if ((h = CreateFile(path16, 0, 0, 0, kNtOpenExisting, kNtFileFlagOpenReparsePoint | kNtFileFlagBackupSemantics, diff --git a/libc/integral/c.inc b/libc/integral/c.inc index 308033202..15e9e350b 100644 --- a/libc/integral/c.inc +++ b/libc/integral/c.inc @@ -151,7 +151,7 @@ typedef struct { #define memcpyesque libcesque #define strlenesque libcesque nosideeffect paramsnonnull() #define vallocesque \ - libcesque dontdiscard returnsaligned((PAGESIZE)) returnspointerwithnoaliases + libcesque dontdiscard returnsaligned((GUARDSIZE)) returnspointerwithnoaliases #define reallocesque libcesque returnsaligned((16)) #define mallocesque reallocesque returnspointerwithnoaliases #define interruptfn nocallersavedregisters forcealignargpointer @@ -273,9 +273,9 @@ typedef struct { static __inline __attribute__((__always_inline__, __gnu_inline__, \ __no_instrument_function__, __unused__)) #else -#define forceinline \ - static __inline __attribute__( \ - (__always_inline__, __no_instrument_function__, __unused__)) +#define forceinline \ + static __inline __attribute__((__always_inline__, \ + __no_instrument_function__, __unused__)) #endif /* __GNUC_STDC_INLINE__ */ #endif /* GCC >= 4.3 */ #elif defined(_MSC_VER) @@ -677,19 +677,19 @@ typedef struct { #if defined(__GNUC__) || defined(__llvm__) #pragma GCC diagnostic ignored \ "-Wundef" /* complaints about __ASSEMBLER__/__LINKER__ */ -#pragma GCC diagnostic ignored "-Wsign-compare" /* lint needs to change */ -#pragma GCC diagnostic ignored "-Wtype-limits" /* makes macros unsafe */ -#pragma GCC diagnostic ignored "-Woverflow" /* also breaks macros */ -#pragma GCC diagnostic ignored "-Wformat" /* forces only gnu pf */ +#pragma GCC diagnostic ignored "-Wsign-compare" /* lint needs to change */ +#pragma GCC diagnostic ignored "-Wtype-limits" /* makes macros unsafe */ +#pragma GCC diagnostic ignored "-Woverflow" /* also breaks macros */ +#pragma GCC diagnostic ignored "-Wformat" /* forces only gnu pf */ #pragma GCC diagnostic ignored "-Wunused-parameter" /* extreme prejudice */ -#pragma GCC diagnostic ignored "-Wunused-function" /* contradicts dce! */ -#pragma GCC diagnostic ignored "-Wunused-const-variable" /* let me dce */ -#pragma GCC diagnostic ignored "-Wunused-variable" /* belongs in tidy */ -#pragma GCC diagnostic ignored "-Wformat-extra-args" /* is also broken */ -#pragma GCC diagnostic ignored "-Wparentheses" /* annoying tidy */ -#pragma GCC diagnostic ignored "-Wdangling-else" /* come on tidy */ -#pragma GCC diagnostic ignored "-Wformat-security" /* come on tidy */ -#pragma GCC diagnostic ignored "-Wunused-value" /* breaks macros */ +#pragma GCC diagnostic ignored "-Wunused-function" /* contradicts dce! */ +#pragma GCC diagnostic ignored "-Wunused-const-variable" /* let me dce */ +#pragma GCC diagnostic ignored "-Wunused-variable" /* belongs in tidy */ +#pragma GCC diagnostic ignored "-Wformat-extra-args" /* is also broken */ +#pragma GCC diagnostic ignored "-Wparentheses" /* annoying tidy */ +#pragma GCC diagnostic ignored "-Wdangling-else" /* come on tidy */ +#pragma GCC diagnostic ignored "-Wformat-security" /* come on tidy */ +#pragma GCC diagnostic ignored "-Wunused-value" /* breaks macros */ #pragma GCC diagnostic ignored "-Wdeprecated-declarations" /* libcxx */ #ifndef __cplusplus #pragma GCC diagnostic ignored "-Wimplicit-int" @@ -709,7 +709,7 @@ typedef struct { #if __GNUC__ >= 8 #pragma GCC diagnostic ignored "-Wstringop-truncation" #pragma GCC diagnostic ignored "-Wstringop-overflow" /* breaks strndup */ -#endif /* GCC8+ */ +#endif /* GCC8+ */ #if __GNUC__ + 0 >= 9 #pragma GCC diagnostic ignored /* "always true" breaks dce */ "-Waddress" #endif /* GCC9+ */ @@ -720,8 +720,8 @@ typedef struct { "-Wincompatible-pointer-types-discards-qualifiers" #pragma clang diagnostic ignored "-Wbuiltin-requires-header" #pragma clang diagnostic ignored "-Wparentheses-equality" /*-save-temps*/ -#pragma clang diagnostic ignored "-Wunused-value" /*({-save-temps})*/ -#pragma clang diagnostic ignored "-Wstring-plus-int" /* special ed */ +#pragma clang diagnostic ignored "-Wunused-value" /*({-save-temps})*/ +#pragma clang diagnostic ignored "-Wstring-plus-int" /* special ed */ #pragma clang diagnostic ignored "-Wunused-value" /* extreme prejudice */ #pragma clang diagnostic ignored "-Wbuiltin-requires-header" #pragma clang diagnostic ignored \ @@ -756,7 +756,7 @@ typedef struct { #if __GNUC__ >= 6 #pragma GCC diagnostic error "-Wnonnull-compare" #if defined(COSMO) && !defined(MODE_DBG) && !defined(STACK_FRAME_UNLIMITED) -#pragma GCC diagnostic error "-Wframe-larger-than=4096" +#pragma GCC diagnostic error "-Wframe-larger-than=16384" #if __GNUC__ >= 9 #pragma GCC diagnostic error "-Walloca-larger-than=1024" #pragma GCC diagnostic error "-Wvla-larger-than=1024" diff --git a/libc/integral/normalize.inc b/libc/integral/normalize.inc index 82e053933..56356ebba 100644 --- a/libc/integral/normalize.inc +++ b/libc/integral/normalize.inc @@ -70,13 +70,14 @@ #if defined(COSMO) && (defined(MODE_DBG) || defined(__SANITIZE_ADDRESS__)) #define STACKSIZE 262144 /* 256kb stack */ #elif defined(COSMO) -#define STACKSIZE 65536 /* 64kb stack */ +#define STACKSIZE 131072 /* 128kb stack */ #else #define STACKSIZE 8388608 /* 8mb stack */ #endif #define BIGPAGESIZE 0x200000 #define FRAMESIZE 0x10000 /* 8086 */ +#define GUARDSIZE 0x4000 /* b/c apple m1 */ #define PAGESIZE 0x1000 /* i386+ */ #define BUFSIZ 0x1000 /* best stdio default */ #define CACHELINE 0x40 /* nexgen32e */ diff --git a/libc/intrin/asan.c b/libc/intrin/asan.c index 037a785f3..1f35ea41c 100644 --- a/libc/intrin/asan.c +++ b/libc/intrin/asan.c @@ -1458,7 +1458,7 @@ static textstartup void __asan_shadow_mapping(struct MemoryIntervals *m, static textstartup void __asan_shadow_existing_mappings(void) { __asan_shadow_mapping(&_mmi, 0); __asan_map_shadow(GetStackAddr(), GetStackSize()); - __asan_poison((void *)GetStackAddr(), PAGESIZE, kAsanStackOverflow); + __asan_poison((void *)GetStackAddr(), GUARDSIZE, kAsanStackOverflow); } __attribute__((__constructor__)) void __asan_init(int argc, char **argv, @@ -1482,7 +1482,7 @@ __attribute__((__constructor__)) void __asan_init(int argc, char **argv, __asan_shadow_existing_mappings(); __asan_map_shadow((uintptr_t)_base, _end - _base); __asan_map_shadow(0, 4096); - __asan_poison(0, PAGESIZE, kAsanNullPage); + __asan_poison(0, GUARDSIZE, kAsanNullPage); if (!IsWindows()) { __sysv_mprotect((void *)0x7fff8000, 0x10000, PROT_READ); } diff --git a/libc/intrin/extend.c b/libc/intrin/extend.c index b4cd7226c..72435e2cf 100644 --- a/libc/intrin/extend.c +++ b/libc/intrin/extend.c @@ -75,6 +75,7 @@ noasan void *_extend(void *p, size_t n, void *e, int f, intptr_t h) { char *q; _unassert(!((uintptr_t)SHADOW(p) & (G - 1))); _unassert((uintptr_t)p + (G << kAsanScale) <= h); + // TODO(jart): Make this spin less in non-ASAN mode. for (q = e; q < ((char *)p + n); q += 8) { if (!((uintptr_t)q & (G - 1))) { _unassert(q + G <= (char *)h); diff --git a/libc/log/oncrash.c b/libc/log/oncrash.c index 4e1c0d73c..fa5afe231 100644 --- a/libc/log/oncrash.c +++ b/libc/log/oncrash.c @@ -232,7 +232,7 @@ relegated void ShowCrashReport(int err, int sig, struct siginfo *si, " %s %s %s %s\n", !__nocolor ? "\e[30;101m" : "", !__nocolor ? "\e[0m" : "", sig, (ctx && (ctx->uc_mcontext.rsp >= GetStaticStackAddr(0) && - ctx->uc_mcontext.rsp <= GetStaticStackAddr(0) + PAGESIZE)) + ctx->uc_mcontext.rsp <= GetStaticStackAddr(0) + GUARDSIZE)) ? "Stack Overflow" : GetSiCodeName(sig, si->si_code), host, getpid(), gettid(), program_invocation_name, names.sysname, diff --git a/libc/mem/balloc.c b/libc/mem/balloc.c index fe47c18e1..a21ba63be 100644 --- a/libc/mem/balloc.c +++ b/libc/mem/balloc.c @@ -21,7 +21,7 @@ /* TODO(jart): delete */ -#define kGuard PAGESIZE +#define kGuard GUARDSIZE #define kGrain FRAMESIZE /** diff --git a/libc/runtime/clone-linux.S b/libc/runtime/clone-linux.S index be1bc422f..d804964d2 100644 --- a/libc/runtime/clone-linux.S +++ b/libc/runtime/clone-linux.S @@ -44,9 +44,14 @@ sys_clone_linux: ret 2: xor %ebp,%ebp # child thread mov %rbx,%rdi # arg + mov %r10,%r15 # experiment mov (%r10),%esi # tid call *%r9 # func(arg,tid) xchg %eax,%edi # func(arg,tid) → exitcode + mov (%r15),%eax # experiment + test %eax,%eax # experiment + jz 1f # experiment mov $60,%eax # __NR_exit(exitcode) syscall +1: hlt # ctid was corrupted by program! .endfn sys_clone_linux,globl,hidden diff --git a/libc/runtime/clone.c b/libc/runtime/clone.c index 93e474132..0c71f1e4a 100644 --- a/libc/runtime/clone.c +++ b/libc/runtime/clone.c @@ -446,6 +446,7 @@ static int CloneLinux(int (*func)(void *arg, int rc), char *stk, size_t stksz, sp -= sizeof(int); sp = sp & -alignof(int); ctid = (int *)sp; + sp -= 8; // experiment } sp = sp & -16; // align the stack if ((rc = sys_clone_linux(flags, sp, ptid, ctid, tls, func, arg)) >= 0) { diff --git a/libc/runtime/mmap.c b/libc/runtime/mmap.c index 1e990468b..946169be9 100644 --- a/libc/runtime/mmap.c +++ b/libc/runtime/mmap.c @@ -381,10 +381,10 @@ static noasan inline void *Mmap(void *addr, size_t size, int prot, int flags, // however this 1mb behavior oddly enough is smart enough to not // apply if the mapping is a manually-created guard page. int e = errno; - if ((dm = sys_mmap(p + size - PAGESIZE, PAGESIZE, prot, + if ((dm = sys_mmap(p + size - GUARDSIZE, GUARDSIZE, prot, f | MAP_GROWSDOWN_linux, fd, off)) .addr != MAP_FAILED) { - _npassert(sys_mmap(p, PAGESIZE, PROT_NONE, + _npassert(sys_mmap(p, GUARDSIZE, PROT_NONE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) .addr == p); dm.addr = p; @@ -412,11 +412,11 @@ static noasan inline void *Mmap(void *addr, size_t size, int prot, int flags, if (needguard) { if (!IsWindows()) { // make windows fork() code simpler - mprotect(p, PAGESIZE, PROT_NONE); + mprotect(p, GUARDSIZE, PROT_NONE); } if (IsAsan()) { __repstosb((void *)(((intptr_t)p >> 3) + 0x7fff8000), - kAsanStackOverflow, PAGESIZE / 8); + kAsanStackOverflow, GUARDSIZE / 8); } } } diff --git a/libc/runtime/stack.h b/libc/runtime/stack.h index a748ceedb..ac3db3c70 100644 --- a/libc/runtime/stack.h +++ b/libc/runtime/stack.h @@ -122,7 +122,7 @@ extern char ape_stack_align[] __attribute__((__weak__)); */ #define HaveStackMemory(n) \ (IsTiny() || \ - (intptr_t)__builtin_frame_address(0) >= GetStackAddr() + PAGESIZE + (n)) + (intptr_t)__builtin_frame_address(0) >= GetStackAddr() + GUARDSIZE + (n)) forceinline void CheckLargeStackAllocation(void *p, ssize_t n) { for (; n > 0; n -= 4096) { diff --git a/libc/str/memmem.c b/libc/str/memmem.c index 90a2df108..b8150d08a 100644 --- a/libc/str/memmem.c +++ b/libc/str/memmem.c @@ -16,9 +16,9 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/intrin/likely.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" +#include "libc/intrin/likely.h" #include "libc/str/str.h" typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(16))); diff --git a/libc/str/str.mk b/libc/str/str.mk index 823992e5a..bf2cf5302 100644 --- a/libc/str/str.mk +++ b/libc/str/str.mk @@ -45,10 +45,6 @@ $(LIBC_STR_A).pkg: \ $(LIBC_STR_A_OBJS) \ $(foreach x,$(LIBC_STR_A_DIRECTDEPS),$($(x)_A).pkg) -o/$(MODE)/libc/str/memmem.o: private \ - OVERRIDE_CPPFLAGS += \ - -DSTACK_FRAME_UNLIMITED - o/$(MODE)/libc/str/wmemset.o \ o/$(MODE)/libc/str/memset16.o \ o/$(MODE)/libc/str/dosdatetimetounix.o: private \ diff --git a/libc/thread/pthread_attr_init.c b/libc/thread/pthread_attr_init.c index 9ff1fca92..d56845dd9 100644 --- a/libc/thread/pthread_attr_init.c +++ b/libc/thread/pthread_attr_init.c @@ -27,7 +27,7 @@ errno_t pthread_attr_init(pthread_attr_t *attr) { *attr = (pthread_attr_t){ .__stacksize = GetStackSize(), - .__guardsize = PAGESIZE, + .__guardsize = GUARDSIZE, }; return 0; } diff --git a/libc/thread/pthread_create.c b/libc/thread/pthread_create.c index 940c6f1dc..c64b74abd 100644 --- a/libc/thread/pthread_create.c +++ b/libc/thread/pthread_create.c @@ -174,12 +174,12 @@ static errno_t pthread_create_impl(pthread_t *thread, pt->flags = PT_OWNSTACK; pt->attr.__stacksize = MAX(pt->attr.__stacksize, GetStackSize()); pt->attr.__stacksize = _roundup2pow(pt->attr.__stacksize); - pt->attr.__guardsize = ROUNDUP(pt->attr.__guardsize, PAGESIZE); - if (pt->attr.__guardsize + PAGESIZE >= pt->attr.__stacksize) { + pt->attr.__guardsize = ROUNDUP(pt->attr.__guardsize, GUARDSIZE); + if (pt->attr.__guardsize + GUARDSIZE >= pt->attr.__stacksize) { _pthread_free(pt); return EINVAL; } - if (pt->attr.__guardsize == PAGESIZE) { + if (pt->attr.__guardsize == GUARDSIZE) { // user is wisely using smaller stacks with default guard size pt->attr.__stackaddr = mmap(0, pt->attr.__stacksize, PROT_READ | PROT_WRITE, diff --git a/net/turfwar/turfwar.c b/net/turfwar/turfwar.c index 11728d732..ec29b92f0 100644 --- a/net/turfwar/turfwar.c +++ b/net/turfwar/turfwar.c @@ -46,6 +46,7 @@ #include "libc/runtime/internal.h" #include "libc/runtime/runtime.h" #include "libc/runtime/stack.h" +#include "libc/runtime/sysconf.h" #include "libc/sock/sock.h" #include "libc/sock/struct/pollfd.h" #include "libc/sock/struct/sockaddr.h" @@ -114,7 +115,7 @@ #define SOCK_MAX 100 // max length of socket queue #define MSG_BUF 512 // small response lookaside -#define INBUF_SIZE PAGESIZE +#define INBUF_SIZE FRAMESIZE #define OUTBUF_SIZE 8192 #define TB_BYTES (1u << TB_CIDR) @@ -632,16 +633,18 @@ static bool GetNick(char *inbuf, struct HttpMessage *msg, struct Claim *v) { // so if it gets hacked it'll at least crash instead of get compromised void *NewSafeBuffer(size_t n) { char *p; - size_t m = ROUNDUP(n, PAGESIZE); - _npassert((p = valloc(m + PAGESIZE))); - _npassert(!mprotect(p + m, PAGESIZE, PROT_NONE)); + long pagesize = sysconf(_SC_PAGESIZE); + size_t m = ROUNDUP(n, pagesize); + _npassert((p = valloc(m + pagesize))); + _npassert(!mprotect(p + m, pagesize, PROT_NONE)); return p; } // frees memory with hardware-accelerated buffer overflow detection void FreeSafeBuffer(void *p) { + long pagesize = sysconf(_SC_PAGESIZE); size_t n = malloc_usable_size(p); - size_t m = ROUNDDOWN(n, PAGESIZE); + size_t m = ROUNDDOWN(n, pagesize); _npassert(!mprotect(p, m, PROT_READ | PROT_WRITE)); free(p); } diff --git a/test/libc/calls/setrlimit_test.c b/test/libc/calls/setrlimit_test.c index fcb168a7a..6ed9b612f 100644 --- a/test/libc/calls/setrlimit_test.c +++ b/test/libc/calls/setrlimit_test.c @@ -125,8 +125,8 @@ TEST(setrlimit, testMemoryLimit) { ASSERT_NE(-1, (wstatus = xspawn(0))); if (wstatus == -2) { ASSERT_EQ(0, SetKernelEnforcedMemoryLimit(MEM)); - for (gotsome = i = 0; i < (MEM * 2) / PAGESIZE; ++i) { - p = mmap(0, PAGESIZE, PROT_READ | PROT_WRITE, + for (gotsome = i = 0; i < (MEM * 2) / GUARDSIZE; ++i) { + p = mmap(0, GUARDSIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_POPULATE, -1, 0); if (p != MAP_FAILED) { gotsome = true; @@ -138,7 +138,7 @@ TEST(setrlimit, testMemoryLimit) { ASSERT_EQ(ENOMEM, errno); _Exit(0); } - rngset(p, PAGESIZE, _rand64, -1); + rngset(p, GUARDSIZE, _rand64, -1); } _Exit(1); } @@ -158,15 +158,15 @@ TEST(setrlimit, testVirtualMemoryLimit) { ASSERT_NE(-1, (wstatus = xspawn(0))); if (wstatus == -2) { ASSERT_EQ(0, setrlimit(RLIMIT_AS, &(struct rlimit){MEM, MEM})); - for (i = 0; i < (MEM * 2) / PAGESIZE; ++i) { - p = sys_mmap(0, PAGESIZE, PROT_READ | PROT_WRITE, + for (i = 0; i < (MEM * 2) / GUARDSIZE; ++i) { + p = sys_mmap(0, GUARDSIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_POPULATE, -1, 0) .addr; if (p == MAP_FAILED) { ASSERT_EQ(ENOMEM, errno); _Exit(0); } - rngset(p, PAGESIZE, _rand64, -1); + rngset(p, GUARDSIZE, _rand64, -1); } _Exit(1); } @@ -188,15 +188,15 @@ TEST(setrlimit, testDataMemoryLimit) { ASSERT_NE(-1, (wstatus = xspawn(0))); if (wstatus == -2) { ASSERT_EQ(0, setrlimit(RLIMIT_DATA, &(struct rlimit){MEM, MEM})); - for (i = 0; i < (MEM * 2) / PAGESIZE; ++i) { - p = sys_mmap(0, PAGESIZE, PROT_READ | PROT_WRITE, + for (i = 0; i < (MEM * 2) / GUARDSIZE; ++i) { + p = sys_mmap(0, GUARDSIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_POPULATE, -1, 0) .addr; if (p == MAP_FAILED) { ASSERT_EQ(ENOMEM, errno); _Exit(0); } - rngset(p, PAGESIZE, _rand64, -1); + rngset(p, GUARDSIZE, _rand64, -1); } _Exit(1); } diff --git a/test/libc/intrin/kprintf_test.c b/test/libc/intrin/kprintf_test.c index aed2c997b..fe9001fd1 100644 --- a/test/libc/intrin/kprintf_test.c +++ b/test/libc/intrin/kprintf_test.c @@ -226,9 +226,9 @@ TEST(ksnprintf, fuzzTheUnbreakable) { size_t i; uint64_t x; char *f, b[32]; - _Alignas(PAGESIZE) static const char weasel[PAGESIZE]; + _Alignas(FRAMESIZE) static const char weasel[FRAMESIZE]; asm("mov\t%1,%0" : "=r"(f) : "g"(weasel)); - EXPECT_SYS(0, 0, mprotect(f, PAGESIZE, PROT_READ | PROT_WRITE)); + EXPECT_SYS(0, 0, mprotect(f, FRAMESIZE, PROT_READ | PROT_WRITE)); strcpy(f, "hello %s\n"); EXPECT_EQ(12, ksnprintf(b, sizeof(b), f, "world")); EXPECT_STREQ("hello world\n", b); @@ -240,7 +240,7 @@ TEST(ksnprintf, fuzzTheUnbreakable) { f[Rando() & 15] = '%'; ksnprintf(b, sizeof(b), f, lemur64(), lemur64(), lemur64()); } - EXPECT_SYS(0, 0, mprotect(f, PAGESIZE, PROT_READ)); + EXPECT_SYS(0, 0, mprotect(f, FRAMESIZE, PROT_READ)); } TEST(kprintf, testFailure_wontClobberErrnoAndBypassesSystemCallSupport) { diff --git a/test/libc/intrin/popcnt_test.c b/test/libc/intrin/popcnt_test.c index 93d219de1..b8ff51617 100644 --- a/test/libc/intrin/popcnt_test.c +++ b/test/libc/intrin/popcnt_test.c @@ -16,14 +16,14 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/intrin/popcnt.h" #include "libc/calls/calls.h" +#include "libc/intrin/popcnt.h" #include "libc/testlib/ezbench.h" #include "libc/testlib/hyperion.h" #include "libc/testlib/testlib.h" void SetUpOnce(void) { - ASSERT_SYS(0, 0, pledge("stdio", 0)); + ASSERT_SYS(0, 0, pledge("stdio rpath", 0)); } TEST(popcnt, test) { diff --git a/test/libc/runtime/brk_test.c b/test/libc/runtime/brk_test.c index 8b72b6c83..ac24a9084 100644 --- a/test/libc/runtime/brk_test.c +++ b/test/libc/runtime/brk_test.c @@ -49,7 +49,7 @@ TEST(brk, underflowsEnd_returnsEinval) { } TEST(sbrk, underflowsEnd_returnsEinval) { - ASSERT_SYS(EINVAL, MAP_FAILED, sbrk(-PAGESIZE)); + ASSERT_SYS(EINVAL, MAP_FAILED, sbrk(-GUARDSIZE)); } TEST(sbrk, giantDelta_returnsEnomem) { @@ -73,11 +73,11 @@ TEST(sbrk, overlapsExistingMapping_failsWithEexist) { TEST(sbrk, testGrowAndShrink) { SPAWN(fork); ASSERT_FALSE(testlib_memoryexists(_end)); - ASSERT_SYS(0, _end, sbrk(PAGESIZE)); - ASSERT_SYS(0, _end + PAGESIZE, sbrk(0)); + ASSERT_SYS(0, _end, sbrk(GUARDSIZE)); + ASSERT_SYS(0, _end + GUARDSIZE, sbrk(0)); ASSERT_TRUE(testlib_memoryexists(_end)); - ASSERT_FALSE(testlib_memoryexists(_end + PAGESIZE)); - ASSERT_SYS(0, _end + PAGESIZE, sbrk(-PAGESIZE)); + ASSERT_FALSE(testlib_memoryexists(_end + GUARDSIZE)); + ASSERT_SYS(0, _end + GUARDSIZE, sbrk(-GUARDSIZE)); ASSERT_FALSE(testlib_memoryexists(_end)); EXITS(0); } @@ -85,9 +85,9 @@ TEST(sbrk, testGrowAndShrink) { TEST(brk, testGrowAndShrink) { SPAWN(fork); ASSERT_FALSE(testlib_memoryexists(_end)); - ASSERT_EQ(0, brk(_end + PAGESIZE)); + ASSERT_EQ(0, brk(_end + GUARDSIZE)); ASSERT_TRUE(testlib_memoryexists(_end)); - ASSERT_FALSE(testlib_memoryexists(_end + PAGESIZE)); + ASSERT_FALSE(testlib_memoryexists(_end + GUARDSIZE)); ASSERT_EQ(0, brk(_end)); EXITS(0); } diff --git a/test/libc/runtime/mprotect_test.c b/test/libc/runtime/mprotect_test.c index 30e0f4ab4..ff1bd43c6 100644 --- a/test/libc/runtime/mprotect_test.c +++ b/test/libc/runtime/mprotect_test.c @@ -94,9 +94,9 @@ void TearDown(void) { } TEST(mprotect, testOkMemory) { - char *p = gc(memalign(PAGESIZE, PAGESIZE)); + char *p = gc(memalign(GUARDSIZE, GUARDSIZE)); p[0] = 0; - ASSERT_NE(-1, mprotect(p, PAGESIZE, PROT_READ | PROT_WRITE)); + ASSERT_NE(-1, mprotect(p, GUARDSIZE, PROT_READ | PROT_WRITE)); p[0] = 1; EXPECT_EQ(1, p[0]); EXPECT_FALSE(gotsegv); @@ -105,19 +105,19 @@ TEST(mprotect, testOkMemory) { TEST(mprotect, testSegfault_writeToReadOnlyAnonymous) { volatile char *p; - p = gc(memalign(PAGESIZE, PAGESIZE)); + p = gc(memalign(GUARDSIZE, GUARDSIZE)); EXPECT_FALSE(gotsegv); p[0] = 1; EXPECT_FALSE(gotsegv); EXPECT_FALSE(gotbusted); - EXPECT_NE(-1, mprotect(p, PAGESIZE, PROT_READ)); + EXPECT_NE(-1, mprotect(p, GUARDSIZE, PROT_READ)); _missingno(p[0]); EXPECT_FALSE(gotsegv); EXPECT_FALSE(gotbusted); p[0] = 2; EXPECT_TRUE(gotsegv | gotbusted); EXPECT_EQ(1, p[0]); - EXPECT_NE(-1, mprotect(p, PAGESIZE, PROT_READ | PROT_WRITE)); + EXPECT_NE(-1, mprotect(p, GUARDSIZE, PROT_READ | PROT_WRITE)); } TEST(mprotect, testExecOnly_canExecute) { @@ -137,11 +137,11 @@ TEST(mprotect, testExecOnly_canExecute) { TEST(mprotect, testProtNone_cantEvenRead) { volatile char *p; - p = gc(memalign(PAGESIZE, PAGESIZE)); - EXPECT_NE(-1, mprotect(p, PAGESIZE, PROT_NONE)); + p = gc(memalign(GUARDSIZE, GUARDSIZE)); + EXPECT_NE(-1, mprotect(p, GUARDSIZE, PROT_NONE)); _missingno(p[0]); EXPECT_TRUE(gotsegv | gotbusted); - EXPECT_NE(-1, mprotect(p, PAGESIZE, PROT_READ | PROT_WRITE)); + EXPECT_NE(-1, mprotect(p, GUARDSIZE, PROT_READ | PROT_WRITE)); } static const char kRet31337[] = { @@ -150,24 +150,24 @@ static const char kRet31337[] = { }; TEST(mprotect, testExecJit_actuallyWorks) { - int (*p)(void) = gc(memalign(PAGESIZE, PAGESIZE)); + int (*p)(void) = gc(memalign(GUARDSIZE, GUARDSIZE)); memcpy(p, kRet31337, sizeof(kRet31337)); - EXPECT_NE(-1, mprotect(p, PAGESIZE, PROT_EXEC)); + EXPECT_NE(-1, mprotect(p, GUARDSIZE, PROT_EXEC)); EXPECT_EQ(31337, p()); EXPECT_FALSE(gotsegv); EXPECT_FALSE(gotbusted); - EXPECT_NE(-1, mprotect(p, PAGESIZE, PROT_READ | PROT_WRITE)); + EXPECT_NE(-1, mprotect(p, GUARDSIZE, PROT_READ | PROT_WRITE)); } TEST(mprotect, testRwxMap_vonNeumannRules) { if (IsOpenbsd()) return; // boo - int (*p)(void) = gc(memalign(PAGESIZE, PAGESIZE)); + int (*p)(void) = gc(memalign(GUARDSIZE, GUARDSIZE)); memcpy(p, kRet31337, sizeof(kRet31337)); - EXPECT_NE(-1, mprotect(p, PAGESIZE, PROT_READ | PROT_WRITE | PROT_EXEC)); + EXPECT_NE(-1, mprotect(p, GUARDSIZE, PROT_READ | PROT_WRITE | PROT_EXEC)); EXPECT_EQ(31337, p()); EXPECT_FALSE(gotsegv); EXPECT_FALSE(gotbusted); - EXPECT_NE(-1, mprotect(p, PAGESIZE, PROT_READ | PROT_WRITE)); + EXPECT_NE(-1, mprotect(p, GUARDSIZE, PROT_READ | PROT_WRITE)); } TEST(mprotect, testExecuteFlatFileMapOpenedAsReadonly) { @@ -202,13 +202,13 @@ TEST(mprotect, testFileMap_canChangeToExecWhileOpenInRdwrMode) { } TEST(mprotect, testBadProt_failsEinval) { - volatile char *p = gc(memalign(PAGESIZE, PAGESIZE)); + volatile char *p = gc(memalign(GUARDSIZE, GUARDSIZE)); EXPECT_EQ(-1, mprotect(p, 9999, -1)); EXPECT_EQ(EINVAL, errno); } TEST(mprotect, testZeroSize_doesNothing) { - volatile char *p = gc(memalign(PAGESIZE, PAGESIZE)); + volatile char *p = gc(memalign(GUARDSIZE, GUARDSIZE)); EXPECT_NE(-1, mprotect(p, 0, PROT_READ)); p[0] = 1; EXPECT_FALSE(gotsegv); diff --git a/third_party/dlmalloc/init.inc b/third_party/dlmalloc/init.inc index 3a91aeb68..c93477238 100644 --- a/third_party/dlmalloc/init.inc +++ b/third_party/dlmalloc/init.inc @@ -24,8 +24,8 @@ int init_mparams(void) { size_t gsize; #if defined(__COSMOPOLITAN__) - psize = 4096; - gsize = 65536; + psize = FRAMESIZE; + gsize = FRAMESIZE; #elif !defined(WIN32) psize = malloc_getpagesize; gsize = ((DEFAULT_GRANULARITY != 0)? DEFAULT_GRANULARITY : psize); diff --git a/third_party/lua/lua.mk b/third_party/lua/lua.mk index a157cbcff..2fdbb9c92 100644 --- a/third_party/lua/lua.mk +++ b/third_party/lua/lua.mk @@ -155,10 +155,6 @@ o/$(MODE)/third_party/lua/lvm.o: private \ OVERRIDE_CFLAGS += \ -fno-gcse -o/$(MODE)/third_party/lua/lauxlib.o: private \ - OVERRIDE_CFLAGS += \ - -DSTACK_FRAME_UNLIMITED - $(THIRD_PARTY_LUA_A_OBJS): private \ OVERRIDE_CFLAGS += \ -ffunction-sections \ diff --git a/third_party/lua/luaencodejsondata.c b/third_party/lua/luaencodejsondata.c index 2186a755e..1bb93065e 100644 --- a/third_party/lua/luaencodejsondata.c +++ b/third_party/lua/luaencodejsondata.c @@ -22,8 +22,8 @@ #include "libc/intrin/likely.h" #include "libc/log/log.h" #include "libc/log/rop.h" -#include "libc/mem/mem.h" #include "libc/mem/gc.internal.h" +#include "libc/mem/mem.h" #include "libc/runtime/stack.h" #include "libc/stdio/append.h" #include "libc/stdio/strlist.internal.h" @@ -169,7 +169,7 @@ static int SerializeTable(lua_State *L, char **buf, int idx, bool multi; bool isarray; lua_Unsigned n; - if (UNLIKELY(!HaveStackMemory(PAGESIZE))) { + if (UNLIKELY(!HaveStackMemory(GUARDSIZE))) { z->reason = "out of stack"; return -1; } diff --git a/third_party/lua/luaencodeluadata.c b/third_party/lua/luaencodeluadata.c index a280222a0..1a4586f6c 100644 --- a/third_party/lua/luaencodeluadata.c +++ b/third_party/lua/luaencodeluadata.c @@ -353,7 +353,7 @@ static int SerializeTable(lua_State *L, char **buf, int idx, int rc; bool multi; intptr_t rsp, bot; - if (UNLIKELY(!HaveStackMemory(PAGESIZE))) { + if (UNLIKELY(!HaveStackMemory(GUARDSIZE))) { z->reason = "out of stack"; return -1; } diff --git a/third_party/make/make.mk b/third_party/make/make.mk index b55643892..b154db5db 100644 --- a/third_party/make/make.mk +++ b/third_party/make/make.mk @@ -171,8 +171,8 @@ o/$(MODE)/third_party/make/hash.o: private \ $(THIRD_PARTY_MAKE_OBJS): private \ OVERRIDE_CFLAGS += \ -DNO_ARCHIVES \ - -DSTACK_FRAME_UNLIMITED \ -DHAVE_CONFIG_H \ + -DSTACK_FRAME_UNLIMITED \ -DINCLUDEDIR=\".\" \ -DLIBDIR=\".\" \ -DLOCALEDIR=\".\" diff --git a/third_party/mbedtls/test/test.mk b/third_party/mbedtls/test/test.mk index 13173da5a..6bdf465c8 100644 --- a/third_party/mbedtls/test/test.mk +++ b/third_party/mbedtls/test/test.mk @@ -134,10 +134,6 @@ o/$(MODE)/third_party/mbedtls/test/%.com.dbg: \ o/$(MODE)/third_party/mbedtls/test/%.com.runs: o/$(MODE)/third_party/mbedtls/test/%.com @$(COMPILE) -ACHECK -wtT$@ $< $(TESTARGS) -$(THIRD_PARTY_MBEDTLS_TEST_OBJS): private \ - OVERRIDE_CFLAGS += \ - -DSTACK_FRAME_UNLIMITED - o/$(MODE)/third_party/mbedtls/test/lib.o: private \ OVERRIDE_CFLAGS += \ -fdata-sections \ diff --git a/third_party/quickjs/quickjs.mk b/third_party/quickjs/quickjs.mk index 1391fb8f6..6256e6fc5 100644 --- a/third_party/quickjs/quickjs.mk +++ b/third_party/quickjs/quickjs.mk @@ -199,10 +199,6 @@ o/tiny/third_party/quickjs/call.o: private \ OVERRIDE_CFLAGS += \ -O2 -o/$(MODE)/third_party/quickjs/unicode_gen.o: private \ - OVERRIDE_CPPFLAGS += \ - -DSTACK_FRAME_UNLIMITED - # TODO(jart): Replace alloca() calls with malloc(). o/$(MODE)/third_party/quickjs/libregexp.o \ o/$(MODE)/third_party/quickjs/quickjs.o: private \ diff --git a/third_party/quickjs/unicode_gen.c b/third_party/quickjs/unicode_gen.c index d5d956c41..6d0b4a37c 100644 --- a/third_party/quickjs/unicode_gen.c +++ b/third_party/quickjs/unicode_gen.c @@ -22,11 +22,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include "libc/mem/alg.h" #include "libc/assert.h" #include "libc/fmt/conv.h" #include "libc/fmt/fmt.h" #include "libc/log/log.h" +#include "libc/mem/alg.h" #include "libc/mem/mem.h" #include "libc/runtime/runtime.h" #include "libc/stdio/stdio.h" diff --git a/third_party/stb/stb.mk b/third_party/stb/stb.mk index 36df433bd..fbdc123ba 100644 --- a/third_party/stb/stb.mk +++ b/third_party/stb/stb.mk @@ -60,7 +60,7 @@ $(THIRD_PARTY_STB_A_OBJS): private \ -ffunction-sections \ -fdata-sections -$(THIRD_PARTY_STB_A_OBJS): private \ +o/$(MODE)/third_party/stb/stb_vorbis.o: private \ OVERRIDE_CPPFLAGS += \ -DSTACK_FRAME_UNLIMITED diff --git a/third_party/zip/zip.mk b/third_party/zip/zip.mk index 472e6eeee..a94d41cae 100644 --- a/third_party/zip/zip.mk +++ b/third_party/zip/zip.mk @@ -162,13 +162,6 @@ o/$(MODE)/third_party/zip/zipup.o: private \ -DZIP64_SUPPORT \ -DBZIP2_SUPPORT -o/$(MODE)/third_party/zip/zip.o \ -o/$(MODE)/third_party/zip/zipsplit.o \ -o/$(MODE)/third_party/zip/fileio.o \ -o/$(MODE)/third_party/zip/fileio_.o: private \ - OVERRIDE_CPPFLAGS += \ - -DSTACK_FRAME_UNLIMITED - .PHONY: o/$(MODE)/third_party/zip o/$(MODE)/third_party/zip: \ $(THIRD_PARTY_ZIP_BINS) \ diff --git a/third_party/zip/zipup.c b/third_party/zip/zipup.c index 445545d29..213fcbe29 100644 --- a/third_party/zip/zipup.c +++ b/third_party/zip/zipup.c @@ -48,6 +48,9 @@ // MISSING #include "os2/os2zip.h" #endif +#undef PAGESIZE +#define PAGESIZE FRAMESIZE + #if defined(MMAP) #include "libc/calls/calls.h" #include "libc/calls/weirdtypes.h" diff --git a/tool/emacs/cosmo-cpp-constants.el b/tool/emacs/cosmo-cpp-constants.el index 3e67cf206..15927ff98 100644 --- a/tool/emacs/cosmo-cpp-constants.el +++ b/tool/emacs/cosmo-cpp-constants.el @@ -153,6 +153,7 @@ (defconst cosmo-cpp-constants-cosmopolitan '("__SAUCE__" "PAGESIZE" + "GUARDSIZE" "FRAMESIZE" "BIGPAGESIZE" "STACKSIZE" diff --git a/tool/net/ljson.c b/tool/net/ljson.c index d929b3792..ad6e58562 100644 --- a/tool/net/ljson.c +++ b/tool/net/ljson.c @@ -98,7 +98,7 @@ static struct DecodeJson Parse(struct lua_State *L, const char *p, if (UNLIKELY(!depth)) { return (struct DecodeJson){-1, "maximum depth exceeded"}; } - if (UNLIKELY(!HaveStackMemory(PAGESIZE))) { + if (UNLIKELY(!HaveStackMemory(GUARDSIZE))) { return (struct DecodeJson){-1, "out of stack"}; } for (a = p, d = +1; p < e;) { diff --git a/tool/viz/life.c b/tool/viz/life.c index c9e848c1c..f68b27ff4 100644 --- a/tool/viz/life.c +++ b/tool/viz/life.c @@ -481,17 +481,17 @@ static void *NewBoard(size_t *out_size) { char *p; size_t s, n, k; s = (byn * bxn) >> 3; - k = PAGESIZE + ROUNDUP(s, PAGESIZE); - n = ROUNDUP(k + PAGESIZE, FRAMESIZE); + k = GUARDSIZE + ROUNDUP(s, GUARDSIZE); + n = ROUNDUP(k + GUARDSIZE, FRAMESIZE); p = _mapanon(n); - mprotect(p, PAGESIZE, 0); + mprotect(p, GUARDSIZE, 0); mprotect(p + k, n - k, 0); if (out_size) *out_size = n; - return p + PAGESIZE; + return p + GUARDSIZE; } static void FreeBoard(void *p, size_t n) { - munmap((char *)p - PAGESIZE, n); + munmap((char *)p - GUARDSIZE, n); } static void AllocateBoardsWithHardwareAcceleratedMemorySafety(void) {