Strengthen the pledge() polyfill

This commit is contained in:
Justine Tunney 2022-06-27 13:01:58 -07:00
parent a6f65eea7c
commit 3c92adfd6e
79 changed files with 1457 additions and 357 deletions

View file

@ -19,14 +19,27 @@
#include "libc/calls/struct/flock.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/calls/syscall_support-sysv.internal.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/sysv/consts/f.h"
#include "libc/sysv/errfuns.h"
int sys_fcntl(int fd, int cmd, uintptr_t arg) {
int rc;
bool islock;
islock = cmd == F_SETLK || cmd == F_SETLKW || cmd == F_GETLK;
if (islock) cosmo2flock(arg);
if ((islock = cmd == F_GETLK || //
cmd == F_SETLK || //
cmd == F_SETLKW)) {
if ((!IsAsan() && !arg) ||
(IsAsan() &&
!__asan_is_valid((struct flock *)arg, sizeof(struct flock)))) {
return efault();
}
cosmo2flock(arg);
}
rc = __sys_fcntl(fd, cmd, arg);
if (islock) flock2cosmo(arg);
if (islock) {
flock2cosmo(arg);
}
return rc;
}

36
libc/calls/isatty-metal.c Normal file
View file

@ -0,0 +1,36 @@
/*-*- 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 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/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/syscall_support-sysv.internal.h"
#include "libc/sysv/errfuns.h"
bool32 sys_isatty_metal(int fd) {
if (__isfdopen(fd)) {
if (__isfdkind(fd, kFdSerial)) {
return true;
} else {
enotty();
return false;
}
} else {
ebadf();
return false;
}
}

View file

@ -22,7 +22,17 @@
#include "libc/sysv/errfuns.h"
textwindows bool32 sys_isatty_nt(int fd) {
return __isfdkind(fd, kFdConsole) ||
(__isfdkind(fd, kFdFile) &&
GetFileType(__getfdhandleactual(fd)) == kNtFileTypeChar);
if (__isfdopen(fd)) {
if (__isfdkind(fd, kFdConsole) ||
(__isfdkind(fd, kFdFile) &&
GetFileType(g_fds.p[fd].handle) == kNtFileTypeChar)) {
return true;
} else {
enotty();
return false;
}
} else {
ebadf();
return false;
}
}

View file

@ -22,32 +22,39 @@
#include "libc/calls/struct/winsize.h"
#include "libc/calls/syscall-nt.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/calls/syscall_support-sysv.internal.h"
#include "libc/errno.h"
#include "libc/sysv/consts/termios.h"
#include "libc/sysv/errfuns.h"
/**
* Returns true if file descriptor is backed by a terminal device.
* Tells if file descriptor is a terminal.
*
* @param fd is file descriptor
* @return 1 if is terminal, otherwise 0 w/ errno
* @raise EBADF if fd isn't a valid file descriptor
* @raise ENOTTY if fd is something other than a terminal
* @raise EPERM if pledge() was used without tty
*/
bool32 isatty(int fd) {
int e;
bool32 res;
struct winsize ws;
e = errno;
if (fd >= 0) {
if (__isfdkind(fd, kFdZip)) {
res = false;
} else if (IsMetal()) {
res = false;
} else if (!IsWindows()) {
res = sys_ioctl(fd, TIOCGWINSZ, &ws) != -1;
} else {
res = sys_isatty_nt(fd);
}
if (__isfdkind(fd, kFdZip)) {
enotty();
res = false;
} else if (IsWindows()) {
res = sys_isatty_nt(fd);
} else if (IsMetal()) {
res = sys_isatty_metal(fd);
} else if (!sys_ioctl(fd, TIOCGWINSZ, &ws)) {
res = true;
} else {
res = false;
if (errno != EBADF && errno != EPERM) {
enotty();
}
}
STRACE("isatty(%d) → %hhhd% m", fd, res);
errno = e;
return res;
}

View file

@ -20,7 +20,7 @@
#include "libc/errno.h"
#include "libc/sysv/consts/pr.h"
bool __is_linux_2_6_23(void) {
privileged bool __is_linux_2_6_23(void) {
int rc;
if (!IsLinux()) return false;
asm volatile("syscall"

View file

@ -28,7 +28,7 @@
*
* @raise ENOSYS on non-Linux.
*/
int prctl(int operation, ...) {
privileged int prctl(int operation, ...) {
int rc;
va_list va;
intptr_t a, b;

View file

@ -34,7 +34,7 @@
*
* @raise ENOSYS on non-Linux.
*/
int seccomp(unsigned operation, unsigned flags, void *args) {
privileged int seccomp(unsigned operation, unsigned flags, void *args) {
int rc;
if (IsLinux()) {
asm volatile("syscall"

View file

@ -62,15 +62,15 @@ COSMOPOLITAN_C_START_
#define BPF_TO_BE 0x08
#define BPF_FROM_LE BPF_TO_LE
#define BPF_FROM_BE BPF_TO_BE
#define BPF_JNE 0x50
#define BPF_JLT 0xa0
#define BPF_JLE 0xb0
#define BPF_JSGT 0x60
#define BPF_JSGE 0x70
#define BPF_JSLT 0xc0
#define BPF_JSLE 0xd0
#define BPF_CALL 0x80
#define BPF_EXIT 0x90
#define BPF_JNE 0x50 /* != */
#define BPF_JLT 0xa0 /* unsigned < */
#define BPF_JLE 0xb0 /* unsigned <= */
#define BPF_JSGT 0x60 /* signed > */
#define BPF_JSGE 0x70 /* signed >= */
#define BPF_JSLT 0xc0 /* signed < */
#define BPF_JSLE 0xd0 /* signed <= */
#define BPF_CALL 0x80 /* call */
#define BPF_EXIT 0x90 /* ret */
#define BPF_FETCH 0x01
#define BPF_XCHG (0xe0 | BPF_FETCH)
#define BPF_CMPXCHG (0xf0 | BPF_FETCH)

View file

@ -26,8 +26,8 @@ struct sock_fprog {
#define BPF_STMT(code, k) \
{ (unsigned short)(code), 0, 0, k }
#define BPF_JUMP(code, k, jt, jf) \
{ (unsigned short)(code), jt, jf, k }
#define BPF_JUMP(code, k, jumptrue, jumpfalse) \
{ (unsigned short)(code), jumptrue, jumpfalse, k }
#define BPF_MEMWORDS 16

View file

@ -19,6 +19,7 @@ void __restore_rt() hidden;
void __restore_rt_netbsd(void) hidden;
void cosmo2flock(uintptr_t);
void flock2cosmo(uintptr_t);
bool32 sys_isatty_metal(int);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -35,7 +35,7 @@
* @vforksafe
* @noreturn
*/
wontreturn void _Exit(int exitcode) {
privileged wontreturn void _Exit(int exitcode) {
int i;
STRACE("_Exit(%d)", exitcode);
if (!IsWindows() && !IsMetal()) {

View file

@ -18,6 +18,7 @@
*/
#include "libc/sysv/consts/nr.h"
#include "libc/macros.internal.h"
.privileged
_futex: mov __NR_futex,%eax
clc

View file

@ -47,7 +47,8 @@ static union metatermios __oldtermios;
static textstartup void __oldtermios_init() {
int e;
e = errno;
if (sys_ioctl(0, TCGETS, &__oldtermios) != -1) {
if (!IsOpenbsd() && // avoid pledge(tty)
sys_ioctl(0, TCGETS, &__oldtermios) != -1) {
__isrestorable = true;
}
errno = e;

File diff suppressed because it is too large Load diff

View file

@ -17,6 +17,7 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/macros.internal.h"
.privileged
// Invokes clone() system call on GNU/Systemd.
//

View file

@ -34,6 +34,7 @@ extern unsigned char _ereal[]; /* αpε */
extern unsigned char __privileged_start[]; /* αpε */
extern unsigned char __privileged_addr[]; /* αpε */
extern unsigned char __privileged_size[]; /* αpε */
extern unsigned char __privileged_end[]; /* αpε */
extern unsigned char __test_start[]; /* αpε */
extern unsigned char __ro[]; /* αpε */
extern unsigned char *__relo_start[]; /* αpε */

View file

@ -74,6 +74,10 @@ static textexit void LogStackUse(void) {
}
static textstartup void LogStackUseInit(void) {
if (IsOpenbsd()) {
// avoid pledge() dependency on wpath
return;
}
if (IsTiny()) return;
if (isdirectory("o/" MODE) &&
getcwd(stacklog, sizeof(stacklog) - strlen("/o/" MODE "/stack.log"))) {

View file

@ -22,12 +22,14 @@
#include "libc/sysv/consts/af.h"
/**
* Creates bidirectional pipe.
* Creates bidirectional pipe, e.g.
*
* int sv[2];
* socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
*
* @param family should be AF_UNIX or synonymously AF_LOCAL
* @param type can be SOCK_STREAM (for TCP), SOCK_DGRAM (e.g. UDP), or
* SOCK_RAW (IP) so long as IP_HDRINCL was passed to setsockopt();
* and additionally, may be or'd with SOCK_NONBLOCK, SOCK_CLOEXEC
* @param type can be SOCK_STREAM or SOCK_DGRAM and additionally,
* may be or'd with SOCK_NONBLOCK, SOCK_CLOEXEC
* @param sv a vector of 2 integers to store the created sockets
* @return 0 if success, -1 in case of error
* @error EFAULT, EPFNOSUPPORT, etc.

View file

@ -31,6 +31,7 @@
_ehead = 0
_ereal = 0
__privileged_start = 0
__privileged_end = 0
__privileged_addr = 0
__privileged_size = 0
__test_start = 0
@ -58,6 +59,7 @@
.globl __privileged_size
.globl __privileged_addr
.globl __privileged_start
.globl __privileged_end
.globl __ro
.globl __test_start
.globl _edata
@ -83,6 +85,7 @@
.weak __privileged_size
.weak __privileged_addr
.weak __privileged_start
.weak __privileged_end
.weak __ro
.weak __test_start
.weak _edata

View file

@ -220,6 +220,7 @@ syscon compat O_LARGEFILE 0 0 0 0 0 0 #
# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary
syscon mmap MAP_FILE 0 0 0 0 0 0 # consensus
syscon mmap MAP_SHARED 1 1 1 1 1 1 # forced consensus & faked nt
syscon mmap MAP_SHARED_VALIDATE 3 1 1 1 1 1 # weird linux thing
syscon mmap MAP_PRIVATE 2 2 2 2 2 2 # forced consensus & faked nt
syscon mmap MAP_STACK 6 6 6 6 6 6 # our definition
syscon mmap MAP_TYPE 15 15 15 15 15 15 # mask for type of mapping
@ -232,6 +233,7 @@ syscon mmap MAP_NORESERVE 0x00004000 0x00000040 0 0 0x00000040 0 # L
syscon mmap MAP_POPULATE 0x00008000 0 0x00040000 0 0 0 # MAP_PREFAULT_READ on FreeBSD; can avoid madvise(MADV_WILLNEED) on private file mapping
syscon mmap MAP_NONBLOCK 0x00010000 0 0 0 0 0
syscon mmap MAP_HUGETLB 0x00040000 0 0 0 0 0x80000000 # kNtSecLargePages
syscon mmap MAP_SYNC 0x00080000 0 0 0 0 0 # perform synchronous page faults for mapping (Linux 4.15+)
syscon mmap MAP_INHERIT -1 -1 -1 -1 0x00000080 -1 # make it inherit across execve()
syscon mmap MAP_HASSEMAPHORE 0 0x00000200 0x00000200 0 0x00000200 0 # does it matter on x86?
syscon mmap MAP_NOSYNC 0 0 0x00000800 0 0 0 # flush to physical media only when necessary rather than gratuitously; be sure to use write() rather than ftruncate() with this!
@ -999,11 +1001,15 @@ syscon sio SIOCSIFTXQLEN 0x8943 0 0 0 0 0
syscon sio SIOCSRARP 0x8962 0 0 0 0 0
syscon sio SIOGIFINDEX 0x8933 0 0 0 0 0
# socket() address families
#
# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary
syscon af AF_UNSPEC 0 0 0 0 0 0 # consensus
syscon af AF_UNIX 1 1 1 1 1 1 # consensus
syscon af AF_LOCAL 1 1 1 1 1 1 # consensus
syscon af AF_FILE 1 0 0 0 0 0
syscon af AF_INET 2 2 2 2 2 2 # consensus
syscon af AF_INET6 10 30 28 24 24 23
syscon af AF_AX25 3 0 0 0 0 0
syscon af AF_IPX 4 23 23 23 23 6 # bsd consensus
syscon af AF_APPLETALK 5 0x10 0x10 0x10 0x10 0x10 # bsd consensus
@ -1011,7 +1017,6 @@ syscon af AF_NETROM 6 0 0 0 0 0
syscon af AF_BRIDGE 7 0 0 0 0 0
syscon af AF_ATMPVC 8 0 0 0 0 0
syscon af AF_X25 9 0 0 0 0 0
syscon af AF_INET6 10 30 28 24 24 23
syscon af AF_ROSE 11 0 0 0 0 0
syscon af AF_NETBEUI 13 0 0 0 0 0
syscon af AF_SECURITY 14 0 0 0 0 0
@ -1250,14 +1255,15 @@ syscon msg MSG_PEEK 2 2 2 2 2 2 # consensus
syscon msg MSG_DONTROUTE 4 4 4 4 4 4 # consensus
syscon msg MSG_FASTOPEN 0x20000000 0 0 0 0 0 # TODO
syscon msg MSG_WAITALL 0x0100 0x40 0x40 0x40 0x40 8 # bsd consensus
syscon msg MSG_MORE 0x8000 0 0 0 0 0 # send/sendto: manual TCP_CORK hbasically
syscon msg MSG_NOSIGNAL 0x4000 0x80000 0x020000 0x0400 0x0400 0 # send/sendto: don't SIGPIPE on EOF
syscon msg MSG_DONTWAIT 0x40 0x80 0x80 0x80 0x80 0 # send/sendto: manual non-blocking
syscon msg MSG_TRUNC 0x20 0x10 0x10 0x10 0x10 0x0100 # bsd consensus
syscon msg MSG_CTRUNC 8 0x20 0x20 0x20 0x20 0x0200 # bsd consensus
syscon msg MSG_ERRQUEUE 0x2000 0 0 0 0 0x1000 # bsd consensus
syscon msg MSG_NOERROR 0x1000 0x1000 0x1000 0x1000 0x1000 0 # unix consensus
syscon msg MSG_DONTWAIT 0x40 0x80 0x80 0x80 0x80 0 # bsd consensus
syscon msg MSG_EOR 0x80 8 8 8 8 0 # bsd consensus
syscon msg MSG_CMSG_CLOEXEC 0x40000000 0 0x040000 0x0800 0x0800 0
syscon msg MSG_NOSIGNAL 0x4000 0 0x020000 0x0400 0x0400 0
syscon msg MSG_WAITFORONE 0x010000 0 0x080000 0 0x2000 0
syscon msg MSG_BATCH 0x040000 0 0 0 0 0
syscon msg MSG_CONFIRM 0x0800 0 0 0 0 0
@ -1265,7 +1271,6 @@ syscon msg MSG_EXCEPT 0x2000 0 0 0 0 0
syscon msg MSG_FIN 0x0200 0x0100 0x0100 0 0 0
syscon msg MSG_EOF 0x0200 0x0100 0x0100 0 0 0
syscon msg MSG_INFO 12 0 0 0 0 0
syscon msg MSG_MORE 0x8000 0 0 0 0 0
syscon msg MSG_PARITY_ERROR 9 0 0 0 0 0
syscon msg MSG_PROXY 0x10 0 0 0 0 0
syscon msg MSG_RST 0x1000 0 0 0 0 0
@ -1327,17 +1332,17 @@ syscon compat TIOCSETAF 0x5404 0x80487416 0x802c7416 0x802c7416 0x802c74
syscon termios TIOCGWINSZ 0x5413 1074295912 1074295912 1074295912 1074295912 0x5413 # ioctl(tty, TIOCGWINSZ, struct winsize *argp); polyfilled NT
syscon termios TIOCSWINSZ 0x5414 0x80087467 0x80087467 0x80087467 0x80087467 0x5414 # ioctl(tty, TIOCSWINSZ, const struct winsize *argp) (faked NT)
syscon termios TIOCOUTQ 0x5411 0x40047473 0x40047473 0x40047473 0x40047473 0 # get # bytes queued in TTY's output buffer ioctl(tty, TIOCSWINSZ, const struct winsize *argp)
syscon termios TIOCGPGRP 0x540f 0x40047477 0x40047477 0x40047477 0x40047477 0 # get pgrp of tty
syscon termios TIOCSPGRP 0x5410 0x80047476 0x80047476 0x80047476 0x80047476 0 # set pgrp of tty
syscon termios TIOCSBRK 0x5427 0x2000747b 0x2000747b 0x2000747b 0x2000747b 0 # set break bit
syscon termios TIOCCBRK 0x5428 0x2000747a 0x2000747a 0x2000747a 0x2000747a 0 # boop
syscon termios TIOCCONS 0x541d 0x80047462 0x80047462 0x80047462 0x80047462 0 # boop
syscon termios TIOCGETD 0x5424 0x4004741a 0x4004741a 0x4004741a 0x4004741a 0 # boop
syscon termios TIOCGPGRP 0x540f 0x40047477 0x40047477 0x40047477 0x40047477 0 # boop
syscon termios TIOCNOTTY 0x5422 0x20007471 0x20007471 0x20007471 0x20007471 0 # boop
syscon termios TIOCNXCL 0x540d 0x2000740e 0x2000740e 0x2000740e 0x2000740e 0 # boop
syscon termios TIOCSBRK 0x5427 0x2000747b 0x2000747b 0x2000747b 0x2000747b 0 # boop
syscon termios TIOCSCTTY 0x540e 0x20007461 0x20007461 0x20007461 0x20007461 0 # boop
syscon termios TIOCSETD 0x5423 0x8004741b 0x8004741b 0x8004741b 0x8004741b 0 # boop
syscon termios TIOCSIG 0x40045436 0x2000745f 0x2004745f 0x8004745f 0x8004745f 0 # boop
syscon termios TIOCSPGRP 0x5410 0x80047476 0x80047476 0x80047476 0x80047476 0 # boop
syscon termios TIOCSTI 0x5412 0x80017472 0x80017472 0 0 0 # boop
syscon termios TIOCGSID 0x5429 0x40047463 0x40047463 0x40047463 0x40047463 0 # boop
syscon termios TABLDISC 0 0x3 0 0x3 0x3 0 # boop
@ -1347,7 +1352,7 @@ syscon termios TCSBRK 0x5409 0x2000745e 0x2000745e 0x2000745e 0x2000745
syscon termios TIOCDRAIN 0x5409 0x2000745e 0x2000745e 0x2000745e 0x2000745e 0 # TCSBRK on Linux
syscon termios TIOCSTAT 0 0x20007465 0x20007465 0x20007465 0x20007465 0 # boop
syscon termios TIOCSTART 0 0x2000746e 0x2000746e 0x2000746e 0x2000746e 0 # boop
syscon termios TIOCCDTR 0 0x20007478 0x20007478 0x20007478 0x20007478 0 # boop
syscon termios TIOCCDTR 0 0x20007478 0x20007478 0x20007478 0x20007478 0 # clear data terminal ready
syscon termios TIOCSDTR 0 0x20007479 0x20007479 0x20007479 0x20007479 0 # boop
syscon termios TIOCEXT 0 0x80047460 0x80047460 0x80047460 0x80047460 0 # boop
syscon termios TIOCGDRAINWAIT 0 0x40047456 0x40047456 0 0 0 # boop

View file

@ -0,0 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon mmap,MAP_SHARED_VALIDATE,3,1,1,1,1,1

View file

@ -0,0 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon mmap,MAP_SYNC,0x00080000,0,0,0,0,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon msg,MSG_NOSIGNAL,0x4000,0,0x020000,0x0400,0x0400,0
.syscon msg,MSG_NOSIGNAL,0x4000,0x80000,0x020000,0x0400,0x0400,0

View file

@ -26,6 +26,7 @@ extern const long MAP_NOSYNC;
extern const long MAP_POPULATE;
extern const long MAP_PRIVATE;
extern const long MAP_SHARED;
extern const long MAP_SHARED_VALIDATE;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
@ -54,6 +55,7 @@ COSMOPOLITAN_C_END_
#define MAP_NORESERVE SYMBOLIC(MAP_NORESERVE)
#define MAP_NOSYNC SYMBOLIC(MAP_NOSYNC)
#define MAP_POPULATE SYMBOLIC(MAP_POPULATE)
#define MAP_SHARED_VALIDATE SYMBOLIC(MAP_SHARED_VALIDATE)
#define MAP_ANON MAP_ANONYMOUS
#define MAP_NOCORE MAP_CONCEAL

View file

@ -58,7 +58,7 @@ scall sys_writev 0x0790790792079014 globl hidden
scall sys_access 0x0210210212021015 globl hidden
scall __sys_pipe 0x02a10721e202a016 globl hidden # NOTE: pipe2() on FreeBSD; XNU is pipe(void)→eax:edx
scall sys_select 0x1a104705d205d017 globl hidden
scall pselect 0x1b406e20a218afff globl
scall pseletc 0x1b406e20a218afff globl
scall pselect6 0xfffffffffffff10e globl
scall sys_sched_yield 0x15e12a14bffff018 globl hidden # swtch on xnu? possibly removed in 12.4
scall __sys_mremap 0x19bffffffffff019 globl hidden

View file

@ -17,9 +17,14 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/bits/bits.h"
#include "libc/calls/calls.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath", 0);
}
unsigned P[] = {
// 33333222222222111111111000000000
0b000011000000010000000001000000000, //
@ -106,7 +111,5 @@ TEST(bextra, 9bit) {
}
BENCH(bextra, bench) {
EZBENCH2("bextra 0/32", donothing, bextra(P, 0, 32));
EZBENCH2("bextra 1/31", donothing, bextra(P, 1, 31));
EZBENCH2("bextra 1/32", donothing, bextra(P, 1, 32));
}

View file

@ -17,9 +17,14 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/bits/bits.h"
#include "libc/calls/calls.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath", 0);
}
TEST(bitreverse, test) {
EXPECT_EQ(0xde, BITREVERSE8(123));
EXPECT_EQ(0xde, bitreverse8(123));

View file

@ -18,12 +18,17 @@
*/
#include "libc/bits/bits.h"
#include "libc/bits/popcnt.h"
#include "libc/calls/calls.h"
#include "libc/mem/mem.h"
#include "libc/runtime/gc.internal.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/hyperion.h"
#include "libc/testlib/testlib.h"
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath", 0);
}
TEST(_countbits, testLow) {
int i;
char p[2];

View file

@ -17,11 +17,16 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/bits/morton.h"
#include "libc/calls/calls.h"
#include "libc/nexgen32e/kcpuids.h"
#include "libc/str/str.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath", 0);
}
TEST(morton, test) {
EXPECT_EQ(0, morton(0, 0));
EXPECT_EQ(1, morton(0, 1));

View file

@ -24,11 +24,13 @@ TEST_LIBC_BITS_CHECKS = \
TEST_LIBC_BITS_DIRECTDEPS = \
LIBC_BITS \
LIBC_FMT \
LIBC_INTRIN \
LIBC_MEM \
LIBC_RUNTIME \
LIBC_NEXGEN32E \
LIBC_RUNTIME \
LIBC_STUBS \
LIBC_SYSV \
LIBC_TESTLIB \
LIBC_X \
THIRD_PARTY_COMPILER_RT

View file

@ -29,6 +29,10 @@
char testlib_enable_tmp_setup_teardown;
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath wpath cpath fattr", 0);
}
TEST(access, efault) {
ASSERT_SYS(EFAULT, -1, access(0, F_OK));
if (IsWindows() && !IsAsan()) return; // not possible

View file

@ -24,6 +24,10 @@
char testlib_enable_tmp_setup_teardown;
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath wpath cpath fattr", 0);
}
TEST(chdir, efault) {
ASSERT_SYS(EFAULT, -1, chdir(0));
if (IsWindows() && !IsAsan()) return; // not possible

View file

@ -39,6 +39,10 @@ char tmp[PATH_MAX];
char pathbuf[PATH_MAX];
char testlib_enable_tmp_setup_teardown;
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath wpath cpath fattr", 0);
}
void SetUp(void) {
static int x;
mkdir("bin", 0755);

View file

@ -32,6 +32,10 @@
char testlib_enable_tmp_setup_teardown;
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath wpath cpath fattr proc exec", 0);
}
static textstartup void TestInit(int argc, char **argv) {
int fd;
if (argc == 2 && !strcmp(argv[1], "boop")) {

View file

@ -32,6 +32,11 @@ STATIC_YOINK("zip_uri_support");
int ws, pid;
char testlib_enable_tmp_setup_teardown;
__attribute__((__constructor__)) static void init(void) {
// TODO(jart): what's up with rhel5 / rhel7?
// pledge("stdio rpath wpath cpath fattr proc exec", 0);
}
bool UsingBinfmtMisc(void) {
return fileexists("/proc/sys/fs/binfmt_misc/APE");
}

View file

@ -30,6 +30,10 @@
char testlib_enable_tmp_setup_teardown;
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath wpath cpath fattr", 0);
}
TEST(fcntl_getfl, testRemembersAccessMode) {
int fd;
ASSERT_NE(-1, (fd = open("foo", O_CREAT | O_RDWR, 0644)));

View file

@ -23,6 +23,10 @@
char testlib_enable_tmp_setup_teardown;
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath wpath cpath fattr", 0);
}
TEST(fileexists, test) {
EXPECT_SYS(0, 0, fileexists("doge"));
EXPECT_SYS(0, 0, isdirectory("doge"));

View file

@ -31,6 +31,10 @@ int64_t fd;
struct stat st;
const char *path;
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath wpath cpath", 0);
}
TEST(ftruncate, test) {
mkdir("o", 0755);
mkdir("o/tmp", 0755);

View file

@ -28,6 +28,10 @@
char testlib_enable_tmp_setup_teardown;
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath cpath fattr", 0);
}
TEST(getcwd, test) {
char buf[PATH_MAX];
EXPECT_SYS(0, 0, mkdir("subdir", 0755));

View file

@ -27,6 +27,10 @@
char testlib_enable_tmp_setup_teardown;
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath wpath cpath fattr proc", 0);
}
TEST(lseek, wat) {
int fd, pid;
char buf[8] = {0};

View file

@ -30,6 +30,10 @@
char testlib_enable_tmp_setup_teardown;
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath wpath cpath fattr", 0);
}
void SetUp(void) {
errno = 0;
}

View file

@ -27,6 +27,10 @@
char testlib_enable_tmp_setup_teardown;
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath wpath cpath fattr", 0);
}
TEST(open, efault) {
ASSERT_SYS(EFAULT, -1, open(0, O_RDONLY));
if (IsWindows() && !IsAsan()) return; // not possible

View file

@ -20,10 +20,13 @@
#include "libc/sysv/consts/o.h"
#include "libc/testlib/testlib.h"
int fd;
char buf[8];
char testlib_enable_tmp_setup_teardown;
static int fd;
static char buf[8];
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath wpath cpath fattr", 0);
}
TEST(dog, testReadPastEof_returnsZero) {
EXPECT_NE(-1, (fd = open("a", O_RDWR | O_CREAT | O_TRUNC, 0644)));

View file

@ -22,6 +22,10 @@
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath tty", 0);
}
/**
* @fileoverview platform arguments tool
*

View file

@ -32,6 +32,10 @@
char testlib_enable_tmp_setup_teardown;
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath wpath cpath fattr", 0);
}
TEST(readlink, enoent) {
char buf[32];
ASSERT_SYS(ENOENT, -1, readlink("doesnotexist", buf, 32));

View file

@ -24,6 +24,10 @@
char testlib_enable_tmp_setup_teardown;
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath wpath cpath fattr", 0);
}
TEST(rename, enoent) {
EXPECT_SYS(ENOENT, -1, rename("foo", ""));
EXPECT_SYS(ENOENT, -1, rename("", "foo"));

View file

@ -33,6 +33,10 @@
#include "libc/testlib/testlib.h"
#include "tool/net/sandbox.h"
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath proc", 0);
}
// It's been reported that Chromebooks return EINVAL here.
bool CanUseSeccomp(void) {
int ws, pid;

View file

@ -30,6 +30,10 @@
bool gotsig;
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath", 0);
}
void OnSigAlrm(int sig, siginfo_t *si, ucontext_t *ctx) {
EXPECT_EQ(SIGALRM, sig);
EXPECT_EQ(SIGALRM, si->si_signo);

View file

@ -31,9 +31,12 @@
#include "third_party/xed/x86.h"
struct sigaction oldsa;
volatile bool gotsigint;
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath proc", 0);
}
void OnSigInt(int sig) {
CheckStackIsAligned();
gotsigint = true;

View file

@ -28,6 +28,10 @@ testonly void OnUsr1(int sig) {
_exit(0);
}
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath proc", 0);
}
TEST(signal, test) {
ASSERT_NE(SIG_ERR, signal(SIGUSR1, OnUsr1));
ASSERT_NE(-1, raise(SIGUSR1));

View file

@ -28,6 +28,10 @@
volatile int n;
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath proc", 0);
}
void OnSig(int sig, siginfo_t *si, ucontext_t *ctx) {
++n;
}

View file

@ -36,6 +36,10 @@ STATIC_YOINK("zip_uri_support");
char testlib_enable_tmp_setup_teardown;
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath wpath cpath fattr", 0);
}
TEST(stat_010, testEmptyFile_sizeIsZero) {
struct stat st;
memset(&st, -1, sizeof(st));

View file

@ -30,6 +30,10 @@ char testlib_enable_tmp_setup_teardown;
char p[2][PATH_MAX];
struct stat st;
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath wpath cpath fattr", 0);
}
TEST(symlink, enoent) {
ASSERT_SYS(ENOENT, -1, symlink("o/foo", ""));
ASSERT_SYS(ENOENT, -1, symlink("o/foo", "o/bar"));

View file

@ -23,6 +23,10 @@
char testlib_enable_tmp_setup_teardown;
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath wpath cpath fattr", 0);
}
TEST(unlink, efault) {
ASSERT_SYS(EFAULT, -1, unlink(0));
if (IsWindows() && !IsAsan()) return; // not possible

View file

@ -29,6 +29,10 @@
char testlib_enable_tmp_setup_teardown;
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath wpath cpath fattr", 0);
}
TEST(utimensat, test) {
struct stat st;
struct timespec ts[2] = {

View file

@ -31,6 +31,10 @@
char testlib_enable_tmp_setup_teardown;
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath wpath cpath fattr", 0);
}
TEST(writev, test) {
int fd;
char ba[1] = "a";

View file

@ -16,11 +16,16 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/dns/dns.h"
#include "libc/mem/mem.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath", 0);
}
TEST(CompareDnsNames, testEmpty) {
char *A = strcpy(malloc(1), "");
char *B = strcpy(malloc(1), "");

View file

@ -45,6 +45,10 @@ void SetUp(void) {
if (IsWindows()) exit(0);
}
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath", 0);
}
TEST(malloc, zeroMeansOne) {
ASSERT_GE(malloc_usable_size(gc(malloc(0))), 1);
}

View file

@ -18,15 +18,35 @@
*/
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/ioctl.h"
#include "libc/calls/struct/bpf.h"
#include "libc/calls/struct/filter.h"
#include "libc/calls/struct/flock.h"
#include "libc/calls/struct/seccomp.h"
#include "libc/calls/struct/stat.h"
#include "libc/calls/syscall_support-sysv.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/mem/mem.h"
#include "libc/runtime/runtime.h"
#include "libc/sock/sock.h"
#include "libc/sock/struct/sockaddr.h"
#include "libc/sysv/consts/af.h"
#include "libc/sysv/consts/at.h"
#include "libc/sysv/consts/f.h"
#include "libc/sysv/consts/fio.h"
#include "libc/sysv/consts/ipproto.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/nrlinux.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/pr.h"
#include "libc/sysv/consts/prot.h"
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/consts/sock.h"
#include "libc/testlib/testlib.h"
char testlib_enable_tmp_setup_teardown;
void SetUp(void) {
if (!__is_linux_2_6_23() && !IsOpenbsd()) {
exit(0);
@ -62,3 +82,175 @@ TEST(pledge, stdio_forbidsOpeningPasswd) {
EXPECT_EQ(SIGABRT, WTERMSIG(ws));
}
}
TEST(pledge, stdio_fcntl_allowsSomeFirstArgs) {
if (IsOpenbsd()) return; // b/c testing linux bpf
int ws, pid;
struct flock lk;
ASSERT_NE(-1, (pid = fork()));
if (!pid) {
ASSERT_SYS(0, 0, pledge("stdio", 0));
ASSERT_NE(-1, fcntl(0, F_GETFL));
ASSERT_SYS(0, 0, fcntl(0, F_GETFD));
ASSERT_SYS(0, 3, fcntl(2, F_DUPFD_CLOEXEC, 3));
ASSERT_SYS(0, 0, ioctl(0, FIOCLEX, 0));
ASSERT_SYS(EPERM, 0, isatty(0));
ASSERT_SYS(EPERM, -1, fcntl(0, -1));
ASSERT_SYS(EPERM, -1, fcntl(0, F_GETLK, &lk));
ASSERT_SYS(EPERM, -1, fcntl(0, F_NOTIFY));
ASSERT_SYS(EPERM, -1, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
_Exit(0);
}
EXPECT_NE(-1, wait(&ws));
EXPECT_TRUE(WIFEXITED(ws) && !WEXITSTATUS(ws));
}
TEST(pledge, stdioTty_sendtoRestricted_requiresNullAddr) {
if (IsOpenbsd()) return; // b/c testing linux bpf
int ws, pid, sv[2];
struct sockaddr_in sa = {AF_UNIX};
ASSERT_SYS(0, 0, socketpair(AF_UNIX, SOCK_STREAM, 0, sv));
ASSERT_NE(-1, (pid = fork()));
if (!pid) {
ASSERT_SYS(0, 0, pledge("stdio tty", 0));
ASSERT_SYS(0, 5, send(sv[0], "hello", 5, 0));
ASSERT_SYS(0, 5, sendto(sv[0], "hello", 5, 0, 0, 0));
isatty(0);
ASSERT_NE(EPERM, errno);
errno = 0;
ASSERT_SYS(EPERM, -1, sendto(sv[0], "hello", 5, 0, &sa, sizeof(sa)));
_Exit(0);
}
close(sv[0]);
close(sv[1]);
EXPECT_NE(-1, wait(&ws));
EXPECT_TRUE(WIFEXITED(ws) && !WEXITSTATUS(ws));
}
TEST(pledge, unix_forbidsInetSockets) {
if (IsOpenbsd()) return; // b/c testing linux bpf
int ws, pid;
ASSERT_NE(-1, (pid = fork()));
if (!pid) {
ASSERT_SYS(0, 0, pledge("stdio unix", 0));
ASSERT_SYS(0, 3, socket(AF_UNIX, SOCK_STREAM, 0));
ASSERT_SYS(EPERM, -1, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
ASSERT_SYS(EPERM, -1, socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP));
_Exit(0);
}
EXPECT_NE(-1, wait(&ws));
EXPECT_TRUE(WIFEXITED(ws) && !WEXITSTATUS(ws));
}
TEST(pledge, inet_forbidsOtherSockets) {
if (IsOpenbsd()) return; // b/c testing linux bpf
int ws, pid;
ASSERT_NE(-1, (pid = fork()));
if (!pid) {
ASSERT_SYS(0, 0, pledge("stdio inet", 0));
ASSERT_SYS(0, 3, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
ASSERT_SYS(0, 4, socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP));
ASSERT_SYS(EPERM, -1, socket(AF_UNIX, SOCK_STREAM, 0));
ASSERT_SYS(EPERM, -1, socket(AF_BLUETOOTH, SOCK_STREAM, 0));
_Exit(0);
}
EXPECT_NE(-1, wait(&ws));
EXPECT_TRUE(WIFEXITED(ws) && !WEXITSTATUS(ws));
}
TEST(pledge, mmap) {
if (IsOpenbsd()) return; // b/c testing linux bpf
char *p;
int ws, pid;
ASSERT_NE(-1, (pid = fork()));
if (!pid) {
ASSERT_SYS(0, 0, pledge("stdio", 0));
ASSERT_NE(MAP_FAILED, (p = mmap(0, FRAMESIZE, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)));
ASSERT_SYS(0, 0, mprotect(p, FRAMESIZE, PROT_READ));
ASSERT_SYS(EPERM, MAP_FAILED,
mprotect(p, FRAMESIZE, PROT_READ | PROT_EXEC));
ASSERT_SYS(EPERM, MAP_FAILED,
mmap(0, FRAMESIZE, PROT_EXEC | PROT_READ,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0));
_Exit(0);
}
EXPECT_NE(-1, wait(&ws));
EXPECT_TRUE(WIFEXITED(ws) && !WEXITSTATUS(ws));
}
TEST(pledge, msyscall) {
if (IsOpenbsd()) return; // b/c testing linux bpf
int ax, ws, pid;
ASSERT_NE(-1, (pid = fork()));
if (!pid) {
ASSERT_SYS(0, 0, pledge("stdio", 0));
// now issue authorized syscall where rip isn't privileged
asm volatile("syscall"
: "=a"(ax)
: "0"(__NR_linux_dup), "D"(2)
: "rcx", "r11", "memory");
_Exit(1);
}
EXPECT_NE(-1, wait(&ws));
EXPECT_TRUE(WIFSIGNALED(ws));
EXPECT_EQ(SIGSYS, WTERMSIG(ws));
}
TEST(pledge, chmod_ignoresDangerBits) {
if (IsOpenbsd()) return; // b/c testing linux bpf
int ws, pid;
struct stat st;
ASSERT_SYS(0, 3, creat("foo", 0644));
ASSERT_NE(-1, (pid = fork()));
if (!pid) {
ASSERT_SYS(0, 0, pledge("stdio rpath", 0));
ASSERT_SYS(0, 0, fchmod(3, 00700));
ASSERT_SYS(0, 0, chmod("foo", 00700));
ASSERT_SYS(0, 0, fchmodat(AT_FDCWD, "foo", 00700, 0));
ASSERT_SYS(EPERM, -1, fchmod(3, 07700));
ASSERT_SYS(EPERM, -1, chmod("foo", 04700));
ASSERT_SYS(EPERM, -1, fchmodat(AT_FDCWD, "foo", 02700, 0));
_Exit(0);
}
EXPECT_NE(-1, wait(&ws));
EXPECT_TRUE(WIFEXITED(ws) && !WEXITSTATUS(ws));
close(3);
}
TEST(pledge, open_rpath) {
if (IsOpenbsd()) return; // b/c testing linux bpf
int ws, pid;
struct stat st;
ASSERT_SYS(0, 0, touch("foo", 0644));
ASSERT_NE(-1, (pid = fork()));
if (!pid) {
ASSERT_SYS(0, 0, pledge("stdio rpath", 0));
ASSERT_SYS(0, 3, open("foo", O_RDONLY));
ASSERT_SYS(EPERM, -1, open("foo", O_RDWR | O_TRUNC | O_CREAT, 0644));
ASSERT_SYS(EPERM, -1, open("foo", O_WRONLY | O_TRUNC | O_CREAT, 0644));
_Exit(0);
}
EXPECT_NE(-1, wait(&ws));
EXPECT_TRUE(WIFEXITED(ws) && !WEXITSTATUS(ws));
close(3);
}
TEST(pledge, open_wpath) {
if (IsOpenbsd()) return; // b/c testing linux bpf
int ws, pid;
struct stat st;
ASSERT_SYS(0, 0, touch("foo", 0644));
ASSERT_NE(-1, (pid = fork()));
if (!pid) {
ASSERT_SYS(0, 0, pledge("stdio wpath", 0));
ASSERT_SYS(0, 3, open("foo", O_RDONLY));
ASSERT_SYS(EPERM, -1, open(".", O_RDWR | O_TMPFILE, 07644));
ASSERT_SYS(EPERM, -1, open("foo", O_WRONLY | O_TRUNC | O_CREAT, 07644));
ASSERT_SYS(0, 4, open("foo", O_WRONLY | O_TRUNC | O_CREAT, 0644));
_Exit(0);
}
EXPECT_NE(-1, wait(&ws));
EXPECT_TRUE(WIFEXITED(ws) && !WEXITSTATUS(ws));
close(3);
}

View file

@ -37,6 +37,7 @@ TEST_LIBC_MEM_DIRECTDEPS = \
LIBC_NEXGEN32E \
LIBC_RAND \
LIBC_RUNTIME \
LIBC_SOCK \
LIBC_STDIO \
LIBC_STR \
LIBC_STUBS \

View file

@ -32,6 +32,11 @@ STATIC_YOINK("apetest2.com");
char testlib_enable_tmp_setup_teardown_once;
__attribute__((__constructor__)) static void init(void) {
// TODO(jart): What's up with RHEL5 / RHEL7?
// pledge("stdio rpath wpath cpath tty proc exec", 0);
}
void Extract(const char *from, const char *to, int mode) {
ASSERT_SYS(0, 3, open(from, O_RDONLY));
ASSERT_SYS(0, 4, creat(to, mode));

View file

@ -21,6 +21,10 @@
#include "libc/dce.h"
#include "libc/testlib/testlib.h"
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath", 0);
}
TEST(arch_prctl, fs) {
if (IsLinux() || IsOpenbsd()) {
uint64_t n, x;

View file

@ -42,6 +42,10 @@ char *stack, *tls;
int x, me, tid, *childetid;
_Atomic(int) thechilde;
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath thread", 0);
}
void SetUp(void) {
x = 0;
me = gettid();

View file

@ -29,6 +29,10 @@
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath proc", 0);
}
TEST(fork, testPipes) {
int a, b;
int ws, pid;

View file

@ -16,6 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/errno.h"
#include "libc/intrin/kprintf.h"
#include "libc/limits.h"
@ -30,6 +31,10 @@
#define I(x, y) \
{ x, y, 0, (y - x) * FRAMESIZE + FRAMESIZE }
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath", 0);
}
static bool AreMemoryIntervalsEqual(const struct MemoryIntervals *mm1,
const struct MemoryIntervals *mm2) {
if (mm1->i != mm2->i) return false;

View file

@ -48,6 +48,10 @@
char testlib_enable_tmp_setup_teardown;
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath wpath cpath proc", 0);
}
TEST(mmap, zeroSize) {
ASSERT_SYS(EINVAL, MAP_FAILED,
mmap(NULL, 0, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0));

View file

@ -37,6 +37,10 @@
#include "tool/decode/lib/flagger.h"
#include "tool/decode/lib/pollnames.h"
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath proc inet", 0);
}
dontdiscard char *FormatPollFd(struct pollfd p[2]) {
return xasprintf("fd:%d revents:%s\n"
"fd:%d revents:%s\n",

View file

@ -23,6 +23,10 @@
#include "libc/testlib/testlib.h"
#include "libc/time/time.h"
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath", 0);
}
// TEST(select, allZero) {
// // todo: figure out how to test block until signal w/ select
// EXPECT_SYS(0, 0, select(0, 0, 0, 0, 0));

View file

@ -27,6 +27,10 @@
#include "libc/sysv/consts/sol.h"
#include "libc/testlib/testlib.h"
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath inet", 0);
}
TEST(setsockopt, SO_RCVTIMEO) {
char buf[32];
struct timeval tv = {0, 10000};

View file

@ -25,6 +25,10 @@
#include "libc/sysv/consts/sock.h"
#include "libc/testlib/testlib.h"
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath tty", 0);
}
TEST(socketpair, testAfUnixStream) {
int fd[2];
const char ping[] = "ping";

View file

@ -31,6 +31,10 @@
#include "libc/testlib/testlib.h"
#include "libc/time/time.h"
__attribute__((__constructor__)) static void init(void) {
pledge("stdio rpath cpath proc unix", 0);
}
char testlib_enable_tmp_setup_teardown;
void DatagramServer(void) {

View file

@ -31,6 +31,7 @@
#include "libc/calls/struct/sigaction.h"
#include "libc/errno.h"
#include "libc/intrin/nomultics.internal.h"
#include "libc/intrin/pthread.h"
#include "libc/log/check.h"
#include "libc/macros.internal.h"
#include "libc/mem/mem.h"
@ -68,11 +69,19 @@ static const char *const kKeywordHints[] = {
bool lua_repl_blocking;
bool lua_repl_isterminal;
linenoiseCompletionCallback *lua_repl_completions_callback;
_Alignas(64) char lua_repl_lock;
struct linenoiseState *lua_repl_linenoise;
static lua_State *globalL;
static const char *g_progname;
static const char *g_historypath;
static pthread_mutex_t lua_repl_lock_obj;
void(lua_repl_lock)(void) {
pthread_mutex_lock(&lua_repl_lock_obj);
}
void(lua_repl_unlock)(void) {
pthread_mutex_unlock(&lua_repl_lock_obj);
}
/*
** {==================================================================
@ -239,7 +248,7 @@ static ssize_t pushline (lua_State *L, int firstline) {
prmt = strdup(get_prompt(L, firstline));
lua_pop(L, 1); /* remove prompt */
if (lua_repl_isterminal) {
LUA_REPL_UNLOCK;
lua_repl_unlock();
rc = linenoiseEdit(lua_repl_linenoise, prmt, &b, !firstline || lua_repl_blocking);
free(prmt);
if (rc != -1) {
@ -249,9 +258,9 @@ static ssize_t pushline (lua_State *L, int firstline) {
linenoiseHistorySave(g_historypath);
}
}
LUA_REPL_LOCK;
lua_repl_lock();
} else {
LUA_REPL_UNLOCK;
lua_repl_unlock();
fputs(prmt, stdout);
fflush(stdout);
b = linenoiseGetLine(stdin);
@ -262,7 +271,7 @@ static ssize_t pushline (lua_State *L, int firstline) {
} else {
rc = 0;
}
LUA_REPL_LOCK;
lua_repl_lock();
}
if (!(rc == -1 && errno == EAGAIN)) {
write(1, "\n", 1);
@ -330,7 +339,7 @@ static int multiline (lua_State *L) {
void lua_initrepl(lua_State *L, const char *progname) {
const char *prompt;
LUA_REPL_LOCK;
lua_repl_lock();
g_progname = progname;
if ((lua_repl_isterminal = linenoiseIsTerminal())) {
linenoiseSetCompletionCallback(lua_readline_completions);
@ -349,16 +358,16 @@ void lua_initrepl(lua_State *L, const char *progname) {
__replmode = true;
if (isatty(2)) __replstderr = true;
}
LUA_REPL_UNLOCK;
lua_repl_unlock();
}
void lua_freerepl(void) {
LUA_REPL_LOCK;
lua_repl_lock();
__replmode = false;
linenoiseEnd(lua_repl_linenoise);
free(g_historypath);
LUA_REPL_UNLOCK;
lua_repl_unlock();
}
@ -375,16 +384,16 @@ int lua_loadline (lua_State *L) {
ssize_t rc;
int status;
lua_settop(L, 0);
LUA_REPL_LOCK;
lua_repl_lock();
if ((rc = pushline(L, 1)) != 1) {
LUA_REPL_UNLOCK;
lua_repl_unlock();
return rc - 1; /* eof or error */
}
if ((status = addreturn(L)) != LUA_OK) /* 'return ...' did not work? */
status = multiline(L); /* try as command, maybe with continuation lines */
lua_remove(L, 1); /* remove line from the stack */
lua_assert(lua_gettop(L) == 1);
LUA_REPL_UNLOCK;
lua_repl_unlock();
return status;
}

View file

@ -1,31 +1,19 @@
#ifndef COSMOPOLITAN_THIRD_PARTY_LUA_LREPL_H_
#define COSMOPOLITAN_THIRD_PARTY_LUA_LREPL_H_
#include "libc/dce.h"
#include "libc/intrin/spinlock.h"
#include "libc/intrin/nopl.h"
#include "third_party/linenoise/linenoise.h"
#include "third_party/lua/lauxlib.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
#if !defined(STATIC) && SupportsWindows()
#define LUA_REPL_LOCK _spinlock(&lua_repl_lock)
#else
#define LUA_REPL_LOCK (void)0
#endif
#if !defined(STATIC) && SupportsWindows()
#define LUA_REPL_UNLOCK _spunlock(&lua_repl_lock)
#else
#define LUA_REPL_UNLOCK (void)0
#endif
extern char lua_repl_lock;
extern bool lua_repl_blocking;
extern bool lua_repl_isterminal;
extern struct linenoiseState *lua_repl_linenoise;
extern linenoiseCompletionCallback *lua_repl_completions_callback;
void lua_freerepl(void);
void lua_repl_lock(void);
void lua_repl_unlock(void);
int lua_loadline(lua_State *);
void lua_l_print(lua_State *);
void lua_sigint(lua_State *, int);
@ -36,6 +24,11 @@ void lua_l_message(const char *, const char *);
char *lua_readline_hint(const char *, const char **, const char **);
void lua_readline_completions(const char *, linenoiseCompletions *);
#ifdef _NOPL0
#define lua_repl_lock() _NOPL0("__threadcalls", lua_repl_lock)
#define lua_repl_unlock() _NOPL0("__threadcalls", lua_repl_unlock)
#endif
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_THIRD_PARTY_LUA_LREPL_H_ */

View file

@ -31,6 +31,7 @@
#include "libc/calls/struct/stat.h"
#include "libc/calls/struct/timespec.h"
#include "libc/calls/struct/timeval.h"
#include "libc/calls/struct/winsize.h"
#include "libc/calls/ucontext.h"
#include "libc/dns/dns.h"
#include "libc/errno.h"
@ -1803,6 +1804,29 @@ static int LuaUnixSissock(lua_State *L) {
return 1;
}
// unix.isatty(fd:int)
// ├─→ true
// └─→ nil, unix.Errno
static int LuaUnixIsatty(lua_State *L) {
int olderr = errno;
return SysretBool(L, "isatty", olderr, isatty(luaL_checkinteger(L, 1)));
}
// unix.tiocgwinsz(fd:int)
// ├─→ rows:int, cols:int
// └─→ nil, unix.Errno
static int LuaUnixTiocgwinsz(lua_State *L) {
struct winsize ws;
int olderr = errno;
if (!ioctl(luaL_checkinteger(L, 1), TIOCGWINSZ, &ws)) {
lua_pushinteger(L, ws.ws_row);
lua_pushinteger(L, ws.ws_col);
return 2;
} else {
return SysretErrno(L, "tiocgwinsz", olderr);
}
}
////////////////////////////////////////////////////////////////////////////////
// unix.Stat object
@ -2505,8 +2529,10 @@ static const luaL_Reg kLuaUnix[] = {
{"getsid", LuaUnixGetsid}, // get session id of pid
{"getsockname", LuaUnixGetsockname}, // get address of local end
{"getsockopt", LuaUnixGetsockopt}, // get socket tunings
{"tiocgwinsz", LuaUnixTiocgwinsz}, // pseudoteletypewriter dimensions
{"getuid", LuaUnixGetuid}, // get real user id of process
{"gmtime", LuaUnixGmtime}, // destructure unix timestamp
{"isatty", LuaUnixIsatty}, // detects pseudoteletypewriters
{"kill", LuaUnixKill}, // signal child process
{"link", LuaUnixLink}, // create hard link
{"listen", LuaUnixListen}, // begin listening for clients
@ -2658,6 +2684,7 @@ int LuaUnix(lua_State *L) {
LuaSetIntField(L, "MSG_PEEK", MSG_PEEK);
LuaSetIntField(L, "MSG_OOB", MSG_OOB);
LuaSetIntField(L, "MSG_NOSIGNAL", MSG_NOSIGNAL);
LuaSetIntField(L, "MSG_MORE", MSG_MORE);
// readdir() type
LuaSetIntField(L, "DT_UNKNOWN", DT_UNKNOWN);

View file

@ -685,6 +685,7 @@ void StartInteractive(void) {
isatty(fileno(stdout)) && !__nocolor) {
interactive = true;
}
errno = 0;
if (interactive) {
fputs(BANNER, stdout);
fflush(/* needed b/c entering tty mode */ stdout);

View file

@ -130,7 +130,6 @@ KEYBOARD
PROTIP REMAP CAPS LOCK TO CTRL
────────────────────────────────────────────────────────────────────────────────
USAGE
This executable is also a ZIP file that contains static assets.
@ -239,7 +238,6 @@ USAGE
redbean.com: ELF 64-bit LSB executable
────────────────────────────────────────────────────────────────────────────────
SECURITY
redbean uses a protocol polyglot for serving HTTP and HTTPS on
@ -258,7 +256,6 @@ SECURITY
See http://redbean.dev for further details.
────────────────────────────────────────────────────────────────────────────────
LUA SERVER PAGES
Any files with the extension .lua will be dynamically served by redbean.
@ -299,7 +296,6 @@ LUA SERVER PAGES
isolated processes are cloned from the blueprint you created.
────────────────────────────────────────────────────────────────────────────────
REPL
Your redbean displays a Read-Eval-Print-Loop that lets you modify the
@ -352,7 +348,6 @@ REPL
────────────────────────────────────────────────────────────────────────────────
LUA ENHANCEMENTS
We've made some enhancements to the Lua language that should make it
@ -375,7 +370,6 @@ LUA ENHANCEMENTS
────────────────────────────────────────────────────────────────────────────────
GLOBALS
arg: array[str]
@ -409,7 +403,6 @@ GLOBALS
arg[ 2] = 'arg2'
────────────────────────────────────────────────────────────────────────────────
SPECIAL PATHS
/
@ -496,7 +489,6 @@ SPECIAL PATHS
of your `.args` file.
────────────────────────────────────────────────────────────────────────────────
HOOKS
OnHttpRequest()
@ -545,7 +537,6 @@ HOOKS
in uniprocess mode.
────────────────────────────────────────────────────────────────────────────────
FUNCTIONS
Write(data:str)
@ -1491,7 +1482,6 @@ FUNCTIONS
────────────────────────────────────────────────────────────────────────────────
CONSTANTS
kLogDebug
@ -1515,7 +1505,6 @@ CONSTANTS
process exit.
────────────────────────────────────────────────────────────────────────────────
LSQLITE3 MODULE
Please refer to the LuaSQLite3 Documentation.
@ -1552,7 +1541,6 @@ LSQLITE3 MODULE
administrate your redbean database. See the sqlite3.com download above.
────────────────────────────────────────────────────────────────────────────────
RE MODULE
This module exposes an API for POSIX regular expressions which enable you
@ -1622,7 +1610,6 @@ RE MODULE
regex_t*:search.
────────────────────────────────────────────────────────────────────────────────
MAXMIND MODULE
This module may be used to get city/country/asn/etc from IPs, e.g.
@ -1644,7 +1631,6 @@ MAXMIND MODULE
For further details, please see maxmind.lua in redbean-demo.com.
────────────────────────────────────────────────────────────────────────────────
ARGON2 MODULE
This module implemeents a password hashing algorithm based on blake2b
@ -1712,7 +1698,6 @@ ARGON2 MODULE
true
────────────────────────────────────────────────────────────────────────────────
UNIX MODULE
This module exposes the low-level System Five system call interface.
@ -2857,9 +2842,10 @@ UNIX MODULE
`flags` may have any combination (using bitwise OR) of:
- `MSG_OOB`
- `MSG_DONTROUTE`
- `MSG_NOSIGNAL`
- `MSG_NOSIGNAL`: Don't SIGPIPE on EOF
- `MSG_OOB`: Send stream data through out of bound channel
- `MSG_DONTROUTE`: Don't go through gateway (for diagnostics)
- `MSG_MORE`: Manual corking to belay nodelay (0 on non-Linux)
unix.sendto(fd:int, data:str, ip:uint32, port:uint16[, flags:int])
unix.sendto(fd:int, data:str, unixpath:str[, flags:int])
@ -3103,85 +3089,106 @@ UNIX MODULE
This can be used to sandbox your redbean workers. It allows finer
customization compared to the `-S` flag.
Pledging causes most system calls to become unavailable. On Linux the
disabled calls will return EPERM whereas OpenBSD kills the process.
Using pledge is irreversible. On Linux it causes PR_SET_NO_NEW_PRIVS
to be set on your process.
By default exit and exit_group are always allowed. This is useful
for processes that perform pure computation and interface with the
parent via shared memory.
Currently only available on OpenBSD and Linux. On Linux, the default
action when your policy is violated is to return `EPERM`. On OpenBSD
the kernel will kill the process.
Once pledge is in effect, the chmod functions (if allowed) will not
permit the sticky/setuid/setgid bits to change. Linux will EPERM here
and OpenBSD should ignore those three bits rather than crashing.
User and group IDs also can't be changed once pledge is in effect.
OpenBSD should ignore the chown functions without crashing. Linux
will just EPERM.
Memory functions won't permit creating executable code after pledge.
Restrictions on origin of SYSCALL instructions will become enforced
on Linux (cf. msyscall) after pledge too, which means the process
gets killed if SYSCALL is used outside the .privileged section. One
exception is if the "exec" group is specified, in which case these
restrictions need to be loosened.
`promises` is a string that may include any of the following groups
delimited by spaces.
stdio
Allows clock_getres, clock_gettime, close, dup, dup2, dup3,
fchdir, fstat, fsync, ftruncate, getdents, getegid, getrandom,
Allows read, write, send, recv, recvfrom, recvmsg, close,
clock_getres, clock_gettime, dup, dup2, dup3, fchdir, fstat,
fsync, fdatasync, ftruncate, getdents, getegid, getrandom,
geteuid, getgid, getgroups, getitimer, getpgid, getpgrp, getpid,
getppid, getresgid, getresuid, getrlimit, getsid, gettimeofday,
getuid, lseek, madvise, brk, mmap, mprotect, munmap, nanosleep,
pipe, pipe2, poll, pread, preadv, pwrite, pwritev, read, readv,
recvfrom, recvmsg, select, sendmsg, sendto, setitimer, shutdown,
sigaction, sigprocmask, sigreturn, socketpair, umask, wait4,
write, writev.
getuid, lseek, madvise, brk, mmap/mprotect (PROT_EXEC isn't
allowed), msync, munmap, gethostname, nanosleep, pipe, pipe2,
poll, setitimer, shutdown, sigaction, sigsuspend, sigprocmask,
socketpair, umask, wait4, ioctl(FIONREAD), ioctl(FIONBIO),
ioctl(FIOCLEX), ioctl(FIONCLEX), fcntl(F_GETFD), fcntl(F_SETFD),
fcntl(F_GETFL), fcntl(F_SETFL).
rpath
Allows chdir, getcwd, openat, fstatat, faccessat, readlinkat,
lstat, chmod, fchmod, fchmodat, chown, fchown, fchownat, fstat.
Allows chdir, getcwd, open, stat, fstat, access, readlink, chmod,
chmod, fchmod.
wpath
Allows getcwd, openat, fstatat, faccessat, readlinkat, lstat,
chmod, fchmod, fchmodat, chown, fchown, fchownat, fstat.
Allows getcwd, open, stat, fstat, access, readlink, chmod, fchmod.
cpath
Allows rename, renameat, link, linkat, symlink, symlinkat, unlink,
unlinkat, mkdir, mkdirat, rmdir.
dpath
Allows mknod
tmppath
Allows lstat, chmod, chown, unlink, fstat.
inet
Allows socket, listen, bind, connect, accept4, accept,
getpeername, getsockname, setsockopt, getsockopt.
Allows rename, link, symlink, unlink, mkdir, rmdir.
fattr
Allows utimes, utimensat, chmod, fchmod, fchmodat, chown,
fchownat, lchown, fchown, utimes.
Allows chmod, fchmod, utimensat, futimens.
flock
Allows flock, fcntl(F_GETLK), fcntl(F_SETLK), fcntl(F_SETLKW).
tty
Allows isatty, tiocgwinsz, tcgets, tcsets, tcsetsw, tcsetsf.
inet
Allows socket (AF_INET), listen, bind, connect, accept,
getpeername, getsockname, setsockopt, getsockopt.
unix
Allows socket, listen, bind, connect, accept4, accept,
Allows socket (AF_UNIX), listen, bind, connect, accept,
getpeername, getsockname, setsockopt, getsockopt.
dns
Allows sendto, recvfrom, socket, connect.
Allows sendto, recvfrom, socket (AF_INET), connect.
proc
Allows fork, vfork, kill, getpriority, setpriority, setrlimit,
setpgid, setsid.
exec
Allows execve.
Allows fork, vfork, clone, kill, getpriority, setpriority,
setrlimit, setpgid, setsid.
id
Allows setuid, setreuid, setresuid, setgid, setregid, setresgid,
setgroups, setrlimit, getpriority, setpriority.
exec
Allows execve.
If this is used then APE binaries should be assimilated in order
to work on OpenBSD. On Linux, mmap() will be loosened up to allow
creating PROT_EXEC memory (for APE loader) and system call origin
verification won't be activated.
unix.gmtime(unixts:int)
├─→ year,mon,mday,hour,min,sec,gmtoffsec,wday,yday,dst:int,zone:str
└─→ nil,unix.Errno
@ -3295,9 +3302,20 @@ UNIX MODULE
returned unix.Dir ownership takes ownership of the file descriptor
and will close it automatically when garbage collected.
unix.isatty(fd:int)
├─→ true
└─→ nil, unix.Errno
Returns true if file descriptor is a pseudoteletypewriter.
unix.tiocgwinsz(fd:int)
├─→ rows:int, cols:int
└─→ nil, unix.Errno
Returns cellular dimensions of pseudoteletypewriter display.
────────────────────────────────────────────────────────────────────────────────
UNIX DIR OBJECT
unix.Dir objects are created by opendir() or fdopendir(). The
@ -3357,7 +3375,6 @@ UNIX MODULE
────────────────────────────────────────────────────────────────────────────────
UNIX RUSAGE OBJECT
unix.Rusage objects are created by wait() or getrusage(). The
@ -3524,7 +3541,6 @@ UNIX MODULE
────────────────────────────────────────────────────────────────────────────────
UNIX STAT OBJECT
unix.Stat objects are created by stat() or fstat(). The following
@ -3667,7 +3683,6 @@ UNIX MODULE
────────────────────────────────────────────────────────────────────────────────
UNIX SIGSET OBJECT
The unix.Sigset class defines a mutable bitset that may currently
@ -3707,7 +3722,6 @@ UNIX MODULE
────────────────────────────────────────────────────────────────────────────────
UNIX SIGNAL MAGNUMS
unix.SIGINT
@ -3795,7 +3809,6 @@ UNIX MODULE
────────────────────────────────────────────────────────────────────────────────
UNIX ERRNO OBJECT
This object is returned by system calls that fail. We prefer returning
@ -3860,7 +3873,6 @@ UNIX MODULE
────────────────────────────────────────────────────────────────────────────────
UNIX ERROR MAGNUMS
unix.EINVAL
@ -4287,7 +4299,6 @@ UNIX MODULE
────────────────────────────────────────────────────────────────────────────────
UNIX MISCELLANEOUS MAGNUMS
unix.ARG_MAX
@ -4366,7 +4377,6 @@ UNIX MODULE
────────────────────────────────────────────────────────────────────────────────
LEGAL
redbean contains software licensed ISC, MIT, BSD-2, BSD-3, zlib
@ -4379,7 +4389,6 @@ LEGAL
────────────────────────────────────────────────────────────────────────────────
SEE ALSO
https://redbean.dev/

View file

@ -37,6 +37,7 @@
#include "libc/fmt/itoa.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/nomultics.internal.h"
#include "libc/intrin/spinlock.h"
#include "libc/intrin/wait0.internal.h"
#include "libc/log/check.h"
#include "libc/log/log.h"
@ -3430,8 +3431,8 @@ static void StoreAsset(char *path, size_t pathlen, char *data, size_t datalen,
}
//////////////////////////////////////////////////////////////////////////////
if (-1 == fcntl(zfd, F_SETLKW, &(struct flock){F_WRLCK})) {
WARNF("can't place write lock on file descriptor %d: %s",
zfd, strerror(errno));
WARNF("can't place write lock on file descriptor %d: %s", zfd,
strerror(errno));
return;
}
OpenZip(false);
@ -3592,7 +3593,7 @@ static void StoreFile(char *path) {
tlen = strlen(target);
if (!IsReasonablePath(target, tlen))
FATALF("(cfg) error: can't store %`'s: contains '.' or '..' segments",
target);
target);
if (lstat(path, &st) == -1) FATALF("(cfg) error: can't stat %`'s: %m", path);
if (!(p = xslurp(path, &plen)))
FATALF("(cfg) error: can't read %`'s: %m", path);
@ -4950,7 +4951,8 @@ static bool LuaRunAsset(const char *path, bool mandatory) {
effectivepath.p = path;
effectivepath.n = pathlen;
DEBUGF("(lua) LuaRunAsset(%`'s)", path);
status = luaL_loadbuffer(L, code, codelen,
status = luaL_loadbuffer(
L, code, codelen,
FreeLater(xasprintf("@%s%s", a->file ? "" : "/zip", path)));
if (status != LUA_OK || LuaCallWithTrace(L, 0, 0, NULL) != LUA_OK) {
LogLuaError("lua code", lua_tostring(L, -1));
@ -6838,7 +6840,7 @@ static int HandleReadline(void) {
}
}
DisableRawMode();
LUA_REPL_LOCK;
lua_repl_lock();
if (status == LUA_OK) {
status = lua_runchunk(L, 0, LUA_MULTRET);
}
@ -6847,7 +6849,7 @@ static int HandleReadline(void) {
} else {
lua_report(L, status);
}
LUA_REPL_UNLOCK;
lua_repl_unlock();
EnableRawMode();
}
}
@ -6863,14 +6865,14 @@ static int HandlePoll(int ms) {
if (polls[pollid].fd < 0) continue;
if (polls[pollid].fd) {
// handle listen socket
LUA_REPL_LOCK;
lua_repl_lock();
serverid = pollid - 1;
assert(0 <= serverid && serverid < servers.n);
serveraddr = &servers.p[serverid].addr;
ishandlingconnection = true;
rc = HandleConnection(serverid);
ishandlingconnection = false;
LUA_REPL_UNLOCK;
lua_repl_unlock();
if (rc == -1) return -1;
#ifndef STATIC
} else {
@ -6991,18 +6993,18 @@ static int EventLoop(int ms) {
while (!terminated) {
errno = 0;
if (zombied) {
LUA_REPL_LOCK;
lua_repl_lock();
ReapZombies();
LUA_REPL_UNLOCK;
lua_repl_unlock();
} else if (invalidated) {
LUA_REPL_LOCK;
lua_repl_lock();
HandleReload();
LUA_REPL_UNLOCK;
lua_repl_unlock();
invalidated = false;
} else if (meltdown) {
LUA_REPL_LOCK;
lua_repl_lock();
EnterMeltdownMode();
LUA_REPL_UNLOCK;
lua_repl_unlock();
meltdown = false;
} else if ((t = nowl()) - lastheartbeat > HEARTBEAT / 1000.) {
lastheartbeat = t;
@ -7043,9 +7045,9 @@ static int WindowsReplThread(void *arg) {
}
DisableRawMode();
lua_freerepl();
LUA_REPL_LOCK;
lua_repl_lock();
lua_settop(L, 0); // clear stack
LUA_REPL_UNLOCK;
lua_repl_unlock();
if ((sig = linenoiseGetInterrupt())) {
raise(sig);
}

View file

@ -8,7 +8,7 @@
#define _SECCOMP_MACHINE(MAGNUM) \
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, arch)), \
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, AUDIT_ARCH_X86_64, 1, 0), \
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, MAGNUM, 1, 0), \
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL_PROCESS)
#define _SECCOMP_LOAD_SYSCALL_NR() \