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/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 \

View file

@ -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,

View file

@ -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"

View file

@ -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 */

View file

@ -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);
}

View file

@ -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);

View file

@ -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,

View file

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

View file

@ -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

View file

@ -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) {

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
// 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);
}
}
}

View file

@ -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) {

View file

@ -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)));

View file

@ -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 \

View file

@ -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;
}

View file

@ -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,

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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) {

View file

@ -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) {

View file

@ -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);
}

View file

@ -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);

View file

@ -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);

View file

@ -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 \

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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=\".\"

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
@$(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 \

View file

@ -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 \

View file

@ -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"

View file

@ -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

View file

@ -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) \

View file

@ -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"

View file

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

View file

@ -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;) {

View file

@ -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) {