Increase stack size to 128k and guard size to 16k

This improves our compatibility with Apple M1.
This commit is contained in:
Justine Tunney 2022-12-18 22:58:29 -08:00
parent 57c0dcdc29
commit dd04aeba1c
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
36 changed files with 109 additions and 125 deletions

View file

@ -121,21 +121,12 @@ o/$(MODE)/libc/calls/execlp.o \
o/$(MODE)/libc/calls/statfs.o \ o/$(MODE)/libc/calls/statfs.o \
o/$(MODE)/libc/calls/fstatfs.o \ o/$(MODE)/libc/calls/fstatfs.o \
o/$(MODE)/libc/calls/execve-sysv.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/execve-nt.greg.o \
o/$(MODE)/libc/calls/mkntenvblock.o: private \ o/$(MODE)/libc/calls/mkntenvblock.o: private \
OVERRIDE_CPPFLAGS += \ OVERRIDE_CPPFLAGS += \
-DSTACK_FRAME_UNLIMITED -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: # we must segregate codegen because:
# file contains multiple independently linkable apis # file contains multiple independently linkable apis
o/$(MODE)/libc/calls/ioctl-siocgifconf.o \ o/$(MODE)/libc/calls/ioctl-siocgifconf.o \

View file

@ -28,6 +28,7 @@
#include "libc/nt/files.h" #include "libc/nt/files.h"
#include "libc/nt/runtime.h" #include "libc/nt/runtime.h"
#include "libc/nt/struct/reparsedatabuffer.h" #include "libc/nt/struct/reparsedatabuffer.h"
#include "libc/runtime/stack.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/str/utf16.h" #include "libc/str/utf16.h"
#include "libc/sysv/errfuns.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; if (__mkntpathat(dirfd, path, 0, path16) == -1) return -1;
mem = 16384; mem = 16384;
memory = alloca(mem); memory = alloca(mem);
for (i = 0; i < mem; i += PAGESIZE) memory[i] = 0; CheckLargeStackAllocation(memory, mem);
rdb = (struct NtReparseDataBuffer *)memory; rdb = (struct NtReparseDataBuffer *)memory;
if ((h = CreateFile(path16, 0, 0, 0, kNtOpenExisting, if ((h = CreateFile(path16, 0, 0, 0, kNtOpenExisting,
kNtFileFlagOpenReparsePoint | kNtFileFlagBackupSemantics, kNtFileFlagOpenReparsePoint | kNtFileFlagBackupSemantics,

View file

@ -151,7 +151,7 @@ typedef struct {
#define memcpyesque libcesque #define memcpyesque libcesque
#define strlenesque libcesque nosideeffect paramsnonnull() #define strlenesque libcesque nosideeffect paramsnonnull()
#define vallocesque \ #define vallocesque \
libcesque dontdiscard returnsaligned((PAGESIZE)) returnspointerwithnoaliases libcesque dontdiscard returnsaligned((GUARDSIZE)) returnspointerwithnoaliases
#define reallocesque libcesque returnsaligned((16)) #define reallocesque libcesque returnsaligned((16))
#define mallocesque reallocesque returnspointerwithnoaliases #define mallocesque reallocesque returnspointerwithnoaliases
#define interruptfn nocallersavedregisters forcealignargpointer #define interruptfn nocallersavedregisters forcealignargpointer
@ -274,8 +274,8 @@ typedef struct {
__no_instrument_function__, __unused__)) __no_instrument_function__, __unused__))
#else #else
#define forceinline \ #define forceinline \
static __inline __attribute__( \ static __inline __attribute__((__always_inline__, \
(__always_inline__, __no_instrument_function__, __unused__)) __no_instrument_function__, __unused__))
#endif /* __GNUC_STDC_INLINE__ */ #endif /* __GNUC_STDC_INLINE__ */
#endif /* GCC >= 4.3 */ #endif /* GCC >= 4.3 */
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
@ -756,7 +756,7 @@ typedef struct {
#if __GNUC__ >= 6 #if __GNUC__ >= 6
#pragma GCC diagnostic error "-Wnonnull-compare" #pragma GCC diagnostic error "-Wnonnull-compare"
#if defined(COSMO) && !defined(MODE_DBG) && !defined(STACK_FRAME_UNLIMITED) #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 #if __GNUC__ >= 9
#pragma GCC diagnostic error "-Walloca-larger-than=1024" #pragma GCC diagnostic error "-Walloca-larger-than=1024"
#pragma GCC diagnostic error "-Wvla-larger-than=1024" #pragma GCC diagnostic error "-Wvla-larger-than=1024"

View file

@ -70,13 +70,14 @@
#if defined(COSMO) && (defined(MODE_DBG) || defined(__SANITIZE_ADDRESS__)) #if defined(COSMO) && (defined(MODE_DBG) || defined(__SANITIZE_ADDRESS__))
#define STACKSIZE 262144 /* 256kb stack */ #define STACKSIZE 262144 /* 256kb stack */
#elif defined(COSMO) #elif defined(COSMO)
#define STACKSIZE 65536 /* 64kb stack */ #define STACKSIZE 131072 /* 128kb stack */
#else #else
#define STACKSIZE 8388608 /* 8mb stack */ #define STACKSIZE 8388608 /* 8mb stack */
#endif #endif
#define BIGPAGESIZE 0x200000 #define BIGPAGESIZE 0x200000
#define FRAMESIZE 0x10000 /* 8086 */ #define FRAMESIZE 0x10000 /* 8086 */
#define GUARDSIZE 0x4000 /* b/c apple m1 */
#define PAGESIZE 0x1000 /* i386+ */ #define PAGESIZE 0x1000 /* i386+ */
#define BUFSIZ 0x1000 /* best stdio default */ #define BUFSIZ 0x1000 /* best stdio default */
#define CACHELINE 0x40 /* nexgen32e */ #define CACHELINE 0x40 /* nexgen32e */

View file

@ -1458,7 +1458,7 @@ static textstartup void __asan_shadow_mapping(struct MemoryIntervals *m,
static textstartup void __asan_shadow_existing_mappings(void) { static textstartup void __asan_shadow_existing_mappings(void) {
__asan_shadow_mapping(&_mmi, 0); __asan_shadow_mapping(&_mmi, 0);
__asan_map_shadow(GetStackAddr(), GetStackSize()); __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, __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_shadow_existing_mappings();
__asan_map_shadow((uintptr_t)_base, _end - _base); __asan_map_shadow((uintptr_t)_base, _end - _base);
__asan_map_shadow(0, 4096); __asan_map_shadow(0, 4096);
__asan_poison(0, PAGESIZE, kAsanNullPage); __asan_poison(0, GUARDSIZE, kAsanNullPage);
if (!IsWindows()) { if (!IsWindows()) {
__sysv_mprotect((void *)0x7fff8000, 0x10000, PROT_READ); __sysv_mprotect((void *)0x7fff8000, 0x10000, PROT_READ);
} }

View file

@ -75,6 +75,7 @@ noasan void *_extend(void *p, size_t n, void *e, int f, intptr_t h) {
char *q; char *q;
_unassert(!((uintptr_t)SHADOW(p) & (G - 1))); _unassert(!((uintptr_t)SHADOW(p) & (G - 1)));
_unassert((uintptr_t)p + (G << kAsanScale) <= h); _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) { for (q = e; q < ((char *)p + n); q += 8) {
if (!((uintptr_t)q & (G - 1))) { if (!((uintptr_t)q & (G - 1))) {
_unassert(q + G <= (char *)h); _unassert(q + G <= (char *)h);

View file

@ -232,7 +232,7 @@ relegated void ShowCrashReport(int err, int sig, struct siginfo *si,
" %s %s %s %s\n", " %s %s %s %s\n",
!__nocolor ? "\e[30;101m" : "", !__nocolor ? "\e[0m" : "", sig, !__nocolor ? "\e[30;101m" : "", !__nocolor ? "\e[0m" : "", sig,
(ctx && (ctx->uc_mcontext.rsp >= GetStaticStackAddr(0) && (ctx && (ctx->uc_mcontext.rsp >= GetStaticStackAddr(0) &&
ctx->uc_mcontext.rsp <= GetStaticStackAddr(0) + PAGESIZE)) ctx->uc_mcontext.rsp <= GetStaticStackAddr(0) + GUARDSIZE))
? "Stack Overflow" ? "Stack Overflow"
: GetSiCodeName(sig, si->si_code), : GetSiCodeName(sig, si->si_code),
host, getpid(), gettid(), program_invocation_name, names.sysname, host, getpid(), gettid(), program_invocation_name, names.sysname,

View file

@ -21,7 +21,7 @@
/* TODO(jart): delete */ /* TODO(jart): delete */
#define kGuard PAGESIZE #define kGuard GUARDSIZE
#define kGrain FRAMESIZE #define kGrain FRAMESIZE
/** /**

View file

@ -44,9 +44,14 @@ sys_clone_linux:
ret ret
2: xor %ebp,%ebp # child thread 2: xor %ebp,%ebp # child thread
mov %rbx,%rdi # arg mov %rbx,%rdi # arg
mov %r10,%r15 # experiment
mov (%r10),%esi # tid mov (%r10),%esi # tid
call *%r9 # func(arg,tid) call *%r9 # func(arg,tid)
xchg %eax,%edi # func(arg,tid) exitcode xchg %eax,%edi # func(arg,tid) exitcode
mov (%r15),%eax # experiment
test %eax,%eax # experiment
jz 1f # experiment
mov $60,%eax # __NR_exit(exitcode) mov $60,%eax # __NR_exit(exitcode)
syscall syscall
1: hlt # ctid was corrupted by program!
.endfn sys_clone_linux,globl,hidden .endfn sys_clone_linux,globl,hidden

View file

@ -446,6 +446,7 @@ static int CloneLinux(int (*func)(void *arg, int rc), char *stk, size_t stksz,
sp -= sizeof(int); sp -= sizeof(int);
sp = sp & -alignof(int); sp = sp & -alignof(int);
ctid = (int *)sp; ctid = (int *)sp;
sp -= 8; // experiment
} }
sp = sp & -16; // align the stack sp = sp & -16; // align the stack
if ((rc = sys_clone_linux(flags, sp, ptid, ctid, tls, func, arg)) >= 0) { if ((rc = sys_clone_linux(flags, sp, ptid, ctid, tls, func, arg)) >= 0) {

View file

@ -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 // however this 1mb behavior oddly enough is smart enough to not
// apply if the mapping is a manually-created guard page. // apply if the mapping is a manually-created guard page.
int e = errno; 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)) f | MAP_GROWSDOWN_linux, fd, off))
.addr != MAP_FAILED) { .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) MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)
.addr == p); .addr == p);
dm.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 (needguard) {
if (!IsWindows()) { if (!IsWindows()) {
// make windows fork() code simpler // make windows fork() code simpler
mprotect(p, PAGESIZE, PROT_NONE); mprotect(p, GUARDSIZE, PROT_NONE);
} }
if (IsAsan()) { if (IsAsan()) {
__repstosb((void *)(((intptr_t)p >> 3) + 0x7fff8000), __repstosb((void *)(((intptr_t)p >> 3) + 0x7fff8000),
kAsanStackOverflow, PAGESIZE / 8); kAsanStackOverflow, GUARDSIZE / 8);
} }
} }
} }

View file

@ -122,7 +122,7 @@ extern char ape_stack_align[] __attribute__((__weak__));
*/ */
#define HaveStackMemory(n) \ #define HaveStackMemory(n) \
(IsTiny() || \ (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) { forceinline void CheckLargeStackAllocation(void *p, ssize_t n) {
for (; n > 0; n -= 4096) { for (; n > 0; n -= 4096) {

View file

@ -16,9 +16,9 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/intrin/likely.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/intrin/asan.internal.h" #include "libc/intrin/asan.internal.h"
#include "libc/intrin/likely.h"
#include "libc/str/str.h" #include "libc/str/str.h"
typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(16))); typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(16)));

View file

@ -45,10 +45,6 @@ $(LIBC_STR_A).pkg: \
$(LIBC_STR_A_OBJS) \ $(LIBC_STR_A_OBJS) \
$(foreach x,$(LIBC_STR_A_DIRECTDEPS),$($(x)_A).pkg) $(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/wmemset.o \
o/$(MODE)/libc/str/memset16.o \ o/$(MODE)/libc/str/memset16.o \
o/$(MODE)/libc/str/dosdatetimetounix.o: private \ o/$(MODE)/libc/str/dosdatetimetounix.o: private \

View file

@ -27,7 +27,7 @@
errno_t pthread_attr_init(pthread_attr_t *attr) { errno_t pthread_attr_init(pthread_attr_t *attr) {
*attr = (pthread_attr_t){ *attr = (pthread_attr_t){
.__stacksize = GetStackSize(), .__stacksize = GetStackSize(),
.__guardsize = PAGESIZE, .__guardsize = GUARDSIZE,
}; };
return 0; return 0;
} }

View file

@ -174,12 +174,12 @@ static errno_t pthread_create_impl(pthread_t *thread,
pt->flags = PT_OWNSTACK; pt->flags = PT_OWNSTACK;
pt->attr.__stacksize = MAX(pt->attr.__stacksize, GetStackSize()); pt->attr.__stacksize = MAX(pt->attr.__stacksize, GetStackSize());
pt->attr.__stacksize = _roundup2pow(pt->attr.__stacksize); pt->attr.__stacksize = _roundup2pow(pt->attr.__stacksize);
pt->attr.__guardsize = ROUNDUP(pt->attr.__guardsize, PAGESIZE); pt->attr.__guardsize = ROUNDUP(pt->attr.__guardsize, GUARDSIZE);
if (pt->attr.__guardsize + PAGESIZE >= pt->attr.__stacksize) { if (pt->attr.__guardsize + GUARDSIZE >= pt->attr.__stacksize) {
_pthread_free(pt); _pthread_free(pt);
return EINVAL; return EINVAL;
} }
if (pt->attr.__guardsize == PAGESIZE) { if (pt->attr.__guardsize == GUARDSIZE) {
// user is wisely using smaller stacks with default guard size // user is wisely using smaller stacks with default guard size
pt->attr.__stackaddr = pt->attr.__stackaddr =
mmap(0, pt->attr.__stacksize, PROT_READ | PROT_WRITE, mmap(0, pt->attr.__stacksize, PROT_READ | PROT_WRITE,

View file

@ -46,6 +46,7 @@
#include "libc/runtime/internal.h" #include "libc/runtime/internal.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/runtime/stack.h" #include "libc/runtime/stack.h"
#include "libc/runtime/sysconf.h"
#include "libc/sock/sock.h" #include "libc/sock/sock.h"
#include "libc/sock/struct/pollfd.h" #include "libc/sock/struct/pollfd.h"
#include "libc/sock/struct/sockaddr.h" #include "libc/sock/struct/sockaddr.h"
@ -114,7 +115,7 @@
#define SOCK_MAX 100 // max length of socket queue #define SOCK_MAX 100 // max length of socket queue
#define MSG_BUF 512 // small response lookaside #define MSG_BUF 512 // small response lookaside
#define INBUF_SIZE PAGESIZE #define INBUF_SIZE FRAMESIZE
#define OUTBUF_SIZE 8192 #define OUTBUF_SIZE 8192
#define TB_BYTES (1u << TB_CIDR) #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 // so if it gets hacked it'll at least crash instead of get compromised
void *NewSafeBuffer(size_t n) { void *NewSafeBuffer(size_t n) {
char *p; char *p;
size_t m = ROUNDUP(n, PAGESIZE); long pagesize = sysconf(_SC_PAGESIZE);
_npassert((p = valloc(m + PAGESIZE))); size_t m = ROUNDUP(n, pagesize);
_npassert(!mprotect(p + m, PAGESIZE, PROT_NONE)); _npassert((p = valloc(m + pagesize)));
_npassert(!mprotect(p + m, pagesize, PROT_NONE));
return p; return p;
} }
// frees memory with hardware-accelerated buffer overflow detection // frees memory with hardware-accelerated buffer overflow detection
void FreeSafeBuffer(void *p) { void FreeSafeBuffer(void *p) {
long pagesize = sysconf(_SC_PAGESIZE);
size_t n = malloc_usable_size(p); 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)); _npassert(!mprotect(p, m, PROT_READ | PROT_WRITE));
free(p); free(p);
} }

View file

@ -125,8 +125,8 @@ TEST(setrlimit, testMemoryLimit) {
ASSERT_NE(-1, (wstatus = xspawn(0))); ASSERT_NE(-1, (wstatus = xspawn(0)));
if (wstatus == -2) { if (wstatus == -2) {
ASSERT_EQ(0, SetKernelEnforcedMemoryLimit(MEM)); ASSERT_EQ(0, SetKernelEnforcedMemoryLimit(MEM));
for (gotsome = i = 0; i < (MEM * 2) / PAGESIZE; ++i) { for (gotsome = i = 0; i < (MEM * 2) / GUARDSIZE; ++i) {
p = mmap(0, PAGESIZE, PROT_READ | PROT_WRITE, p = mmap(0, GUARDSIZE, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE | MAP_POPULATE, -1, 0); MAP_ANONYMOUS | MAP_PRIVATE | MAP_POPULATE, -1, 0);
if (p != MAP_FAILED) { if (p != MAP_FAILED) {
gotsome = true; gotsome = true;
@ -138,7 +138,7 @@ TEST(setrlimit, testMemoryLimit) {
ASSERT_EQ(ENOMEM, errno); ASSERT_EQ(ENOMEM, errno);
_Exit(0); _Exit(0);
} }
rngset(p, PAGESIZE, _rand64, -1); rngset(p, GUARDSIZE, _rand64, -1);
} }
_Exit(1); _Exit(1);
} }
@ -158,15 +158,15 @@ TEST(setrlimit, testVirtualMemoryLimit) {
ASSERT_NE(-1, (wstatus = xspawn(0))); ASSERT_NE(-1, (wstatus = xspawn(0)));
if (wstatus == -2) { if (wstatus == -2) {
ASSERT_EQ(0, setrlimit(RLIMIT_AS, &(struct rlimit){MEM, MEM})); ASSERT_EQ(0, setrlimit(RLIMIT_AS, &(struct rlimit){MEM, MEM}));
for (i = 0; i < (MEM * 2) / PAGESIZE; ++i) { for (i = 0; i < (MEM * 2) / GUARDSIZE; ++i) {
p = sys_mmap(0, PAGESIZE, PROT_READ | PROT_WRITE, p = sys_mmap(0, GUARDSIZE, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE | MAP_POPULATE, -1, 0) MAP_ANONYMOUS | MAP_PRIVATE | MAP_POPULATE, -1, 0)
.addr; .addr;
if (p == MAP_FAILED) { if (p == MAP_FAILED) {
ASSERT_EQ(ENOMEM, errno); ASSERT_EQ(ENOMEM, errno);
_Exit(0); _Exit(0);
} }
rngset(p, PAGESIZE, _rand64, -1); rngset(p, GUARDSIZE, _rand64, -1);
} }
_Exit(1); _Exit(1);
} }
@ -188,15 +188,15 @@ TEST(setrlimit, testDataMemoryLimit) {
ASSERT_NE(-1, (wstatus = xspawn(0))); ASSERT_NE(-1, (wstatus = xspawn(0)));
if (wstatus == -2) { if (wstatus == -2) {
ASSERT_EQ(0, setrlimit(RLIMIT_DATA, &(struct rlimit){MEM, MEM})); ASSERT_EQ(0, setrlimit(RLIMIT_DATA, &(struct rlimit){MEM, MEM}));
for (i = 0; i < (MEM * 2) / PAGESIZE; ++i) { for (i = 0; i < (MEM * 2) / GUARDSIZE; ++i) {
p = sys_mmap(0, PAGESIZE, PROT_READ | PROT_WRITE, p = sys_mmap(0, GUARDSIZE, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE | MAP_POPULATE, -1, 0) MAP_ANONYMOUS | MAP_PRIVATE | MAP_POPULATE, -1, 0)
.addr; .addr;
if (p == MAP_FAILED) { if (p == MAP_FAILED) {
ASSERT_EQ(ENOMEM, errno); ASSERT_EQ(ENOMEM, errno);
_Exit(0); _Exit(0);
} }
rngset(p, PAGESIZE, _rand64, -1); rngset(p, GUARDSIZE, _rand64, -1);
} }
_Exit(1); _Exit(1);
} }

View file

@ -226,9 +226,9 @@ TEST(ksnprintf, fuzzTheUnbreakable) {
size_t i; size_t i;
uint64_t x; uint64_t x;
char *f, b[32]; 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)); 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"); strcpy(f, "hello %s\n");
EXPECT_EQ(12, ksnprintf(b, sizeof(b), f, "world")); EXPECT_EQ(12, ksnprintf(b, sizeof(b), f, "world"));
EXPECT_STREQ("hello world\n", b); EXPECT_STREQ("hello world\n", b);
@ -240,7 +240,7 @@ TEST(ksnprintf, fuzzTheUnbreakable) {
f[Rando() & 15] = '%'; f[Rando() & 15] = '%';
ksnprintf(b, sizeof(b), f, lemur64(), lemur64(), lemur64()); 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) { TEST(kprintf, testFailure_wontClobberErrnoAndBypassesSystemCallSupport) {

View file

@ -16,14 +16,14 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/intrin/popcnt.h"
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/intrin/popcnt.h"
#include "libc/testlib/ezbench.h" #include "libc/testlib/ezbench.h"
#include "libc/testlib/hyperion.h" #include "libc/testlib/hyperion.h"
#include "libc/testlib/testlib.h" #include "libc/testlib/testlib.h"
void SetUpOnce(void) { void SetUpOnce(void) {
ASSERT_SYS(0, 0, pledge("stdio", 0)); ASSERT_SYS(0, 0, pledge("stdio rpath", 0));
} }
TEST(popcnt, test) { TEST(popcnt, test) {

View file

@ -49,7 +49,7 @@ TEST(brk, underflowsEnd_returnsEinval) {
} }
TEST(sbrk, underflowsEnd_returnsEinval) { TEST(sbrk, underflowsEnd_returnsEinval) {
ASSERT_SYS(EINVAL, MAP_FAILED, sbrk(-PAGESIZE)); ASSERT_SYS(EINVAL, MAP_FAILED, sbrk(-GUARDSIZE));
} }
TEST(sbrk, giantDelta_returnsEnomem) { TEST(sbrk, giantDelta_returnsEnomem) {
@ -73,11 +73,11 @@ TEST(sbrk, overlapsExistingMapping_failsWithEexist) {
TEST(sbrk, testGrowAndShrink) { TEST(sbrk, testGrowAndShrink) {
SPAWN(fork); SPAWN(fork);
ASSERT_FALSE(testlib_memoryexists(_end)); ASSERT_FALSE(testlib_memoryexists(_end));
ASSERT_SYS(0, _end, sbrk(PAGESIZE)); ASSERT_SYS(0, _end, sbrk(GUARDSIZE));
ASSERT_SYS(0, _end + PAGESIZE, sbrk(0)); ASSERT_SYS(0, _end + GUARDSIZE, sbrk(0));
ASSERT_TRUE(testlib_memoryexists(_end)); ASSERT_TRUE(testlib_memoryexists(_end));
ASSERT_FALSE(testlib_memoryexists(_end + PAGESIZE)); ASSERT_FALSE(testlib_memoryexists(_end + GUARDSIZE));
ASSERT_SYS(0, _end + PAGESIZE, sbrk(-PAGESIZE)); ASSERT_SYS(0, _end + GUARDSIZE, sbrk(-GUARDSIZE));
ASSERT_FALSE(testlib_memoryexists(_end)); ASSERT_FALSE(testlib_memoryexists(_end));
EXITS(0); EXITS(0);
} }
@ -85,9 +85,9 @@ TEST(sbrk, testGrowAndShrink) {
TEST(brk, testGrowAndShrink) { TEST(brk, testGrowAndShrink) {
SPAWN(fork); SPAWN(fork);
ASSERT_FALSE(testlib_memoryexists(_end)); ASSERT_FALSE(testlib_memoryexists(_end));
ASSERT_EQ(0, brk(_end + PAGESIZE)); ASSERT_EQ(0, brk(_end + GUARDSIZE));
ASSERT_TRUE(testlib_memoryexists(_end)); ASSERT_TRUE(testlib_memoryexists(_end));
ASSERT_FALSE(testlib_memoryexists(_end + PAGESIZE)); ASSERT_FALSE(testlib_memoryexists(_end + GUARDSIZE));
ASSERT_EQ(0, brk(_end)); ASSERT_EQ(0, brk(_end));
EXITS(0); EXITS(0);
} }

View file

@ -94,9 +94,9 @@ void TearDown(void) {
} }
TEST(mprotect, testOkMemory) { TEST(mprotect, testOkMemory) {
char *p = gc(memalign(PAGESIZE, PAGESIZE)); char *p = gc(memalign(GUARDSIZE, GUARDSIZE));
p[0] = 0; 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; p[0] = 1;
EXPECT_EQ(1, p[0]); EXPECT_EQ(1, p[0]);
EXPECT_FALSE(gotsegv); EXPECT_FALSE(gotsegv);
@ -105,19 +105,19 @@ TEST(mprotect, testOkMemory) {
TEST(mprotect, testSegfault_writeToReadOnlyAnonymous) { TEST(mprotect, testSegfault_writeToReadOnlyAnonymous) {
volatile char *p; volatile char *p;
p = gc(memalign(PAGESIZE, PAGESIZE)); p = gc(memalign(GUARDSIZE, GUARDSIZE));
EXPECT_FALSE(gotsegv); EXPECT_FALSE(gotsegv);
p[0] = 1; p[0] = 1;
EXPECT_FALSE(gotsegv); EXPECT_FALSE(gotsegv);
EXPECT_FALSE(gotbusted); EXPECT_FALSE(gotbusted);
EXPECT_NE(-1, mprotect(p, PAGESIZE, PROT_READ)); EXPECT_NE(-1, mprotect(p, GUARDSIZE, PROT_READ));
_missingno(p[0]); _missingno(p[0]);
EXPECT_FALSE(gotsegv); EXPECT_FALSE(gotsegv);
EXPECT_FALSE(gotbusted); EXPECT_FALSE(gotbusted);
p[0] = 2; p[0] = 2;
EXPECT_TRUE(gotsegv | gotbusted); EXPECT_TRUE(gotsegv | gotbusted);
EXPECT_EQ(1, p[0]); 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) { TEST(mprotect, testExecOnly_canExecute) {
@ -137,11 +137,11 @@ TEST(mprotect, testExecOnly_canExecute) {
TEST(mprotect, testProtNone_cantEvenRead) { TEST(mprotect, testProtNone_cantEvenRead) {
volatile char *p; volatile char *p;
p = gc(memalign(PAGESIZE, PAGESIZE)); p = gc(memalign(GUARDSIZE, GUARDSIZE));
EXPECT_NE(-1, mprotect(p, PAGESIZE, PROT_NONE)); EXPECT_NE(-1, mprotect(p, GUARDSIZE, PROT_NONE));
_missingno(p[0]); _missingno(p[0]);
EXPECT_TRUE(gotsegv | gotbusted); 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[] = { static const char kRet31337[] = {
@ -150,24 +150,24 @@ static const char kRet31337[] = {
}; };
TEST(mprotect, testExecJit_actuallyWorks) { TEST(mprotect, testExecJit_actuallyWorks) {
int (*p)(void) = gc(memalign(PAGESIZE, PAGESIZE)); int (*p)(void) = gc(memalign(GUARDSIZE, GUARDSIZE));
memcpy(p, kRet31337, sizeof(kRet31337)); 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_EQ(31337, p());
EXPECT_FALSE(gotsegv); EXPECT_FALSE(gotsegv);
EXPECT_FALSE(gotbusted); 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) { TEST(mprotect, testRwxMap_vonNeumannRules) {
if (IsOpenbsd()) return; // boo if (IsOpenbsd()) return; // boo
int (*p)(void) = gc(memalign(PAGESIZE, PAGESIZE)); int (*p)(void) = gc(memalign(GUARDSIZE, GUARDSIZE));
memcpy(p, kRet31337, sizeof(kRet31337)); 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_EQ(31337, p());
EXPECT_FALSE(gotsegv); EXPECT_FALSE(gotsegv);
EXPECT_FALSE(gotbusted); 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) { TEST(mprotect, testExecuteFlatFileMapOpenedAsReadonly) {
@ -202,13 +202,13 @@ TEST(mprotect, testFileMap_canChangeToExecWhileOpenInRdwrMode) {
} }
TEST(mprotect, testBadProt_failsEinval) { 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(-1, mprotect(p, 9999, -1));
EXPECT_EQ(EINVAL, errno); EXPECT_EQ(EINVAL, errno);
} }
TEST(mprotect, testZeroSize_doesNothing) { 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)); EXPECT_NE(-1, mprotect(p, 0, PROT_READ));
p[0] = 1; p[0] = 1;
EXPECT_FALSE(gotsegv); EXPECT_FALSE(gotsegv);

View file

@ -24,8 +24,8 @@ int init_mparams(void) {
size_t gsize; size_t gsize;
#if defined(__COSMOPOLITAN__) #if defined(__COSMOPOLITAN__)
psize = 4096; psize = FRAMESIZE;
gsize = 65536; gsize = FRAMESIZE;
#elif !defined(WIN32) #elif !defined(WIN32)
psize = malloc_getpagesize; psize = malloc_getpagesize;
gsize = ((DEFAULT_GRANULARITY != 0)? DEFAULT_GRANULARITY : psize); gsize = ((DEFAULT_GRANULARITY != 0)? DEFAULT_GRANULARITY : psize);

View file

@ -155,10 +155,6 @@ o/$(MODE)/third_party/lua/lvm.o: private \
OVERRIDE_CFLAGS += \ OVERRIDE_CFLAGS += \
-fno-gcse -fno-gcse
o/$(MODE)/third_party/lua/lauxlib.o: private \
OVERRIDE_CFLAGS += \
-DSTACK_FRAME_UNLIMITED
$(THIRD_PARTY_LUA_A_OBJS): private \ $(THIRD_PARTY_LUA_A_OBJS): private \
OVERRIDE_CFLAGS += \ OVERRIDE_CFLAGS += \
-ffunction-sections \ -ffunction-sections \

View file

@ -22,8 +22,8 @@
#include "libc/intrin/likely.h" #include "libc/intrin/likely.h"
#include "libc/log/log.h" #include "libc/log/log.h"
#include "libc/log/rop.h" #include "libc/log/rop.h"
#include "libc/mem/mem.h"
#include "libc/mem/gc.internal.h" #include "libc/mem/gc.internal.h"
#include "libc/mem/mem.h"
#include "libc/runtime/stack.h" #include "libc/runtime/stack.h"
#include "libc/stdio/append.h" #include "libc/stdio/append.h"
#include "libc/stdio/strlist.internal.h" #include "libc/stdio/strlist.internal.h"
@ -169,7 +169,7 @@ static int SerializeTable(lua_State *L, char **buf, int idx,
bool multi; bool multi;
bool isarray; bool isarray;
lua_Unsigned n; lua_Unsigned n;
if (UNLIKELY(!HaveStackMemory(PAGESIZE))) { if (UNLIKELY(!HaveStackMemory(GUARDSIZE))) {
z->reason = "out of stack"; z->reason = "out of stack";
return -1; return -1;
} }

View file

@ -353,7 +353,7 @@ static int SerializeTable(lua_State *L, char **buf, int idx,
int rc; int rc;
bool multi; bool multi;
intptr_t rsp, bot; intptr_t rsp, bot;
if (UNLIKELY(!HaveStackMemory(PAGESIZE))) { if (UNLIKELY(!HaveStackMemory(GUARDSIZE))) {
z->reason = "out of stack"; z->reason = "out of stack";
return -1; return -1;
} }

View file

@ -171,8 +171,8 @@ o/$(MODE)/third_party/make/hash.o: private \
$(THIRD_PARTY_MAKE_OBJS): private \ $(THIRD_PARTY_MAKE_OBJS): private \
OVERRIDE_CFLAGS += \ OVERRIDE_CFLAGS += \
-DNO_ARCHIVES \ -DNO_ARCHIVES \
-DSTACK_FRAME_UNLIMITED \
-DHAVE_CONFIG_H \ -DHAVE_CONFIG_H \
-DSTACK_FRAME_UNLIMITED \
-DINCLUDEDIR=\".\" \ -DINCLUDEDIR=\".\" \
-DLIBDIR=\".\" \ -DLIBDIR=\".\" \
-DLOCALEDIR=\".\" -DLOCALEDIR=\".\"

View file

@ -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 o/$(MODE)/third_party/mbedtls/test/%.com.runs: o/$(MODE)/third_party/mbedtls/test/%.com
@$(COMPILE) -ACHECK -wtT$@ $< $(TESTARGS) @$(COMPILE) -ACHECK -wtT$@ $< $(TESTARGS)
$(THIRD_PARTY_MBEDTLS_TEST_OBJS): private \
OVERRIDE_CFLAGS += \
-DSTACK_FRAME_UNLIMITED
o/$(MODE)/third_party/mbedtls/test/lib.o: private \ o/$(MODE)/third_party/mbedtls/test/lib.o: private \
OVERRIDE_CFLAGS += \ OVERRIDE_CFLAGS += \
-fdata-sections \ -fdata-sections \

View file

@ -199,10 +199,6 @@ o/tiny/third_party/quickjs/call.o: private \
OVERRIDE_CFLAGS += \ OVERRIDE_CFLAGS += \
-O2 -O2
o/$(MODE)/third_party/quickjs/unicode_gen.o: private \
OVERRIDE_CPPFLAGS += \
-DSTACK_FRAME_UNLIMITED
# TODO(jart): Replace alloca() calls with malloc(). # TODO(jart): Replace alloca() calls with malloc().
o/$(MODE)/third_party/quickjs/libregexp.o \ o/$(MODE)/third_party/quickjs/libregexp.o \
o/$(MODE)/third_party/quickjs/quickjs.o: private \ o/$(MODE)/third_party/quickjs/quickjs.o: private \

View file

@ -22,11 +22,11 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#include "libc/mem/alg.h"
#include "libc/assert.h" #include "libc/assert.h"
#include "libc/fmt/conv.h" #include "libc/fmt/conv.h"
#include "libc/fmt/fmt.h" #include "libc/fmt/fmt.h"
#include "libc/log/log.h" #include "libc/log/log.h"
#include "libc/mem/alg.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h" #include "libc/stdio/stdio.h"

View file

@ -60,7 +60,7 @@ $(THIRD_PARTY_STB_A_OBJS): private \
-ffunction-sections \ -ffunction-sections \
-fdata-sections -fdata-sections
$(THIRD_PARTY_STB_A_OBJS): private \ o/$(MODE)/third_party/stb/stb_vorbis.o: private \
OVERRIDE_CPPFLAGS += \ OVERRIDE_CPPFLAGS += \
-DSTACK_FRAME_UNLIMITED -DSTACK_FRAME_UNLIMITED

View file

@ -162,13 +162,6 @@ o/$(MODE)/third_party/zip/zipup.o: private \
-DZIP64_SUPPORT \ -DZIP64_SUPPORT \
-DBZIP2_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 .PHONY: o/$(MODE)/third_party/zip
o/$(MODE)/third_party/zip: \ o/$(MODE)/third_party/zip: \
$(THIRD_PARTY_ZIP_BINS) \ $(THIRD_PARTY_ZIP_BINS) \

View file

@ -48,6 +48,9 @@
// MISSING #include "os2/os2zip.h" // MISSING #include "os2/os2zip.h"
#endif #endif
#undef PAGESIZE
#define PAGESIZE FRAMESIZE
#if defined(MMAP) #if defined(MMAP)
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/weirdtypes.h" #include "libc/calls/weirdtypes.h"

View file

@ -153,6 +153,7 @@
(defconst cosmo-cpp-constants-cosmopolitan (defconst cosmo-cpp-constants-cosmopolitan
'("__SAUCE__" '("__SAUCE__"
"PAGESIZE" "PAGESIZE"
"GUARDSIZE"
"FRAMESIZE" "FRAMESIZE"
"BIGPAGESIZE" "BIGPAGESIZE"
"STACKSIZE" "STACKSIZE"

View file

@ -98,7 +98,7 @@ static struct DecodeJson Parse(struct lua_State *L, const char *p,
if (UNLIKELY(!depth)) { if (UNLIKELY(!depth)) {
return (struct DecodeJson){-1, "maximum depth exceeded"}; return (struct DecodeJson){-1, "maximum depth exceeded"};
} }
if (UNLIKELY(!HaveStackMemory(PAGESIZE))) { if (UNLIKELY(!HaveStackMemory(GUARDSIZE))) {
return (struct DecodeJson){-1, "out of stack"}; return (struct DecodeJson){-1, "out of stack"};
} }
for (a = p, d = +1; p < e;) { for (a = p, d = +1; p < e;) {

View file

@ -481,17 +481,17 @@ static void *NewBoard(size_t *out_size) {
char *p; char *p;
size_t s, n, k; size_t s, n, k;
s = (byn * bxn) >> 3; s = (byn * bxn) >> 3;
k = PAGESIZE + ROUNDUP(s, PAGESIZE); k = GUARDSIZE + ROUNDUP(s, GUARDSIZE);
n = ROUNDUP(k + PAGESIZE, FRAMESIZE); n = ROUNDUP(k + GUARDSIZE, FRAMESIZE);
p = _mapanon(n); p = _mapanon(n);
mprotect(p, PAGESIZE, 0); mprotect(p, GUARDSIZE, 0);
mprotect(p + k, n - k, 0); mprotect(p + k, n - k, 0);
if (out_size) *out_size = n; if (out_size) *out_size = n;
return p + PAGESIZE; return p + GUARDSIZE;
} }
static void FreeBoard(void *p, size_t n) { static void FreeBoard(void *p, size_t n) {
munmap((char *)p - PAGESIZE, n); munmap((char *)p - GUARDSIZE, n);
} }
static void AllocateBoardsWithHardwareAcceleratedMemorySafety(void) { static void AllocateBoardsWithHardwareAcceleratedMemorySafety(void) {