mirror of
				https://github.com/jart/cosmopolitan.git
				synced 2025-10-27 03:16:44 +00:00 
			
		
		
		
	Fix some todos
This commit is contained in:
		
							parent
							
								
									9d372f48dd
								
							
						
					
					
						commit
						9cc4f33c76
					
				
					 13 changed files with 261 additions and 139 deletions
				
			
		
							
								
								
									
										17
									
								
								ape/ape-m1.c
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								ape/ape-m1.c
									
										
									
									
									
								
							|  | @ -22,6 +22,7 @@ | ||||||
| #include <libkern/OSCacheControl.h> | #include <libkern/OSCacheControl.h> | ||||||
| #include <limits.h> | #include <limits.h> | ||||||
| #include <pthread.h> | #include <pthread.h> | ||||||
|  | #include <semaphore.h> | ||||||
| #include <signal.h> | #include <signal.h> | ||||||
| #include <stdarg.h> | #include <stdarg.h> | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
|  | @ -30,7 +31,6 @@ | ||||||
| #include <sys/uio.h> | #include <sys/uio.h> | ||||||
| #include <time.h> | #include <time.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| #include <semaphore.h> |  | ||||||
| 
 | 
 | ||||||
| #define pagesz         16384 | #define pagesz         16384 | ||||||
| #define SYSLIB_MAGIC   ('s' | 'l' << 8 | 'i' << 16 | 'b' << 24) | #define SYSLIB_MAGIC   ('s' | 'l' << 8 | 'i' << 16 | 'b' << 24) | ||||||
|  | @ -89,6 +89,8 @@ struct Syslib { | ||||||
|   long (*sem_post)(int *); |   long (*sem_post)(int *); | ||||||
|   long (*sem_wait)(int *); |   long (*sem_wait)(int *); | ||||||
|   long (*sem_trywait)(int *); |   long (*sem_trywait)(int *); | ||||||
|  |   long (*getrlimit)(int, struct rlimit *); | ||||||
|  |   long (*setrlimit)(int, const struct rlimit *); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #define ELFCLASS32  1 | #define ELFCLASS32  1 | ||||||
|  | @ -814,7 +816,8 @@ static long sys_getentropy(void *buf, size_t buflen) { | ||||||
|   return sysret(getentropy(buf, buflen)); |   return sysret(getentropy(buf, buflen)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static long sys_sem_open(const char *name, int oflags, mode_t mode, unsigned value) { | static long sys_sem_open(const char *name, int oflags, mode_t mode, | ||||||
|  |                          unsigned value) { | ||||||
|   return sysret((long)sem_open(name, oflags, mode, value)); |   return sysret((long)sem_open(name, oflags, mode, value)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -838,6 +841,14 @@ static long sys_sem_trywait(sem_t *sem) { | ||||||
|   return sysret(sem_trywait(sem)); |   return sysret(sem_trywait(sem)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static long sys_getrlimit(int which, struct rlimit *rlim) { | ||||||
|  |   return sysret(getrlimit(which, rlim)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static long sys_setrlimit(int which, const struct rlimit *rlim) { | ||||||
|  |   return sysret(setrlimit(which, rlim)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static long sys_write(int fd, const void *data, size_t size) { | static long sys_write(int fd, const void *data, size_t size) { | ||||||
|   return sysret(write(fd, data, size)); |   return sysret(write(fd, data, size)); | ||||||
| } | } | ||||||
|  | @ -930,6 +941,8 @@ int main(int argc, char **argv, char **envp) { | ||||||
|   M->lib.sem_post = sys_sem_post; |   M->lib.sem_post = sys_sem_post; | ||||||
|   M->lib.sem_wait = sys_sem_wait; |   M->lib.sem_wait = sys_sem_wait; | ||||||
|   M->lib.sem_trywait = sys_sem_trywait; |   M->lib.sem_trywait = sys_sem_trywait; | ||||||
|  |   M->lib.getrlimit = sys_getrlimit; | ||||||
|  |   M->lib.setrlimit = sys_setrlimit; | ||||||
| 
 | 
 | ||||||
|   /* getenv("_") is close enough to at_execfn */ |   /* getenv("_") is close enough to at_execfn */ | ||||||
|   execfn = argc > 0 ? argv[0] : 0; |   execfn = argc > 0 ? argv[0] : 0; | ||||||
|  |  | ||||||
										
											Binary file not shown.
										
									
								
							|  | @ -100,7 +100,7 @@ static int cosmo_clock_nanosleep(int clock, int flags, | ||||||
|   if (timespec_cmp(remain, quantum) > 0) { |   if (timespec_cmp(remain, quantum) > 0) { | ||||||
|     waitfor = timespec_sub(remain, quantum); |     waitfor = timespec_sub(remain, quantum); | ||||||
|     if (sys_clock_nanosleep(sleep_clock, 0, &waitfor, rem) == -1) { |     if (sys_clock_nanosleep(sleep_clock, 0, &waitfor, rem) == -1) { | ||||||
|       if (rem && errno == EINTR) { |       if (!flags && rem && errno == EINTR) { | ||||||
|         *rem = timespec_add(*rem, quantum); |         *rem = timespec_add(*rem, quantum); | ||||||
|       } |       } | ||||||
|       return -1; |       return -1; | ||||||
|  |  | ||||||
|  | @ -1,110 +0,0 @@ | ||||||
| /*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8     -*-│
 |  | ||||||
| │vi: set et ft=asm ts=8 tw=8 fenc=utf-8                                     :vi│ |  | ||||||
| ╞══════════════════════════════════════════════════════════════════════════════╡ |  | ||||||
| │ Copyright 2022 Justine Alexandra Roberts Tunney                              │ |  | ||||||
| │                                                                              │ |  | ||||||
| │ Permission to use, copy, modify, and/or distribute this software for         │ |  | ||||||
| │ any purpose with or without fee is hereby granted, provided that the         │ |  | ||||||
| │ above copyright notice and this permission notice appear in all copies.      │ |  | ||||||
| │                                                                              │ |  | ||||||
| │ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL                │ |  | ||||||
| │ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED                │ |  | ||||||
| │ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE             │ |  | ||||||
| │ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL         │ |  | ||||||
| │ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR        │ |  | ||||||
| │ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER               │ |  | ||||||
| │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │ |  | ||||||
| │ PERFORMANCE OF THIS SOFTWARE.                                                │ |  | ||||||
| ╚─────────────────────────────────────────────────────────────────────────────*/ |  | ||||||
| #include "libc/macros.internal.h" |  | ||||||
| .privileged |  | ||||||
| 
 |  | ||||||
| diagnose_syscall: |  | ||||||
| 	push	%rbp |  | ||||||
| 	mov	%rsp,%rbp |  | ||||||
| 	push	%rbx |  | ||||||
| 	push	%r12 |  | ||||||
| 	push	%r13 |  | ||||||
| 	push	%r14 |  | ||||||
| 	push	%r15 |  | ||||||
| 
 |  | ||||||
| 	mov	$0x7fffffff,%eax |  | ||||||
| 	add	$4,%eax				# set sf/of/pf |  | ||||||
| 
 |  | ||||||
| 	mov	%rdi,%rax			# nr |  | ||||||
| 	mov	%rsi,%rdi			# arg 1 |  | ||||||
| 	mov	%rdx,%rsi			# arg 2 |  | ||||||
| 	mov	%rcx,%rdx			# arg 3 |  | ||||||
| 	mov	%r8,%r10			# arg 4 |  | ||||||
| 	mov	%r9,%r8				# arg 5 |  | ||||||
| 	mov	16(%rbp),%r9			# arg 6 |  | ||||||
| 	push	24(%rbp)			# arg 7 |  | ||||||
| 	push	%rax				# fake ret addr |  | ||||||
| 	mov	32(%rbp),%r12			# ucontext before |  | ||||||
| 	mov	40(%rbp),%r13			# ucontext after |  | ||||||
| 	xor	%ecx,%ecx |  | ||||||
| 	xor	%r11d,%r11d |  | ||||||
| 	mov	$0x5555555555555555,%r11 |  | ||||||
| 	mov	$0x5555555555555555,%r14 |  | ||||||
| 	mov	$0x5555555555555555,%r15 |  | ||||||
| 	mov	$0x5555555555555555,%rbx |  | ||||||
| 
 |  | ||||||
| //	save machine state before system call |  | ||||||
| 	pushf |  | ||||||
| 	pop	176(%r12) |  | ||||||
| 	mov	%r8,40(%r12) |  | ||||||
| 	mov	%r9,48(%r12) |  | ||||||
| 	mov	%r10,56(%r12) |  | ||||||
| 	mov	%r11,64(%r12) |  | ||||||
| 	mov	%r12,72(%r12) |  | ||||||
| 	mov	%r13,80(%r12) |  | ||||||
| 	mov	%r14,88(%r12) |  | ||||||
| 	mov	%r15,96(%r12) |  | ||||||
| 	mov	%rdi,104(%r12) |  | ||||||
| 	mov	%rsi,112(%r12) |  | ||||||
| 	mov	%rbp,120(%r12) |  | ||||||
| 	mov	%rbx,128(%r12) |  | ||||||
| 	mov	%rdx,136(%r12) |  | ||||||
| 	mov	%rax,144(%r12) |  | ||||||
| 	mov	%rcx,152(%r12) |  | ||||||
| 	push	%rbx |  | ||||||
| 	lea	320(%r12),%rbx |  | ||||||
| 	mov	%rbx,224(%r12)			# set fpregs ptr |  | ||||||
| 	pop	%rbx |  | ||||||
| 
 |  | ||||||
| 	syscall |  | ||||||
| 
 |  | ||||||
| //	save machine state after system call |  | ||||||
| 	pushf |  | ||||||
| 	pop	176(%r13) |  | ||||||
| 	mov	%r8,40(%r13) |  | ||||||
| 	mov	%r9,48(%r13) |  | ||||||
| 	mov	%r10,56(%r13) |  | ||||||
| 	mov	%r11,64(%r13) |  | ||||||
| 	mov	%r12,72(%r13) |  | ||||||
| 	mov	%r13,80(%r13) |  | ||||||
| 	mov	%r14,88(%r13) |  | ||||||
| 	mov	%r15,96(%r13) |  | ||||||
| 	mov	%rdi,104(%r13) |  | ||||||
| 	mov	%rsi,112(%r13) |  | ||||||
| 	mov	%rbp,120(%r13) |  | ||||||
| 	mov	%rbx,128(%r13) |  | ||||||
| 	mov	%rdx,136(%r13) |  | ||||||
| 	mov	%rax,144(%r13) |  | ||||||
| 	mov	%rcx,152(%r13) |  | ||||||
| 	push	%rbx |  | ||||||
| 	lea	320(%r13),%rbx |  | ||||||
| 	mov	%rbx,224(%r13)			# set fpregs ptr |  | ||||||
| 	pop	%rbx |  | ||||||
| 
 |  | ||||||
| 	pop	%r13 |  | ||||||
| 	pop	%r13 |  | ||||||
| 
 |  | ||||||
| 	pop	%r15 |  | ||||||
| 	pop	%r14 |  | ||||||
| 	pop	%r13 |  | ||||||
| 	pop	%r12 |  | ||||||
| 	pop	%rbx |  | ||||||
| 	pop	%rbp |  | ||||||
| 	ret |  | ||||||
| 	.endfn	diagnose_syscall,globl |  | ||||||
|  | @ -18,11 +18,13 @@ | ||||||
| ╚─────────────────────────────────────────────────────────────────────────────*/ | ╚─────────────────────────────────────────────────────────────────────────────*/ | ||||||
| #include "libc/calls/calls.h" | #include "libc/calls/calls.h" | ||||||
| #include "libc/calls/struct/rlimit.internal.h" | #include "libc/calls/struct/rlimit.internal.h" | ||||||
|  | #include "libc/calls/syscall-sysv.internal.h" | ||||||
| #include "libc/dce.h" | #include "libc/dce.h" | ||||||
| #include "libc/intrin/asan.internal.h" | #include "libc/intrin/asan.internal.h" | ||||||
| #include "libc/intrin/describeflags.internal.h" | #include "libc/intrin/describeflags.internal.h" | ||||||
| #include "libc/intrin/strace.internal.h" | #include "libc/intrin/strace.internal.h" | ||||||
| #include "libc/runtime/stack.h" | #include "libc/runtime/stack.h" | ||||||
|  | #include "libc/runtime/syslib.internal.h" | ||||||
| #include "libc/sysv/consts/rlimit.h" | #include "libc/sysv/consts/rlimit.h" | ||||||
| #include "libc/sysv/errfuns.h" | #include "libc/sysv/errfuns.h" | ||||||
| 
 | 
 | ||||||
|  | @ -40,6 +42,8 @@ int getrlimit(int resource, struct rlimit *rlim) { | ||||||
|     rc = einval(); |     rc = einval(); | ||||||
|   } else if (!rlim || (IsAsan() && !__asan_is_valid(rlim, sizeof(*rlim)))) { |   } else if (!rlim || (IsAsan() && !__asan_is_valid(rlim, sizeof(*rlim)))) { | ||||||
|     rc = efault(); |     rc = efault(); | ||||||
|  |   } else if (IsXnuSilicon()) { | ||||||
|  |     rc = _sysret(__syslib->__getrlimit(resource, rlim)); | ||||||
|   } else if (!IsWindows()) { |   } else if (!IsWindows()) { | ||||||
|     rc = sys_getrlimit(resource, rlim); |     rc = sys_getrlimit(resource, rlim); | ||||||
|   } else if (resource == RLIMIT_STACK) { |   } else if (resource == RLIMIT_STACK) { | ||||||
|  |  | ||||||
|  | @ -342,14 +342,18 @@ static textwindows int ProcessMouseEvent(const struct NtInputRecord *r, | ||||||
|   bs &= kNtFromLeft1stButtonPressed | kNtRightmostButtonPressed; |   bs &= kNtFromLeft1stButtonPressed | kNtRightmostButtonPressed; | ||||||
|   if (ev & kNtMouseWheeled) { |   if (ev & kNtMouseWheeled) { | ||||||
|     // scroll wheel (unnatural mode)
 |     // scroll wheel (unnatural mode)
 | ||||||
|     if (!(r->Event.MouseEvent.dwControlKeyState & |  | ||||||
|           (kNtShiftPressed | kNtLeftCtrlPressed | kNtRightCtrlPressed | |  | ||||||
|            kNtLeftAltPressed | kNtRightAltPressed))) { |  | ||||||
|     bool isup = ((int)r->Event.MouseEvent.dwButtonState >> 16) > 0; |     bool isup = ((int)r->Event.MouseEvent.dwButtonState >> 16) > 0; | ||||||
|     if (__ttyconf.magic & kTtyXtMouse) { |     if (__ttyconf.magic & kTtyXtMouse) { | ||||||
|  |       if (r->Event.MouseEvent.dwControlKeyState & | ||||||
|  |           (kNtLeftCtrlPressed | kNtRightCtrlPressed)) { | ||||||
|         e = isup ? 80 : 81; |         e = isup ? 80 : 81; | ||||||
|         goto OutputXtermMouseEvent; |  | ||||||
|       } else { |       } else { | ||||||
|  |         e = isup ? 64 : 65; | ||||||
|  |       } | ||||||
|  |       goto OutputXtermMouseEvent; | ||||||
|  |     } else if (!(r->Event.MouseEvent.dwControlKeyState & | ||||||
|  |                  (kNtShiftPressed | kNtLeftCtrlPressed | kNtRightCtrlPressed | | ||||||
|  |                   kNtLeftAltPressed | kNtRightAltPressed))) { | ||||||
|       // we disable mouse highlighting when the tty is put in raw mode
 |       // we disable mouse highlighting when the tty is put in raw mode
 | ||||||
|       // to mouse wheel events with widely understood vt100 arrow keys
 |       // to mouse wheel events with widely understood vt100 arrow keys
 | ||||||
|       *p++ = 033; |       *p++ = 033; | ||||||
|  | @ -360,7 +364,6 @@ static textwindows int ProcessMouseEvent(const struct NtInputRecord *r, | ||||||
|         *p++ = 'B'; |         *p++ = 'B'; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     } |  | ||||||
|   } else if ((bs || currentbs) && (__ttyconf.magic & kTtyXtMouse)) { |   } else if ((bs || currentbs) && (__ttyconf.magic & kTtyXtMouse)) { | ||||||
|     if (bs && (ev & kNtMouseMoved) && currentbs) { |     if (bs && (ev & kNtMouseMoved) && currentbs) { | ||||||
|       e |= 32;  // dragging
 |       e |= 32;  // dragging
 | ||||||
|  |  | ||||||
|  | @ -19,11 +19,13 @@ | ||||||
| #include "libc/assert.h" | #include "libc/assert.h" | ||||||
| #include "libc/calls/calls.h" | #include "libc/calls/calls.h" | ||||||
| #include "libc/calls/struct/rlimit.internal.h" | #include "libc/calls/struct/rlimit.internal.h" | ||||||
|  | #include "libc/calls/syscall-sysv.internal.h" | ||||||
| #include "libc/dce.h" | #include "libc/dce.h" | ||||||
| #include "libc/intrin/asan.internal.h" | #include "libc/intrin/asan.internal.h" | ||||||
| #include "libc/intrin/describeflags.internal.h" | #include "libc/intrin/describeflags.internal.h" | ||||||
| #include "libc/intrin/strace.internal.h" | #include "libc/intrin/strace.internal.h" | ||||||
| #include "libc/macros.internal.h" | #include "libc/macros.internal.h" | ||||||
|  | #include "libc/runtime/syslib.internal.h" | ||||||
| #include "libc/sysv/consts/rlimit.h" | #include "libc/sysv/consts/rlimit.h" | ||||||
| #include "libc/sysv/errfuns.h" | #include "libc/sysv/errfuns.h" | ||||||
| 
 | 
 | ||||||
|  | @ -79,6 +81,8 @@ int setrlimit(int resource, const struct rlimit *rlim) { | ||||||
|     rc = einval(); |     rc = einval(); | ||||||
|   } else if (!rlim || (IsAsan() && !__asan_is_valid(rlim, sizeof(*rlim)))) { |   } else if (!rlim || (IsAsan() && !__asan_is_valid(rlim, sizeof(*rlim)))) { | ||||||
|     rc = efault(); |     rc = efault(); | ||||||
|  |   } else if (IsXnuSilicon()) { | ||||||
|  |     rc = _sysret(__syslib->__setrlimit(resource, rlim)); | ||||||
|   } else if (!IsWindows()) { |   } else if (!IsWindows()) { | ||||||
|     rc = sys_setrlimit(resource, rlim); |     rc = sys_setrlimit(resource, rlim); | ||||||
|     if (IsXnu() && !rc && resource == RLIMIT_AS) { |     if (IsXnu() && !rc && resource == RLIMIT_AS) { | ||||||
|  |  | ||||||
|  | @ -68,6 +68,8 @@ struct Syslib { | ||||||
|   long (*__sem_post)(int *); |   long (*__sem_post)(int *); | ||||||
|   long (*__sem_wait)(int *); |   long (*__sem_wait)(int *); | ||||||
|   long (*__sem_trywait)(int *); |   long (*__sem_trywait)(int *); | ||||||
|  |   long (*__getrlimit)(int, void *); | ||||||
|  |   long (*__setrlimit)(int, const void *); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| extern struct Syslib *__syslib; | extern struct Syslib *__syslib; | ||||||
|  |  | ||||||
|  | @ -4,7 +4,6 @@ | ||||||
| #define TLS_ALIGNMENT 64 | #define TLS_ALIGNMENT 64 | ||||||
| 
 | 
 | ||||||
| #define TIB_FLAG_VFORKED 1 | #define TIB_FLAG_VFORKED 1 | ||||||
| #define TIB_FLAG_WINCRASHING 2 |  | ||||||
| 
 | 
 | ||||||
| #if !(__ASSEMBLER__ + __LINKER__ + 0) | #if !(__ASSEMBLER__ + __LINKER__ + 0) | ||||||
| COSMOPOLITAN_C_START_ | COSMOPOLITAN_C_START_ | ||||||
|  |  | ||||||
|  | @ -32,10 +32,6 @@ | ||||||
| #include "libc/testlib/testlib.h" | #include "libc/testlib/testlib.h" | ||||||
| #include "libc/time/time.h" | #include "libc/time/time.h" | ||||||
| 
 | 
 | ||||||
| void SetUpOnce(void) { |  | ||||||
|   if (!IsWindows()) _Exit(0); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void OnAlrm(int sig) { | void OnAlrm(int sig) { | ||||||
|   // do nothing
 |   // do nothing
 | ||||||
|   STRACE("OnAlrm()"); |   STRACE("OnAlrm()"); | ||||||
|  |  | ||||||
							
								
								
									
										108
									
								
								test/libc/calls/stackoverflow1_test.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								test/libc/calls/stackoverflow1_test.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,108 @@ | ||||||
|  | /*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
 | ||||||
|  | │vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8                                :vi│ | ||||||
|  | ╞══════════════════════════════════════════════════════════════════════════════╡ | ||||||
|  | │ Copyright 2023 Justine Alexandra Roberts Tunney                              │ | ||||||
|  | │                                                                              │ | ||||||
|  | │ Permission to use, copy, modify, and/or distribute this software for         │ | ||||||
|  | │ any purpose with or without fee is hereby granted, provided that the         │ | ||||||
|  | │ above copyright notice and this permission notice appear in all copies.      │ | ||||||
|  | │                                                                              │ | ||||||
|  | │ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL                │ | ||||||
|  | │ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED                │ | ||||||
|  | │ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE             │ | ||||||
|  | │ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL         │ | ||||||
|  | │ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR        │ | ||||||
|  | │ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER               │ | ||||||
|  | │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │ | ||||||
|  | │ PERFORMANCE OF THIS SOFTWARE.                                                │ | ||||||
|  | ╚─────────────────────────────────────────────────────────────────────────────*/ | ||||||
|  | #include "libc/calls/struct/rlimit.h" | ||||||
|  | #include "libc/calls/struct/sigaction.h" | ||||||
|  | #include "libc/calls/struct/sigaltstack.h" | ||||||
|  | #include "libc/calls/struct/siginfo.h" | ||||||
|  | #include "libc/dce.h" | ||||||
|  | #include "libc/intrin/kprintf.h" | ||||||
|  | #include "libc/limits.h" | ||||||
|  | #include "libc/mem/gc.internal.h" | ||||||
|  | #include "libc/mem/mem.h" | ||||||
|  | #include "libc/runtime/runtime.h" | ||||||
|  | #include "libc/runtime/sysconf.h" | ||||||
|  | #include "libc/sysv/consts/rlimit.h" | ||||||
|  | #include "libc/sysv/consts/sa.h" | ||||||
|  | #include "libc/sysv/consts/sig.h" | ||||||
|  | #include "libc/sysv/consts/ss.h" | ||||||
|  | #include "libc/testlib/testlib.h" | ||||||
|  | #include "libc/thread/thread.h" | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * stack overflow recovery technique #1 | ||||||
|  |  * overflow the gigantic main process stack | ||||||
|  |  * simple but it can upset kernels / libraries | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | jmp_buf recover; | ||||||
|  | volatile bool smashed_stack; | ||||||
|  | 
 | ||||||
|  | void CrashHandler(int sig, siginfo_t *si, void *ctx) { | ||||||
|  |   struct sigaltstack ss; | ||||||
|  |   ASSERT_SYS(0, 0, sigaltstack(0, &ss)); | ||||||
|  |   ASSERT_EQ(SS_ONSTACK, ss.ss_flags); | ||||||
|  |   kprintf("kprintf avoids overflowing %G %p\n", si->si_signo, si->si_addr); | ||||||
|  |   smashed_stack = true; | ||||||
|  |   ASSERT_TRUE(__is_stack_overflow(si, ctx)); | ||||||
|  |   longjmp(recover, 123); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void SetUp(void) { | ||||||
|  | 
 | ||||||
|  |   // tune down the main process's stack size to a reasonable amount
 | ||||||
|  |   // some operating systems, e.g. freebsd, will do things like have
 | ||||||
|  |   // 500mb RLIMIT_STACK by default, even on machines with 400mb RAM
 | ||||||
|  |   struct rlimit rl = {2 * 1024 * 1024, 2 * 1024 * 1024}; | ||||||
|  |   if (!IsWindows() && !IsXnu()) { | ||||||
|  |     ASSERT_SYS(0, 0, setrlimit(RLIMIT_STACK, &rl)); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // set up the signal handler and alternative stack
 | ||||||
|  |   struct sigaction sa; | ||||||
|  |   struct sigaltstack ss; | ||||||
|  |   ss.ss_flags = 0; | ||||||
|  |   ss.ss_size = sysconf(_SC_MINSIGSTKSZ) + 8192; | ||||||
|  |   ss.ss_sp = _mapanon(ss.ss_size); | ||||||
|  |   ASSERT_SYS(0, 0, sigaltstack(&ss, 0)); | ||||||
|  |   sa.sa_flags = SA_SIGINFO | SA_ONSTACK;  // <-- important
 | ||||||
|  |   sigemptyset(&sa.sa_mask); | ||||||
|  |   sa.sa_sigaction = CrashHandler; | ||||||
|  |   sigaction(SIGBUS, &sa, 0); | ||||||
|  |   sigaction(SIGSEGV, &sa, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int StackOverflow(int f(), int n) { | ||||||
|  |   if (n < INT_MAX) { | ||||||
|  |     return f(f, n + 1) - 1; | ||||||
|  |   } else { | ||||||
|  |     return INT_MAX; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int (*pStackOverflow)(int (*)(), int) = StackOverflow; | ||||||
|  | 
 | ||||||
|  | TEST(stackoverflow, standardStack_altStack_process_longjmp) { | ||||||
|  |   if (IsTiny()) return;  // TODO(jart): why?
 | ||||||
|  | 
 | ||||||
|  |   int jumpcode; | ||||||
|  |   if (!(jumpcode = setjmp(recover))) { | ||||||
|  |     exit(pStackOverflow(pStackOverflow, 0)); | ||||||
|  |   } | ||||||
|  |   ASSERT_EQ(123, jumpcode); | ||||||
|  |   ASSERT_TRUE(smashed_stack); | ||||||
|  | 
 | ||||||
|  |   // here's where longjmp() gets us into trouble
 | ||||||
|  |   struct sigaltstack ss; | ||||||
|  |   ASSERT_SYS(0, 0, sigaltstack(0, &ss)); | ||||||
|  |   if (IsXnu() || IsNetbsd()) { | ||||||
|  |     ASSERT_EQ(SS_ONSTACK, ss.ss_flags);  // wut
 | ||||||
|  |   } else { | ||||||
|  |     ASSERT_EQ(0, ss.ss_flags); | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										105
									
								
								test/libc/calls/stackoverflow2_test.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								test/libc/calls/stackoverflow2_test.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,105 @@ | ||||||
|  | /*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
 | ||||||
|  | │vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8                                :vi│ | ||||||
|  | ╞══════════════════════════════════════════════════════════════════════════════╡ | ||||||
|  | │ Copyright 2023 Justine Alexandra Roberts Tunney                              │ | ||||||
|  | │                                                                              │ | ||||||
|  | │ Permission to use, copy, modify, and/or distribute this software for         │ | ||||||
|  | │ any purpose with or without fee is hereby granted, provided that the         │ | ||||||
|  | │ above copyright notice and this permission notice appear in all copies.      │ | ||||||
|  | │                                                                              │ | ||||||
|  | │ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL                │ | ||||||
|  | │ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED                │ | ||||||
|  | │ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE             │ | ||||||
|  | │ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL         │ | ||||||
|  | │ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR        │ | ||||||
|  | │ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER               │ | ||||||
|  | │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │ | ||||||
|  | │ PERFORMANCE OF THIS SOFTWARE.                                                │ | ||||||
|  | ╚─────────────────────────────────────────────────────────────────────────────*/ | ||||||
|  | #include "libc/calls/struct/sigaction.h" | ||||||
|  | #include "libc/calls/struct/sigaltstack.h" | ||||||
|  | #include "libc/calls/struct/siginfo.h" | ||||||
|  | #include "libc/dce.h" | ||||||
|  | #include "libc/intrin/kprintf.h" | ||||||
|  | #include "libc/limits.h" | ||||||
|  | #include "libc/mem/gc.internal.h" | ||||||
|  | #include "libc/mem/mem.h" | ||||||
|  | #include "libc/runtime/runtime.h" | ||||||
|  | #include "libc/runtime/sysconf.h" | ||||||
|  | #include "libc/sysv/consts/sa.h" | ||||||
|  | #include "libc/sysv/consts/sig.h" | ||||||
|  | #include "libc/sysv/consts/ss.h" | ||||||
|  | #include "libc/testlib/testlib.h" | ||||||
|  | #include "libc/thread/thread.h" | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * stack overflow recovery technique #2 | ||||||
|  |  * longjmp out of signal back into thread | ||||||
|  |  * simple but it can upset kernels / libraries | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | jmp_buf recover; | ||||||
|  | volatile bool smashed_stack; | ||||||
|  | 
 | ||||||
|  | void CrashHandler(int sig, siginfo_t *si, void *ctx) { | ||||||
|  |   struct sigaltstack ss; | ||||||
|  |   ASSERT_SYS(0, 0, sigaltstack(0, &ss)); | ||||||
|  |   ASSERT_EQ(SS_ONSTACK, ss.ss_flags); | ||||||
|  |   kprintf("kprintf avoids overflowing %G %p\n", si->si_signo, si->si_addr); | ||||||
|  |   smashed_stack = true; | ||||||
|  |   ASSERT_TRUE(__is_stack_overflow(si, ctx)); | ||||||
|  |   longjmp(recover, 123); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int StackOverflow(int f(), int n) { | ||||||
|  |   if (n < INT_MAX) { | ||||||
|  |     return f(f, n + 1) - 1; | ||||||
|  |   } else { | ||||||
|  |     return INT_MAX; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int (*pStackOverflow)(int (*)(), int) = StackOverflow; | ||||||
|  | 
 | ||||||
|  | void *MyPosixThread(void *arg) { | ||||||
|  |   int jumpcode; | ||||||
|  |   struct sigaction sa, o1, o2; | ||||||
|  |   struct sigaltstack ss; | ||||||
|  |   ss.ss_flags = 0; | ||||||
|  |   ss.ss_size = sysconf(_SC_MINSIGSTKSZ) + 4096; | ||||||
|  |   ss.ss_sp = gc(malloc(ss.ss_size)); | ||||||
|  |   ASSERT_SYS(0, 0, sigaltstack(&ss, 0)); | ||||||
|  |   sa.sa_flags = SA_SIGINFO | SA_ONSTACK;  // <-- important
 | ||||||
|  |   sigemptyset(&sa.sa_mask); | ||||||
|  |   sa.sa_sigaction = CrashHandler; | ||||||
|  |   sigaction(SIGBUS, &sa, &o1); | ||||||
|  |   sigaction(SIGSEGV, &sa, &o2); | ||||||
|  |   if (!(jumpcode = setjmp(recover))) { | ||||||
|  |     exit(pStackOverflow(pStackOverflow, 0)); | ||||||
|  |   } | ||||||
|  |   ASSERT_EQ(123, jumpcode); | ||||||
|  |   sigaction(SIGSEGV, &o2, 0); | ||||||
|  |   sigaction(SIGBUS, &o1, 0); | ||||||
|  |   // here's where longjmp() gets us into trouble
 | ||||||
|  |   ASSERT_SYS(0, 0, sigaltstack(0, &ss)); | ||||||
|  |   if (IsXnu() || IsNetbsd()) { | ||||||
|  |     ASSERT_EQ(SS_ONSTACK, ss.ss_flags);  // wut
 | ||||||
|  |   } else { | ||||||
|  |     ASSERT_EQ(0, ss.ss_flags); | ||||||
|  |   } | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | TEST(stackoverflow, standardStack_altStack_thread_longjmp) { | ||||||
|  |   pthread_t th; | ||||||
|  |   struct sigaltstack ss; | ||||||
|  |   for (int i = 0; i < 2; ++i) { | ||||||
|  |     smashed_stack = false; | ||||||
|  |     pthread_create(&th, 0, MyPosixThread, 0); | ||||||
|  |     pthread_join(th, 0); | ||||||
|  |     ASSERT_TRUE(smashed_stack); | ||||||
|  |     // this should be SS_DISABLE but ShowCrashReports() creates an alt stack
 | ||||||
|  |     ASSERT_SYS(0, 0, sigaltstack(0, &ss)); | ||||||
|  |     ASSERT_EQ(0, ss.ss_flags); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | @ -31,10 +31,9 @@ | ||||||
| #include "libc/x/x.h" | #include "libc/x/x.h" | ||||||
| #include "third_party/libcxx/math.h" | #include "third_party/libcxx/math.h" | ||||||
| 
 | 
 | ||||||
| #if 0  // TODO(jart): fix me
 |  | ||||||
| 
 |  | ||||||
| bool gotsome; | bool gotsome; | ||||||
| ucontext_t uc, goback; | ucontext_t uc, goback; | ||||||
|  | extern long __klog_handle; | ||||||
| 
 | 
 | ||||||
| void SetUpOnce(void) { | void SetUpOnce(void) { | ||||||
|   testlib_enable_tmp_setup_teardown(); |   testlib_enable_tmp_setup_teardown(); | ||||||
|  | @ -90,18 +89,17 @@ TEST(makecontext, backtrace) { | ||||||
|   SPAWN(fork); |   SPAWN(fork); | ||||||
|   ASSERT_SYS(0, 0, close(2)); |   ASSERT_SYS(0, 0, close(2)); | ||||||
|   ASSERT_SYS(0, 2, creat("log", 0644)); |   ASSERT_SYS(0, 2, creat("log", 0644)); | ||||||
|  |   __klog_handle = 2; | ||||||
|   getcontext(&uc); |   getcontext(&uc); | ||||||
|   uc.uc_link = 0; |   uc.uc_link = 0; | ||||||
|   uc.uc_stack.ss_sp = NewCosmoStack(); |   uc.uc_stack.ss_sp = NewCosmoStack(); | ||||||
|   uc.uc_stack.ss_size = GetStackSize(); |   uc.uc_stack.ss_size = GetStackSize(); | ||||||
|   makecontext(&uc, itsatrap, 2, 123, 456); |   makecontext(&uc, itsatrap, 2, 123, 456); | ||||||
|   setcontext(&uc); |   setcontext(&uc); | ||||||
|   EXITS(128 + SIGSEGV); |   TERMS(SIGSEGV); | ||||||
|   if (!GetSymbolTable()) return; |   if (!GetSymbolTable()) return; | ||||||
|   char *log = gc(xslurp("log", 0)); |   char *log = gc(xslurp("log", 0)); | ||||||
|   EXPECT_NE(0, strstr(log, "itsatrap")); |   EXPECT_NE(0, strstr(log, "itsatrap")); | ||||||
|   EXPECT_NE(0, strstr(log, "runcontext")); |   EXPECT_NE(0, strstr(log, "runcontext")); | ||||||
|   EXPECT_NE(0, strstr(log, "makecontext_backtrace")); |   EXPECT_NE(0, strstr(log, "makecontext_backtrace")); | ||||||
| } | } | ||||||
| 
 |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue