mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +00:00
Increase stack size to 128k and guard size to 16k
This improves our compatibility with Apple M1.
This commit is contained in:
parent
57c0dcdc29
commit
dd04aeba1c
36 changed files with 109 additions and 125 deletions
|
@ -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 \
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
/* TODO(jart): delete */
|
||||
|
||||
#define kGuard PAGESIZE
|
||||
#define kGuard GUARDSIZE
|
||||
#define kGrain FRAMESIZE
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)));
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
4
third_party/dlmalloc/init.inc
vendored
4
third_party/dlmalloc/init.inc
vendored
|
@ -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);
|
||||
|
|
4
third_party/lua/lua.mk
vendored
4
third_party/lua/lua.mk
vendored
|
@ -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 \
|
||||
|
|
4
third_party/lua/luaencodejsondata.c
vendored
4
third_party/lua/luaencodejsondata.c
vendored
|
@ -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;
|
||||
}
|
||||
|
|
2
third_party/lua/luaencodeluadata.c
vendored
2
third_party/lua/luaencodeluadata.c
vendored
|
@ -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;
|
||||
}
|
||||
|
|
2
third_party/make/make.mk
vendored
2
third_party/make/make.mk
vendored
|
@ -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=\".\"
|
||||
|
|
4
third_party/mbedtls/test/test.mk
vendored
4
third_party/mbedtls/test/test.mk
vendored
|
@ -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 \
|
||||
|
|
4
third_party/quickjs/quickjs.mk
vendored
4
third_party/quickjs/quickjs.mk
vendored
|
@ -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 \
|
||||
|
|
2
third_party/quickjs/unicode_gen.c
vendored
2
third_party/quickjs/unicode_gen.c
vendored
|
@ -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"
|
||||
|
|
2
third_party/stb/stb.mk
vendored
2
third_party/stb/stb.mk
vendored
|
@ -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
|
||||
|
||||
|
|
7
third_party/zip/zip.mk
vendored
7
third_party/zip/zip.mk
vendored
|
@ -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) \
|
||||
|
|
3
third_party/zip/zipup.c
vendored
3
third_party/zip/zipup.c
vendored
|
@ -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"
|
||||
|
|
|
@ -153,6 +153,7 @@
|
|||
(defconst cosmo-cpp-constants-cosmopolitan
|
||||
'("__SAUCE__"
|
||||
"PAGESIZE"
|
||||
"GUARDSIZE"
|
||||
"FRAMESIZE"
|
||||
"BIGPAGESIZE"
|
||||
"STACKSIZE"
|
||||
|
|
|
@ -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;) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue