mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-04-15 04:08:47 +00:00
Add seccomp bpf sandboxing to redbean
It's now possible to pass the `-S` or `-SS` flags to sandbox redbean worker proecsses after they've been forked. The first `-S` flag is intended to be a permissive builtin policy that limits system calls to only that which the various parts of redbean serving need. The second `-SS` flag is intended to be more restrictive, preventing things like the Lua extensions you download off the web from using the HTTP client or sockets APIs. In upcoming changes you'll be able to implement your own Berkeley Packet Filter sandbox programs and load them via Lua.
This commit is contained in:
parent
7166679620
commit
5a132f9652
79 changed files with 2271 additions and 651 deletions
|
@ -1,10 +0,0 @@
|
||||||
#ifndef COSMOPOLITAN_LIBC_CALLS_ISSANDBOXED_INTERNAL_H_
|
|
||||||
#define COSMOPOLITAN_LIBC_CALLS_ISSANDBOXED_INTERNAL_H_
|
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
|
||||||
COSMOPOLITAN_C_START_
|
|
||||||
|
|
||||||
extern bool __issandboxed;
|
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
|
||||||
#endif /* COSMOPOLITAN_LIBC_CALLS_ISSANDBOXED_INTERNAL_H_ */
|
|
|
@ -19,8 +19,22 @@
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/strace.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
|
#include "libc/sysv/consts/pr.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
|
||||||
|
static const char *DescribePrctlOperation(int x) {
|
||||||
|
switch (x) {
|
||||||
|
case PR_SET_NO_NEW_PRIVS:
|
||||||
|
return "PR_SET_NO_NEW_PRIVS";
|
||||||
|
case PR_SET_SECCOMP:
|
||||||
|
return "PR_SET_SECCOMP";
|
||||||
|
case PR_GET_SECCOMP:
|
||||||
|
return "PR_GET_SECCOMP";
|
||||||
|
default:
|
||||||
|
return "PRCTL_???";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tunes process on Linux.
|
* Tunes process on Linux.
|
||||||
*
|
*
|
||||||
|
@ -47,6 +61,7 @@ int prctl(int operation, ...) {
|
||||||
} else {
|
} else {
|
||||||
rc = enosys();
|
rc = enosys();
|
||||||
}
|
}
|
||||||
STRACE("seccomp(%d, %p, %p, %p, %p) → %d% m", operation, a, b, c, d, rc);
|
STRACE("prctl(%s, %p, %p, %p, %p) → %d% m", DescribePrctlOperation(operation),
|
||||||
|
a, b, c, d, rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,8 +42,7 @@
|
||||||
*/
|
*/
|
||||||
ssize_t readv(int fd, const struct iovec *iov, int iovlen) {
|
ssize_t readv(int fd, const struct iovec *iov, int iovlen) {
|
||||||
int i;
|
int i;
|
||||||
ssize_t rc, rem;
|
ssize_t rc;
|
||||||
|
|
||||||
if (fd >= 0 && iovlen >= 0) {
|
if (fd >= 0 && iovlen >= 0) {
|
||||||
if (IsAsan() && !__asan_is_valid_iov(iov, iovlen)) {
|
if (IsAsan() && !__asan_is_valid_iov(iov, iovlen)) {
|
||||||
rc = efault();
|
rc = efault();
|
||||||
|
@ -66,27 +65,16 @@ ssize_t readv(int fd, const struct iovec *iov, int iovlen) {
|
||||||
} else {
|
} else {
|
||||||
rc = einval();
|
rc = einval();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(SYSDEBUG) && _DATATRACE
|
#if defined(SYSDEBUG) && _DATATRACE
|
||||||
if (__strace > 0) {
|
if (__strace > 0) {
|
||||||
if (rc == -1 && errno == EFAULT) {
|
if (rc == -1 && errno == EFAULT) {
|
||||||
STRACE("readv(%d, %p, %d) → %'zd% m", fd, iov, iovlen, rc);
|
STRACE("readv(%d, %p, %d) → %'zd% m", fd, iov, iovlen, rc);
|
||||||
} else {
|
} else {
|
||||||
rem = rc != -1 ? rc : 0;
|
kprintf(STRACE_PROLOGUE "readv(%d, [", fd);
|
||||||
kprintf(STRACE_PROLOGUE "readv(%d, [{", fd);
|
__strace_iov(iov, iovlen, rc != -1 ? rc : 0);
|
||||||
for (i = 0; i < MIN(5, iovlen); ++i) {
|
kprintf("], %d) → %'ld% m%n", iovlen, rc);
|
||||||
kprintf("%s{%#.*hhs%s, %'zu}", i ? ", " : "",
|
|
||||||
MAX(0, MIN(40, MIN(rem, iov[i].iov_len))), iov[i].iov_base,
|
|
||||||
MAX(0, MIN(40, MIN(rem, iov[i].iov_len))) < iov[i].iov_len
|
|
||||||
? "..."
|
|
||||||
: "",
|
|
||||||
iov[i].iov_len);
|
|
||||||
rem -= iov[i].iov_len;
|
|
||||||
}
|
|
||||||
kprintf("%s}], %d) → %'ld% m%n", iovlen > 5 ? "..." : "", iovlen, rc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,15 +17,29 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/issandboxed.h"
|
|
||||||
#include "libc/calls/strace.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
|
#include "libc/calls/struct/seccomp.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/intrin/describeflags.internal.h"
|
#include "libc/intrin/describeflags.internal.h"
|
||||||
#include "libc/sysv/consts/pr.h"
|
#include "libc/sysv/consts/pr.h"
|
||||||
#include "libc/sysv/consts/seccomp.h"
|
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
|
||||||
|
static const char *DescribeSeccompOperation(int x) {
|
||||||
|
switch (x) {
|
||||||
|
case SECCOMP_SET_MODE_STRICT:
|
||||||
|
return "SECCOMP_SET_MODE_STRICT";
|
||||||
|
case SECCOMP_SET_MODE_FILTER:
|
||||||
|
return "SECCOMP_SET_MODE_FILTER";
|
||||||
|
case SECCOMP_GET_ACTION_AVAIL:
|
||||||
|
return "SECCOMP_GET_ACTION_AVAIL";
|
||||||
|
case SECCOMP_GET_NOTIF_SIZES:
|
||||||
|
return "SECCOMP_GET_NOTIF_SIZES";
|
||||||
|
default:
|
||||||
|
return "SECCOMP_???";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tunes Linux security policy.
|
* Tunes Linux security policy.
|
||||||
*
|
*
|
||||||
|
@ -63,7 +77,7 @@ int seccomp(unsigned operation, unsigned flags, void *args) {
|
||||||
} else {
|
} else {
|
||||||
rc = enosys();
|
rc = enosys();
|
||||||
}
|
}
|
||||||
STRACE("seccomp(%s, %#x, %p) → %d% m",
|
STRACE("seccomp(%s, %#x, %p) → %d% m", DescribeSeccompOperation(operation),
|
||||||
DescribeSeccompOperationFlags(operation), flags, args, rc);
|
flags, args, rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#ifndef COSMOPOLITAN_LIBC_CALLS_STRACE_INTERNAL_H_
|
#ifndef COSMOPOLITAN_LIBC_CALLS_STRACE_INTERNAL_H_
|
||||||
#define COSMOPOLITAN_LIBC_CALLS_STRACE_INTERNAL_H_
|
#define COSMOPOLITAN_LIBC_CALLS_STRACE_INTERNAL_H_
|
||||||
|
#include "libc/calls/struct/iovec.h"
|
||||||
#include "libc/calls/struct/rlimit.h"
|
#include "libc/calls/struct/rlimit.h"
|
||||||
#include "libc/calls/struct/sigaction.h"
|
#include "libc/calls/struct/sigaction.h"
|
||||||
#include "libc/calls/struct/stat.h"
|
#include "libc/calls/struct/stat.h"
|
||||||
|
@ -53,6 +54,7 @@ COSMOPOLITAN_C_START_
|
||||||
extern int __strace;
|
extern int __strace;
|
||||||
|
|
||||||
void __stracef(const char *, ...);
|
void __stracef(const char *, ...);
|
||||||
|
void __strace_iov(const struct iovec *, int, ssize_t);
|
||||||
const char *__strace_stat(int, const struct stat *);
|
const char *__strace_stat(int, const struct stat *);
|
||||||
const char *__strace_sigaction(char *, size_t, int, const struct sigaction *);
|
const char *__strace_sigaction(char *, size_t, int, const struct sigaction *);
|
||||||
const char *__strace_sigset(char[41], size_t, int, const sigset_t *);
|
const char *__strace_sigset(char[41], size_t, int, const sigset_t *);
|
||||||
|
|
|
@ -16,20 +16,20 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/intrin/describeflags.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
|
#include "libc/intrin/kprintf.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/sysv/consts/seccomp.h"
|
|
||||||
|
|
||||||
const struct DescribeFlags kSeccompOperationFlags[] = {
|
void __strace_iov(const struct iovec *iov, int iovlen, ssize_t rem) {
|
||||||
{SECCOMP_GET_NOTIF_SIZES, "GET_NOTIF_SIZES"}, // order matters
|
int i;
|
||||||
{SECCOMP_GET_ACTION_AVAIL, "GET_ACTION_AVAIL"}, //
|
kprintf("{");
|
||||||
{SECCOMP_SET_MODE_FILTER, "SET_MODE_FILTER"}, //
|
for (i = 0; rem && i < MIN(5, iovlen); ++i) {
|
||||||
{SECCOMP_SET_MODE_STRICT, "SET_MODE_STRICT"}, //
|
kprintf(
|
||||||
};
|
"%s{%#.*hhs%s, %'zu}", i ? ", " : "",
|
||||||
|
MAX(0, MIN(40, MIN(rem, iov[i].iov_len))), iov[i].iov_base,
|
||||||
const char *DescribeSeccompOperationFlags(int x) {
|
MAX(0, MIN(40, MIN(rem, iov[i].iov_len))) < iov[i].iov_len ? "..." : "",
|
||||||
static char seccompflags[128];
|
iov[i].iov_len);
|
||||||
return DescribeFlags(seccompflags, sizeof(seccompflags),
|
rem -= iov[i].iov_len;
|
||||||
kSeccompOperationFlags, ARRAYLEN(kSeccompOperationFlags),
|
}
|
||||||
"SECCOMP_", x);
|
kprintf("%s}", iovlen > 5 ? "..." : "");
|
||||||
}
|
}
|
1341
libc/calls/struct/bpf.h
Normal file
1341
libc/calls/struct/bpf.h
Normal file
File diff suppressed because it is too large
Load diff
59
libc/calls/struct/filter.h
Normal file
59
libc/calls/struct/filter.h
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_FILTER_H_
|
||||||
|
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_FILTER_H_
|
||||||
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
|
#define BPF_MAJOR_VERSION 1
|
||||||
|
#define BPF_MINOR_VERSION 1
|
||||||
|
|
||||||
|
struct sock_filter {
|
||||||
|
uint16_t code;
|
||||||
|
uint8_t jt;
|
||||||
|
uint8_t jf;
|
||||||
|
uint32_t k;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sock_fprog {
|
||||||
|
unsigned short len;
|
||||||
|
struct sock_filter *filter;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BPF_RVAL(code) ((code)&0x18)
|
||||||
|
#define BPF_A 0x10
|
||||||
|
#define BPF_MISCOP(code) ((code)&0xf8)
|
||||||
|
#define BPF_TAX 0x00
|
||||||
|
#define BPF_TXA 0x80
|
||||||
|
|
||||||
|
#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_MEMWORDS 16
|
||||||
|
|
||||||
|
#define SKF_AD_OFF (-0x1000)
|
||||||
|
#define SKF_AD_PROTOCOL 0
|
||||||
|
#define SKF_AD_PKTTYPE 4
|
||||||
|
#define SKF_AD_IFINDEX 8
|
||||||
|
#define SKF_AD_NLATTR 12
|
||||||
|
#define SKF_AD_NLATTR_NEST 16
|
||||||
|
#define SKF_AD_MARK 20
|
||||||
|
#define SKF_AD_QUEUE 24
|
||||||
|
#define SKF_AD_HATYPE 28
|
||||||
|
#define SKF_AD_RXHASH 32
|
||||||
|
#define SKF_AD_CPU 36
|
||||||
|
#define SKF_AD_ALU_XOR_X 40
|
||||||
|
#define SKF_AD_VLAN_TAG 44
|
||||||
|
#define SKF_AD_VLAN_TAG_PRESENT 48
|
||||||
|
#define SKF_AD_PAY_OFFSET 52
|
||||||
|
#define SKF_AD_RANDOM 56
|
||||||
|
#define SKF_AD_VLAN_TPID 60
|
||||||
|
#define SKF_AD_MAX 64
|
||||||
|
#define SKF_NET_OFF (-0x100000)
|
||||||
|
#define SKF_LL_OFF (-0x200000)
|
||||||
|
#define BPF_NET_OFF SKF_NET_OFF
|
||||||
|
#define BPF_LL_OFF SKF_LL_OFF
|
||||||
|
|
||||||
|
COSMOPOLITAN_C_END_
|
||||||
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
|
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_FILTER_H_ */
|
23
libc/calls/struct/hog.py
Normal file
23
libc/calls/struct/hog.py
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
s="""
|
||||||
|
BPF_SOCK_OPS_VOID,
|
||||||
|
BPF_SOCK_OPS_TIMEOUT_INIT,
|
||||||
|
BPF_SOCK_OPS_RWND_INIT,
|
||||||
|
BPF_SOCK_OPS_TCP_CONNECT_CB,
|
||||||
|
BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB,
|
||||||
|
BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB,
|
||||||
|
BPF_SOCK_OPS_NEEDS_ECN,
|
||||||
|
BPF_SOCK_OPS_BASE_RTT,
|
||||||
|
BPF_SOCK_OPS_RTO_CB,
|
||||||
|
BPF_SOCK_OPS_RETRANS_CB,
|
||||||
|
BPF_SOCK_OPS_STATE_CB,
|
||||||
|
BPF_SOCK_OPS_TCP_LISTEN_CB,
|
||||||
|
BPF_SOCK_OPS_RTT_CB,
|
||||||
|
BPF_SOCK_OPS_PARSE_HDR_OPT_CB,
|
||||||
|
BPF_SOCK_OPS_HDR_OPT_LEN_CB,
|
||||||
|
BPF_SOCK_OPS_WRITE_HDR_OPT_CB,
|
||||||
|
"""
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
for x in s.replace(',','').split():
|
||||||
|
print("#define %s %d" % (x, i))
|
||||||
|
i += 1
|
|
@ -1,8 +1,45 @@
|
||||||
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_SECCOMP_H_
|
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_SECCOMP_H_
|
||||||
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_SECCOMP_H_
|
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_SECCOMP_H_
|
||||||
|
|
||||||
|
#define SECCOMP_SET_MODE_STRICT 0
|
||||||
|
#define SECCOMP_SET_MODE_FILTER 1
|
||||||
|
#define SECCOMP_GET_ACTION_AVAIL 2
|
||||||
|
#define SECCOMP_GET_NOTIF_SIZES 3
|
||||||
|
#define SECCOMP_FILTER_FLAG_TSYNC (1UL << 0)
|
||||||
|
#define SECCOMP_FILTER_FLAG_LOG (1UL << 1)
|
||||||
|
#define SECCOMP_FILTER_FLAG_SPEC_ALLOW (1UL << 2)
|
||||||
|
#define SECCOMP_FILTER_FLAG_NEW_LISTENER (1UL << 3)
|
||||||
|
#define SECCOMP_FILTER_FLAG_TSYNC_ESRCH (1UL << 4)
|
||||||
|
#define SECCOMP_RET_KILL_PROCESS 0x80000000U
|
||||||
|
#define SECCOMP_RET_KILL_THREAD 0x00000000U
|
||||||
|
#define SECCOMP_RET_KILL SECCOMP_RET_KILL_THREAD
|
||||||
|
#define SECCOMP_RET_TRAP 0x00030000U
|
||||||
|
#define SECCOMP_RET_ERRNO 0x00050000U
|
||||||
|
#define SECCOMP_RET_USER_NOTIF 0x7fc00000U
|
||||||
|
#define SECCOMP_RET_TRACE 0x7ff00000U
|
||||||
|
#define SECCOMP_RET_LOG 0x7ffc0000U
|
||||||
|
#define SECCOMP_RET_ALLOW 0x7fff0000U
|
||||||
|
#define SECCOMP_RET_ACTION_FULL 0xffff0000U
|
||||||
|
#define SECCOMP_RET_ACTION 0x7fff0000U
|
||||||
|
#define SECCOMP_RET_DATA 0x0000ffffU
|
||||||
|
#define SECCOMP_USER_NOTIF_FLAG_CONTINUE (1UL << 0)
|
||||||
|
#define SECCOMP_ADDFD_FLAG_SETFD (1UL << 0)
|
||||||
|
#define SECCOMP_ADDFD_FLAG_SEND (1UL << 1)
|
||||||
|
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
COSMOPOLITAN_C_START_
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
|
#define SECCOMP_IOC_MAGIC '!'
|
||||||
|
#define SECCOMP_IO(nr) _IO(SECCOMP_IOC_MAGIC, nr)
|
||||||
|
#define SECCOMP_IOR(nr, type) _IOR(SECCOMP_IOC_MAGIC, nr, type)
|
||||||
|
#define SECCOMP_IOW(nr, type) _IOW(SECCOMP_IOC_MAGIC, nr, type)
|
||||||
|
#define SECCOMP_IOWR(nr, type) _IOWR(SECCOMP_IOC_MAGIC, nr, type)
|
||||||
|
|
||||||
|
#define SECCOMP_IOCTL_NOTIF_RECV SECCOMP_IOWR(0, struct seccomp_notif)
|
||||||
|
#define SECCOMP_IOCTL_NOTIF_SEND SECCOMP_IOWR(1, struct seccomp_notif_resp)
|
||||||
|
#define SECCOMP_IOCTL_NOTIF_ID_VALID SECCOMP_IOW(2, __u64)
|
||||||
|
#define SECCOMP_IOCTL_NOTIF_ADDFD SECCOMP_IOW(3, struct seccomp_notif_addfd)
|
||||||
|
|
||||||
struct seccomp_data {
|
struct seccomp_data {
|
||||||
int32_t nr;
|
int32_t nr;
|
||||||
uint32_t arch;
|
uint32_t arch;
|
||||||
|
@ -38,17 +75,6 @@ struct seccomp_notif_addfd {
|
||||||
uint32_t newfd_flags;
|
uint32_t newfd_flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SECCOMP_IOC_MAGIC '!'
|
|
||||||
#define SECCOMP_IO(nr) _IO(SECCOMP_IOC_MAGIC, nr)
|
|
||||||
#define SECCOMP_IOR(nr, type) _IOR(SECCOMP_IOC_MAGIC, nr, type)
|
|
||||||
#define SECCOMP_IOW(nr, type) _IOW(SECCOMP_IOC_MAGIC, nr, type)
|
|
||||||
#define SECCOMP_IOWR(nr, type) _IOWR(SECCOMP_IOC_MAGIC, nr, type)
|
|
||||||
|
|
||||||
#define SECCOMP_IOCTL_NOTIF_RECV SECCOMP_IOWR(0, struct seccomp_notif)
|
|
||||||
#define SECCOMP_IOCTL_NOTIF_SEND SECCOMP_IOWR(1, struct seccomp_notif_resp)
|
|
||||||
#define SECCOMP_IOCTL_NOTIF_ID_VALID SECCOMP_IOW(2, __u64)
|
|
||||||
#define SECCOMP_IOCTL_NOTIF_ADDFD SECCOMP_IOW(3, struct seccomp_notif_addfd)
|
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
COSMOPOLITAN_C_END_
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SECCOMP_H_ */
|
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SECCOMP_H_ */
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
*/
|
*/
|
||||||
ssize_t writev(int fd, const struct iovec *iov, int iovlen) {
|
ssize_t writev(int fd, const struct iovec *iov, int iovlen) {
|
||||||
int i;
|
int i;
|
||||||
ssize_t rc, rem;
|
ssize_t rc;
|
||||||
|
|
||||||
if (fd >= 0 && iovlen >= 0) {
|
if (fd >= 0 && iovlen >= 0) {
|
||||||
if (IsAsan() && !__asan_is_valid_iov(iov, iovlen)) {
|
if (IsAsan() && !__asan_is_valid_iov(iov, iovlen)) {
|
||||||
|
@ -77,18 +77,9 @@ ssize_t writev(int fd, const struct iovec *iov, int iovlen) {
|
||||||
if (rc == -1 && errno == EFAULT) {
|
if (rc == -1 && errno == EFAULT) {
|
||||||
STRACE("writev(%d, %p, %d) → %'zd% m", fd, iov, iovlen, rc);
|
STRACE("writev(%d, %p, %d) → %'zd% m", fd, iov, iovlen, rc);
|
||||||
} else {
|
} else {
|
||||||
rem = rc != -1 ? rc : 0;
|
kprintf(STRACE_PROLOGUE "readv(%d, ", fd);
|
||||||
kprintf(STRACE_PROLOGUE "writev(%d, {", fd);
|
__strace_iov(iov, iovlen, rc != -1 ? rc : 0);
|
||||||
for (i = 0; i < MIN(5, iovlen); ++i) {
|
kprintf(", %d) → %'ld% m%n", iovlen, rc);
|
||||||
kprintf("%s{%#.*hhs%s, %'zu}", i ? ", " : "",
|
|
||||||
MAX(0, MIN(40, MIN(rem, iov[i].iov_len))), iov[i].iov_base,
|
|
||||||
MAX(0, MIN(40, MIN(rem, iov[i].iov_len))) < iov[i].iov_len
|
|
||||||
? "..."
|
|
||||||
: "",
|
|
||||||
iov[i].iov_len);
|
|
||||||
rem -= iov[i].iov_len;
|
|
||||||
}
|
|
||||||
kprintf("%s}, %d) → %'ld% m%n", iovlen > 5 ? "..." : "", iovlen, rc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/issandboxed.h"
|
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/log/libfatal.internal.h"
|
#include "libc/log/libfatal.internal.h"
|
||||||
#include "libc/log/log.h"
|
#include "libc/log/log.h"
|
||||||
|
@ -39,7 +38,7 @@ noasan noubsan int IsDebuggerPresent(bool force) {
|
||||||
if (!force && IsGenuineCosmo()) return 0;
|
if (!force && IsGenuineCosmo()) return 0;
|
||||||
if (!force && getenv("HEISENDEBUG")) return 0;
|
if (!force && getenv("HEISENDEBUG")) return 0;
|
||||||
if (IsWindows()) return NtGetPeb()->BeingDebugged; /* needs noasan */
|
if (IsWindows()) return NtGetPeb()->BeingDebugged; /* needs noasan */
|
||||||
if (__issandboxed) return false;
|
if (__isworker) return false;
|
||||||
res = 0;
|
res = 0;
|
||||||
if ((fd = __sysv_open("/proc/self/status", O_RDONLY, 0)) >= 0) {
|
if ((fd = __sysv_open("/proc/self/status", O_RDONLY, 0)) >= 0) {
|
||||||
if ((got = __sysv_read(fd, buf, sizeof(buf) - 1)) > 0) {
|
if ((got = __sysv_read(fd, buf, sizeof(buf) - 1)) > 0) {
|
||||||
|
|
|
@ -18,5 +18,11 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
|
|
||||||
// SECCOMP_SET_MODE_STRICT
|
/**
|
||||||
bool __issandboxed;
|
* Indicates if current execution context is a worker task.
|
||||||
|
*
|
||||||
|
* Setting this to true on things like the forked process of a web
|
||||||
|
* server is a good idea since it'll ask the C runtime to not pull
|
||||||
|
* magical stunts like attaching GDB to the process on crash.
|
||||||
|
*/
|
||||||
|
bool __isworker;
|
|
@ -246,7 +246,7 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt, va_list va,
|
||||||
const char *s, *f;
|
const char *s, *f;
|
||||||
unsigned long long x;
|
unsigned long long x;
|
||||||
unsigned i, j, m, rem, sign, hash, cols, prec;
|
unsigned i, j, m, rem, sign, hash, cols, prec;
|
||||||
char c, *p, *e, pdot, zero, flip, dang, base, quot, z[128];
|
char c, *p, *e, pdot, zero, flip, dang, base, quot, uppr, z[128];
|
||||||
if (kistextpointer(b) || kisdangerous(b)) n = 0;
|
if (kistextpointer(b) || kisdangerous(b)) n = 0;
|
||||||
if (!kistextpointer(fmt)) fmt = "!!WONTFMT";
|
if (!kistextpointer(fmt)) fmt = "!!WONTFMT";
|
||||||
p = b;
|
p = b;
|
||||||
|
@ -270,6 +270,7 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt, va_list va,
|
||||||
type = 0;
|
type = 0;
|
||||||
cols = 0;
|
cols = 0;
|
||||||
zero = 0;
|
zero = 0;
|
||||||
|
uppr = 0;
|
||||||
abet = "0123456789abcdef";
|
abet = "0123456789abcdef";
|
||||||
for (;;) {
|
for (;;) {
|
||||||
switch ((c = *f++)) {
|
switch ((c = *f++)) {
|
||||||
|
@ -302,6 +303,10 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt, va_list va,
|
||||||
sign = c;
|
sign = c;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
case '^':
|
||||||
|
uppr = c;
|
||||||
|
continue;
|
||||||
|
|
||||||
case 'h':
|
case 'h':
|
||||||
--type;
|
--type;
|
||||||
continue;
|
continue;
|
||||||
|
@ -507,6 +512,12 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt, va_list va,
|
||||||
type = 0;
|
type = 0;
|
||||||
goto FormatString;
|
goto FormatString;
|
||||||
} else {
|
} else {
|
||||||
|
if (p + 4 <= e) {
|
||||||
|
*p++ = 'e';
|
||||||
|
*p++ = 'r';
|
||||||
|
*p++ = 'r';
|
||||||
|
*p++ = '=';
|
||||||
|
}
|
||||||
type = 0;
|
type = 0;
|
||||||
x = unixerr;
|
x = unixerr;
|
||||||
goto FormatDecimal;
|
goto FormatDecimal;
|
||||||
|
@ -558,10 +569,6 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt, va_list va,
|
||||||
goto FormatString;
|
goto FormatString;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'S':
|
|
||||||
c = 's';
|
|
||||||
type = 1;
|
|
||||||
// fallthrough
|
|
||||||
case 's':
|
case 's':
|
||||||
if (!(s = va_arg(va, const void *))) {
|
if (!(s = va_arg(va, const void *))) {
|
||||||
s = sign != ' ' ? "NULL" : "";
|
s = sign != ' ' ? "NULL" : "";
|
||||||
|
@ -598,6 +605,9 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt, va_list va,
|
||||||
if ((t & 0300) == 0200) goto ActuallyEmitByte;
|
if ((t & 0300) == 0200) goto ActuallyEmitByte;
|
||||||
++i;
|
++i;
|
||||||
EmitByte:
|
EmitByte:
|
||||||
|
if (uppr && 'a' <= t && t <= 'z') {
|
||||||
|
t -= 'a' - 'A';
|
||||||
|
}
|
||||||
if (UNLIKELY(quot) && (t == '\\' || ((t == '"' && c == 's') ||
|
if (UNLIKELY(quot) && (t == '\\' || ((t == '"' && c == 's') ||
|
||||||
(t == '\'' && c == 'c')))) {
|
(t == '\'' && c == 'c')))) {
|
||||||
if (p + 2 <= e) {
|
if (p + 2 <= e) {
|
||||||
|
@ -671,9 +681,15 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt, va_list va,
|
||||||
if (!t) break;
|
if (!t) break;
|
||||||
++i;
|
++i;
|
||||||
EmitChar:
|
EmitChar:
|
||||||
if (t <= 0x7f) {
|
if (t <= 0x7f) goto EmitByte;
|
||||||
goto EmitByte;
|
if (uppr) {
|
||||||
} else if (t <= 0x7ff) {
|
if (weaken(towupper)) {
|
||||||
|
t = weaken(towupper)(t);
|
||||||
|
} else if (uppr && 'a' <= t && t <= 'z') {
|
||||||
|
t -= 'a' - 'A';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (t <= 0x7ff) {
|
||||||
if (p + 2 <= e) {
|
if (p + 2 <= e) {
|
||||||
p[0] = 0300 | (t >> 6);
|
p[0] = 0300 | (t >> 6);
|
||||||
p[1] = 0200 | (t & 077);
|
p[1] = 0200 | (t & 077);
|
||||||
|
@ -886,6 +902,7 @@ privileged void kvprintf(const char *fmt, va_list v) {
|
||||||
* - `+` plus leftpad if positive (aligns w/ negatives)
|
* - `+` plus leftpad if positive (aligns w/ negatives)
|
||||||
* - ` ` space leftpad if positive (aligns w/ negatives)
|
* - ` ` space leftpad if positive (aligns w/ negatives)
|
||||||
* - `#` represent value with literal syntax, e.g. 0x, 0b, quotes
|
* - `#` represent value with literal syntax, e.g. 0x, 0b, quotes
|
||||||
|
* - `^` uppercasing w/ towupper() if linked, otherwise toupper()
|
||||||
*
|
*
|
||||||
* Error numbers:
|
* Error numbers:
|
||||||
*
|
*
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include "libc/bits/safemacros.internal.h"
|
#include "libc/bits/safemacros.internal.h"
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/issandboxed.h"
|
|
||||||
#include "libc/calls/sigbits.h"
|
#include "libc/calls/sigbits.h"
|
||||||
#include "libc/calls/strace.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
@ -160,7 +159,7 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int PrintBacktrace(int fd, const struct StackFrame *bp) {
|
static int PrintBacktrace(int fd, const struct StackFrame *bp) {
|
||||||
if (!IsTiny() && !__issandboxed) {
|
if (!IsTiny() && !__isworker) {
|
||||||
if (PrintBacktraceUsingAddr2line(fd, bp) != -1) {
|
if (PrintBacktraceUsingAddr2line(fd, bp) != -1) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "libc/calls/strace.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/fmt/fmt.h"
|
#include "libc/fmt/fmt.h"
|
||||||
|
#include "libc/intrin/kprintf.h"
|
||||||
#include "libc/log/check.h"
|
#include "libc/log/check.h"
|
||||||
#include "libc/log/color.internal.h"
|
#include "libc/log/color.internal.h"
|
||||||
#include "libc/log/internal.h"
|
#include "libc/log/internal.h"
|
||||||
|
@ -28,6 +29,9 @@
|
||||||
#include "libc/log/log.h"
|
#include "libc/log/log.h"
|
||||||
#include "libc/runtime/memtrack.internal.h"
|
#include "libc/runtime/memtrack.internal.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
#include "libc/stdio/stdio.h"
|
||||||
|
|
||||||
|
STATIC_YOINK("strerror_wr");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles failure of CHECK_xx() macros.
|
* Handles failure of CHECK_xx() macros.
|
||||||
|
@ -44,59 +48,26 @@ relegated void __check_fail(const char *suffix, const char *opstr,
|
||||||
__strace = 0;
|
__strace = 0;
|
||||||
g_ftrace = 0;
|
g_ftrace = 0;
|
||||||
e = errno;
|
e = errno;
|
||||||
p = __fatalbuf;
|
|
||||||
__start_fatal(file, line);
|
__start_fatal(file, line);
|
||||||
__stpcpy(hostname, "unknown");
|
__stpcpy(hostname, "unknown");
|
||||||
gethostname(hostname, sizeof(hostname));
|
gethostname(hostname, sizeof(hostname));
|
||||||
p = __stpcpy(p, "check failed on ");
|
kprintf("check failed on %s pid %d%n", hostname, getpid());
|
||||||
p = __stpcpy(p, hostname);
|
kprintf("\tCHECK_%^s(%s, %s);%n", suffix, wantstr, gotstr);
|
||||||
p = __stpcpy(p, " pid ");
|
kprintf("\t\t → %p (%s)%n", want, wantstr);
|
||||||
p = __intcpy(p, __getpid());
|
kprintf("\t\t%s %p (%s)%n", opstr, got, gotstr);
|
||||||
p = __stpcpy(p, "\n");
|
|
||||||
p = __stpcpy(p, "\tCHECK_");
|
|
||||||
for (; *suffix; ++suffix) {
|
|
||||||
*p++ = *suffix - ('a' <= *suffix && *suffix <= 'z') * 32;
|
|
||||||
}
|
|
||||||
p = __stpcpy(p, "(");
|
|
||||||
p = __stpcpy(p, wantstr);
|
|
||||||
p = __stpcpy(p, ", ");
|
|
||||||
p = __stpcpy(p, gotstr);
|
|
||||||
p = __stpcpy(p, ");\n\t\t → 0x");
|
|
||||||
p = __hexcpy(p, want);
|
|
||||||
p = __stpcpy(p, " (");
|
|
||||||
p = __stpcpy(p, wantstr);
|
|
||||||
p = __stpcpy(p, ")\n\t\t");
|
|
||||||
p = __stpcpy(p, opstr);
|
|
||||||
p = __stpcpy(p, " 0x");
|
|
||||||
p = __hexcpy(p, got);
|
|
||||||
p = __stpcpy(p, " (");
|
|
||||||
p = __stpcpy(p, gotstr);
|
|
||||||
p = __stpcpy(p, ")\n");
|
|
||||||
if (!isempty(fmt)) {
|
if (!isempty(fmt)) {
|
||||||
*p++ = '\t';
|
kprintf("\t");
|
||||||
va_start(va, fmt);
|
va_start(va, fmt);
|
||||||
p += (vsprintf)(p, fmt, va);
|
kvprintf(fmt, va);
|
||||||
va_end(va);
|
va_end(va);
|
||||||
*p++ = '\n';
|
kprintf("%n");
|
||||||
}
|
}
|
||||||
p = __stpcpy(p, "\t");
|
kprintf("\t%m%n\t%s%s", SUBTLE, program_invocation_name);
|
||||||
p = __stpcpy(p, strerror(e));
|
|
||||||
p = __stpcpy(p, "\n\t");
|
|
||||||
p = __stpcpy(p, SUBTLE);
|
|
||||||
p = __stpcpy(p, program_invocation_name);
|
|
||||||
if (__argc > 1) p = __stpcpy(p, " \\");
|
|
||||||
p = __stpcpy(p, RESET);
|
|
||||||
p = __stpcpy(p, "\n");
|
|
||||||
__write(__fatalbuf, p - __fatalbuf);
|
|
||||||
for (i = 1; i < __argc; ++i) {
|
for (i = 1; i < __argc; ++i) {
|
||||||
p = __fatalbuf;
|
kprintf(" %s", __argv[i]);
|
||||||
p = __stpcpy(p, "\t\t");
|
|
||||||
p = __stpcpy(p, __argv[i]);
|
|
||||||
if (i < __argc - 1) p = __stpcpy(p, " \\");
|
|
||||||
p = __stpcpy(p, "\n");
|
|
||||||
}
|
}
|
||||||
|
kprintf("%s%n", RESET);
|
||||||
if (!IsTiny() && e == ENOMEM) {
|
if (!IsTiny() && e == ENOMEM) {
|
||||||
__write("\n", 1);
|
|
||||||
PrintMemoryIntervals(2, &_mmi);
|
PrintMemoryIntervals(2, &_mmi);
|
||||||
}
|
}
|
||||||
__die();
|
__die();
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/issandboxed.h"
|
|
||||||
#include "libc/calls/sigbits.h"
|
#include "libc/calls/sigbits.h"
|
||||||
#include "libc/calls/strace.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/sigaction.h"
|
#include "libc/calls/struct/sigaction.h"
|
||||||
|
@ -200,10 +199,8 @@ relegated void ShowCrashReport(int err, int sig, struct siginfo *si,
|
||||||
names.version[0] = 0;
|
names.version[0] = 0;
|
||||||
names.nodename[0] = 0;
|
names.nodename[0] = 0;
|
||||||
__stpcpy(host, "unknown");
|
__stpcpy(host, "unknown");
|
||||||
if (!__issandboxed) {
|
gethostname(host, sizeof(host));
|
||||||
gethostname(host, sizeof(host));
|
uname(&names);
|
||||||
uname(&names);
|
|
||||||
}
|
|
||||||
p = buf;
|
p = buf;
|
||||||
errno = err;
|
errno = err;
|
||||||
kprintf("%n%serror%s: Uncaught %G (%s) on %s pid %d%n"
|
kprintf("%n%serror%s: Uncaught %G (%s) on %s pid %d%n"
|
||||||
|
@ -292,8 +289,7 @@ relegated noinstrument void __oncrash(int sig, struct siginfo *si,
|
||||||
DebugBreak();
|
DebugBreak();
|
||||||
} else if (__nocolor || g_isrunningundermake) {
|
} else if (__nocolor || g_isrunningundermake) {
|
||||||
gdbpid = -1;
|
gdbpid = -1;
|
||||||
} else if (!IsTiny() && IsLinux() && FindDebugBinary() &&
|
} else if (!IsTiny() && IsLinux() && FindDebugBinary() && !__isworker) {
|
||||||
!__issandboxed) {
|
|
||||||
RestoreDefaultCrashSignalHandlers();
|
RestoreDefaultCrashSignalHandlers();
|
||||||
gdbpid = AttachDebugger(
|
gdbpid = AttachDebugger(
|
||||||
((sig == SIGTRAP || sig == SIGQUIT) &&
|
((sig == SIGTRAP || sig == SIGQUIT) &&
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/issandboxed.h"
|
|
||||||
#include "libc/calls/struct/termios.h"
|
#include "libc/calls/struct/termios.h"
|
||||||
#include "libc/calls/termios.h"
|
#include "libc/calls/termios.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
|
@ -52,7 +51,7 @@ const void *const g_oldtermios_ctor[] initarray = {
|
||||||
|
|
||||||
void __restore_tty(int fd) {
|
void __restore_tty(int fd) {
|
||||||
int e;
|
int e;
|
||||||
if (!__issandboxed) {
|
if (!__isworker) {
|
||||||
e = errno;
|
e = errno;
|
||||||
if (g_oldtermios.c_lflag && !__nocolor && isatty(fd)) {
|
if (g_oldtermios.c_lflag && !__nocolor && isatty(fd)) {
|
||||||
write(fd, ANSI_RESTORE, strlen(ANSI_RESTORE));
|
write(fd, ANSI_RESTORE, strlen(ANSI_RESTORE));
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
*/
|
*/
|
||||||
relegated void __start_fatal(const char *file, int line) {
|
relegated void __start_fatal(const char *file, int line) {
|
||||||
__restore_tty(1);
|
__restore_tty(1);
|
||||||
kprintf("\r%serror%s:%s:%d:%s%s: ", !__nocolor ? "\e[J\e[30;101m" : "",
|
kprintf("%r%serror%s:%s:%d:%s%s: ", !__nocolor ? "\e[J\e[30;101m" : "",
|
||||||
!__nocolor ? "\e[94;49m" : "", file, line,
|
!__nocolor ? "\e[94;49m" : "", file, line,
|
||||||
program_invocation_short_name, !__nocolor ? "\e[0m" : "");
|
program_invocation_short_name, !__nocolor ? "\e[0m" : "");
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include "libc/assert.h"
|
#include "libc/assert.h"
|
||||||
#include "libc/bits/bits.h"
|
#include "libc/bits/bits.h"
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/issandboxed.h"
|
|
||||||
#include "libc/calls/strace.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
@ -118,7 +117,7 @@ static struct SymbolTable *GetSymbolTableFromElf(void) {
|
||||||
struct SymbolTable *GetSymbolTable(void) {
|
struct SymbolTable *GetSymbolTable(void) {
|
||||||
int ft, st;
|
int ft, st;
|
||||||
struct Zipos *z;
|
struct Zipos *z;
|
||||||
if (!g_symtab && !__issandboxed) {
|
if (!g_symtab && !__isworker) {
|
||||||
ft = g_ftrace, g_ftrace = 0;
|
ft = g_ftrace, g_ftrace = 0;
|
||||||
st = __strace, __strace = 0;
|
st = __strace, __strace = 0;
|
||||||
if (weaken(__zipos_get) && (z = weaken(__zipos_get)())) {
|
if (weaken(__zipos_get) && (z = weaken(__zipos_get)())) {
|
||||||
|
|
|
@ -228,8 +228,12 @@ static textwindows dontinline noasan void *MapMemories(char *addr, size_t size,
|
||||||
*/
|
*/
|
||||||
noasan void *mmap(void *addr, size_t size, int prot, int flags, int fd,
|
noasan void *mmap(void *addr, size_t size, int prot, int flags, int fd,
|
||||||
int64_t off) {
|
int64_t off) {
|
||||||
STRACE("mmap(%p, %'zu, %s, %s, %d, %'ld) → ...", addr, size,
|
#if defined(SYSDEBUG) && (_KERNTRACE || _NTTRACE)
|
||||||
DescribeProtFlags(prot), DescribeMapFlags(flags), fd, off);
|
if (IsWindows()) {
|
||||||
|
STRACE("mmap(%p, %'zu, %s, %s, %d, %'ld) → ...", addr, size,
|
||||||
|
DescribeProtFlags(prot), DescribeMapFlags(flags), fd, off);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
void *res;
|
void *res;
|
||||||
char *p = addr;
|
char *p = addr;
|
||||||
struct DirectMap dm;
|
struct DirectMap dm;
|
||||||
|
|
|
@ -39,6 +39,7 @@ extern uint8_t __zip_start[]; /* αpε */
|
||||||
extern uint8_t __zip_end[]; /* αpε */
|
extern uint8_t __zip_end[]; /* αpε */
|
||||||
extern bool ftrace_enabled;
|
extern bool ftrace_enabled;
|
||||||
extern size_t __virtualmax;
|
extern size_t __virtualmax;
|
||||||
|
extern bool __isworker;
|
||||||
|
|
||||||
void mcount(void);
|
void mcount(void);
|
||||||
unsigned long getauxval(unsigned long);
|
unsigned long getauxval(unsigned long);
|
||||||
|
|
31
libc/sock/asanmsghdr.c
Normal file
31
libc/sock/asanmsghdr.c
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/*-*- 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/intrin/asan.internal.h"
|
||||||
|
#include "libc/sock/sock.h"
|
||||||
|
|
||||||
|
bool __asan_is_valid_msghdr(const struct msghdr *msg) {
|
||||||
|
if (!__asan_is_valid(msg, sizeof(struct msghdr))) return false;
|
||||||
|
if (msg->msg_name) {
|
||||||
|
if (!__asan_is_valid(msg->msg_name, msg->msg_namelen)) return false;
|
||||||
|
}
|
||||||
|
if (msg->msg_control) {
|
||||||
|
if (!__asan_is_valid(msg->msg_control, msg->msg_controllen)) return false;
|
||||||
|
}
|
||||||
|
return __asan_is_valid_iov(msg->msg_iov, msg->msg_iovlen);
|
||||||
|
}
|
|
@ -132,6 +132,7 @@ int sys_select_nt(int, fd_set *, fd_set *, fd_set *, struct timeval *) hidden;
|
||||||
int sys_shutdown_nt(struct Fd *, int) hidden;
|
int sys_shutdown_nt(struct Fd *, int) hidden;
|
||||||
int sys_setsockopt_nt(struct Fd *, int, int, const void *, uint32_t) hidden;
|
int sys_setsockopt_nt(struct Fd *, int, int, const void *, uint32_t) hidden;
|
||||||
|
|
||||||
|
bool __asan_is_valid_msghdr(const struct msghdr *);
|
||||||
ssize_t sys_send_nt(int, const struct iovec *, size_t, uint32_t) hidden;
|
ssize_t sys_send_nt(int, const struct iovec *, size_t, uint32_t) hidden;
|
||||||
ssize_t sys_recv_nt(struct Fd *, const struct iovec *, size_t, uint32_t) hidden;
|
ssize_t sys_recv_nt(struct Fd *, const struct iovec *, size_t, uint32_t) hidden;
|
||||||
size_t __iovec2nt(struct NtIovec[hasatleast 16], const struct iovec *,
|
size_t __iovec2nt(struct NtIovec[hasatleast 16], const struct iovec *,
|
||||||
|
|
|
@ -39,34 +39,58 @@
|
||||||
* @restartable (unless SO_RCVTIMEO)
|
* @restartable (unless SO_RCVTIMEO)
|
||||||
*/
|
*/
|
||||||
ssize_t recvmsg(int fd, struct msghdr *msg, int flags) {
|
ssize_t recvmsg(int fd, struct msghdr *msg, int flags) {
|
||||||
ssize_t got;
|
ssize_t rc, got;
|
||||||
if (!IsWindows()) {
|
if (IsAsan() && !__asan_is_valid_msghdr(msg)) {
|
||||||
|
rc = efault();
|
||||||
|
} else if (!IsWindows()) {
|
||||||
got = sys_recvmsg(fd, msg, flags);
|
got = sys_recvmsg(fd, msg, flags);
|
||||||
/* An address was provided, convert from BSD form */
|
// An address was provided, convert from BSD form
|
||||||
if (msg->msg_name && IsBsd() && got != -1) {
|
if (msg->msg_name && IsBsd() && got != -1) {
|
||||||
sockaddr2linux(msg->msg_name);
|
sockaddr2linux(msg->msg_name);
|
||||||
}
|
}
|
||||||
return got;
|
rc = got;
|
||||||
} else {
|
} else if (__isfdopen(fd)) {
|
||||||
if (__isfdopen(fd)) {
|
if (!msg->msg_control) {
|
||||||
if (msg->msg_control) return einval(); /* control msg not supported */
|
|
||||||
if (__isfdkind(fd, kFdSocket)) {
|
if (__isfdkind(fd, kFdSocket)) {
|
||||||
return sys_recvfrom_nt(&g_fds.p[fd], msg->msg_iov, msg->msg_iovlen,
|
rc = sys_recvfrom_nt(&g_fds.p[fd], msg->msg_iov, msg->msg_iovlen, flags,
|
||||||
flags, msg->msg_name, &msg->msg_namelen);
|
msg->msg_name, &msg->msg_namelen);
|
||||||
} else if (__isfdkind(fd, kFdFile) && !msg->msg_name) { /* socketpair */
|
} else if (__isfdkind(fd, kFdFile) && !msg->msg_name) { /* socketpair */
|
||||||
if (flags) return einval();
|
if (!flags) {
|
||||||
if ((got = sys_read_nt(&g_fds.p[fd], msg->msg_iov, msg->msg_iovlen,
|
if ((got = sys_read_nt(&g_fds.p[fd], msg->msg_iov, msg->msg_iovlen,
|
||||||
-1)) != -1) {
|
-1)) != -1) {
|
||||||
msg->msg_flags = 0;
|
msg->msg_flags = 0;
|
||||||
return got;
|
rc = got;
|
||||||
|
} else {
|
||||||
|
rc = -1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
rc = einval(); // flags not supported on nt
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return enotsock();
|
rc = enotsock();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return ebadf();
|
rc = einval(); // control msg not supported on nt
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rc = ebadf();
|
||||||
|
}
|
||||||
|
#if defined(SYSDEBUG) && _DATATRACE
|
||||||
|
if (__strace > 0) {
|
||||||
|
if (!msg || (rc == -1 && errno == EFAULT)) {
|
||||||
|
DATATRACE("recvmsg(%d, %p, %#x) → %'ld% m", fd, msg, flags, rc);
|
||||||
|
} else {
|
||||||
|
kprintf(STRACE_PROLOGUE "recvmsg(%d, [{");
|
||||||
|
if (msg->msg_namelen)
|
||||||
|
kprintf(".name=%#.*hhs, ", msg->msg_namelen, msg->msg_name);
|
||||||
|
if (msg->msg_controllen)
|
||||||
|
kprintf(".control=%#.*hhs, ", msg->msg_controllen, msg->msg_control);
|
||||||
|
if (msg->msg_flags) kprintf(".flags=%#x, ", msg->msg_flags);
|
||||||
|
kprintf(".iov=", fd);
|
||||||
|
__strace_iov(msg->msg_iov, msg->msg_iovlen, rc != -1 ? rc : 0);
|
||||||
|
kprintf("}], %#x) → %'ld% m%n", flags, rc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,11 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/assert.h"
|
#include "libc/assert.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/iovec.h"
|
#include "libc/calls/struct/iovec.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
#include "libc/intrin/asan.internal.h"
|
||||||
|
#include "libc/intrin/kprintf.h"
|
||||||
#include "libc/sock/internal.h"
|
#include "libc/sock/internal.h"
|
||||||
#include "libc/sock/sock.h"
|
#include "libc/sock/sock.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
|
@ -39,35 +42,57 @@
|
||||||
* @restartable (unless SO_RCVTIMEO)
|
* @restartable (unless SO_RCVTIMEO)
|
||||||
*/
|
*/
|
||||||
ssize_t sendmsg(int fd, const struct msghdr *msg, int flags) {
|
ssize_t sendmsg(int fd, const struct msghdr *msg, int flags) {
|
||||||
if (!IsWindows()) {
|
int64_t rc;
|
||||||
|
char addr2[128];
|
||||||
|
struct msghdr msg2;
|
||||||
|
if (IsAsan() && !__asan_is_valid_msghdr(msg)) {
|
||||||
|
rc = efault();
|
||||||
|
} else if (!IsWindows()) {
|
||||||
if (IsBsd() && msg->msg_name) {
|
if (IsBsd() && msg->msg_name) {
|
||||||
/* An optional address is provided, convert it to the BSD form */
|
/* An optional address is provided, convert it to the BSD form */
|
||||||
char addr2[128];
|
if (msg->msg_namelen <= sizeof(addr2)) {
|
||||||
struct msghdr msg2;
|
memcpy(&addr2[0], msg->msg_name, msg->msg_namelen);
|
||||||
if (msg->msg_namelen > sizeof(addr2)) return einval();
|
sockaddr2bsd(&addr2[0]);
|
||||||
memcpy(&addr2[0], msg->msg_name, msg->msg_namelen);
|
/* Copy all of msg (except for msg_name) into the new ephemeral local */
|
||||||
sockaddr2bsd(&addr2[0]);
|
memcpy(&msg2, msg, sizeof(msg2));
|
||||||
|
msg2.msg_name = &addr2[0];
|
||||||
/* Copy all of msg (except for msg_name) into the new ephemeral local */
|
rc = sys_sendmsg(fd, &msg2, flags);
|
||||||
memcpy(&msg2, msg, sizeof(msg2));
|
} else {
|
||||||
msg2.msg_name = &addr2[0];
|
rc = einval();
|
||||||
return sys_sendmsg(fd, &msg2, flags);
|
}
|
||||||
}
|
}
|
||||||
/* else do the syscall */
|
/* else do the syscall */
|
||||||
return sys_sendmsg(fd, msg, flags);
|
rc = sys_sendmsg(fd, msg, flags);
|
||||||
} else {
|
} else if (__isfdopen(fd)) {
|
||||||
if (__isfdopen(fd)) {
|
if (msg->msg_control) {
|
||||||
if (msg->msg_control) return einval(); /* control msg not supported */
|
rc = einval(); /* control msg not supported */
|
||||||
if (__isfdkind(fd, kFdSocket)) {
|
} else if (__isfdkind(fd, kFdSocket)) {
|
||||||
return sys_sendto_nt(fd, msg->msg_iov, msg->msg_iovlen, flags,
|
rc = sys_sendto_nt(fd, msg->msg_iov, msg->msg_iovlen, flags,
|
||||||
msg->msg_name, msg->msg_namelen);
|
msg->msg_name, msg->msg_namelen);
|
||||||
} else if (__isfdkind(fd, kFdFile)) {
|
} else if (__isfdkind(fd, kFdFile)) {
|
||||||
return sys_write_nt(fd, msg->msg_iov, msg->msg_iovlen, -1);
|
rc = sys_write_nt(fd, msg->msg_iov, msg->msg_iovlen, -1);
|
||||||
} else {
|
|
||||||
return enotsock();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return ebadf();
|
rc = enotsock();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rc = ebadf();
|
||||||
|
}
|
||||||
|
#if defined(SYSDEBUG) && _DATATRACE
|
||||||
|
if (__strace > 0) {
|
||||||
|
if (!msg || (rc == -1 && errno == EFAULT)) {
|
||||||
|
DATATRACE("sendmsg(%d, %p, %#x) → %'ld% m", fd, msg, flags, rc);
|
||||||
|
} else {
|
||||||
|
kprintf(STRACE_PROLOGUE "sendmsg(%d, {");
|
||||||
|
if (msg->msg_namelen)
|
||||||
|
kprintf(".name=%#.*hhs, ", msg->msg_namelen, msg->msg_name);
|
||||||
|
if (msg->msg_controllen)
|
||||||
|
kprintf(".control=%#.*hhs, ", msg->msg_controllen, msg->msg_control);
|
||||||
|
if (msg->msg_flags) kprintf(".flags=%#x, ", msg->msg_flags);
|
||||||
|
kprintf(".iov=", fd);
|
||||||
|
__strace_iov(msg->msg_iov, msg->msg_iovlen, rc != -1 ? rc : 0);
|
||||||
|
kprintf("}, %#x) → %'ld% m%n", flags, rc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,12 @@ static int log_mask;
|
||||||
static uint16_t log_id; /* Used for Windows EvtID */
|
static uint16_t log_id; /* Used for Windows EvtID */
|
||||||
static int64_t log_fd = -1;
|
static int64_t log_fd = -1;
|
||||||
|
|
||||||
static const struct sockaddr_un log_addr = {AF_UNIX, "/dev/log"};
|
static const char *const kLogPaths[] = {
|
||||||
|
"/dev/log",
|
||||||
|
// "/var/run/log", // TODO: Help with XNU and FreeBSD.
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct sockaddr_un log_addr = {AF_UNIX, "/dev/log"};
|
||||||
|
|
||||||
static int64_t Time(int64_t *tp) {
|
static int64_t Time(int64_t *tp) {
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
|
@ -73,16 +78,20 @@ forceinline int is_lost_conn(int e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __openlog() {
|
static void __openlog() {
|
||||||
|
int i;
|
||||||
if (IsWindows()) {
|
if (IsWindows()) {
|
||||||
log_fd = RegisterEventSource(NULL, log_ident);
|
log_fd = RegisterEventSource(NULL, log_ident);
|
||||||
} else {
|
} else {
|
||||||
log_fd = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
|
log_fd = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
|
||||||
if (log_fd >= 0) {
|
if (log_fd >= 0) {
|
||||||
int rc = connect(log_fd, (void *)&log_addr, sizeof(log_addr));
|
for (i = 0; i < ARRAYLEN(kLogPaths); ++i) {
|
||||||
if (rc < 0) {
|
strcpy(log_addr.sun_path, kLogPaths[i]);
|
||||||
printf("ERR: connect(openlog) failed: %s (errno=%d)\n", strerror(errno),
|
if (!connect(log_fd, (void *)&log_addr, sizeof(log_addr))) {
|
||||||
errno);
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
printf("ERR: connect(openlog) failed: %s (errno=%d)\n", strerror(errno),
|
||||||
|
errno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
#ifndef COSMOPOLITAN_LIBC_SOCK_SYSLOG_H_
|
#ifndef COSMOPOLITAN_LIBC_SOCK_SYSLOG_H_
|
||||||
#define COSMOPOLITAN_LIBC_SOCK_SYSLOG_H_
|
#define COSMOPOLITAN_LIBC_SOCK_SYSLOG_H_
|
||||||
|
|
||||||
|
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
COSMOPOLITAN_C_START_
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
#define LOG_PRI(p) ((p) & LOG_PRIMASK)
|
#define LOG_PRI(p) (LOG_PRIMASK & (p))
|
||||||
|
|
||||||
int setlogmask(int);
|
int setlogmask(int);
|
||||||
void openlog(const char *, int, int);
|
void openlog(const char *, int, int);
|
||||||
|
|
|
@ -3308,42 +3308,4 @@ syscon misc ETH_P_RARP 0x8035 0 0 0 0 0
|
||||||
syscon misc ETH_P_SCA 0x6007 0 0 0 0 0
|
syscon misc ETH_P_SCA 0x6007 0 0 0 0 0
|
||||||
syscon misc ETH_P_WAN_PPP 7 0 0 0 0 0
|
syscon misc ETH_P_WAN_PPP 7 0 0 0 0 0
|
||||||
|
|
||||||
syscon log LOG_EMERG 0 0 0 0 0 0 # consensus
|
|
||||||
syscon log LOG_KERN 0 0 0 0 0 0 # consensus
|
|
||||||
syscon log LOG_ALERT 1 1 1 1 1 1 # unix consensus
|
|
||||||
syscon log LOG_PID 1 1 1 1 1 1 # unix consensus
|
|
||||||
syscon log LOG_CONS 2 2 2 2 2 2 # unix consensus
|
|
||||||
syscon log LOG_CRIT 2 2 2 2 2 2 # unix consensus
|
|
||||||
syscon log LOG_ERR 3 3 3 3 3 3 # unix consensus
|
|
||||||
syscon log LOG_ODELAY 4 4 4 4 4 4 # unix consensus
|
|
||||||
syscon log LOG_WARNING 4 4 4 4 4 4 # unix consensus
|
|
||||||
syscon log LOG_NOTICE 5 5 5 5 5 5 # unix consensus
|
|
||||||
syscon log LOG_INFO 6 6 6 6 6 6 # unix consensus
|
|
||||||
syscon log LOG_DEBUG 7 7 7 7 7 7 # unix consensus
|
|
||||||
syscon log LOG_PRIMASK 7 7 7 7 7 7 # unix consensus
|
|
||||||
syscon log LOG_NDELAY 8 8 8 8 8 8 # unix consensus
|
|
||||||
syscon log LOG_USER 8 8 8 8 8 8 # unix consensus
|
|
||||||
syscon log LOG_MAIL 0x10 0x10 0x10 0x10 0x10 0x10 # unix consensus
|
|
||||||
syscon log LOG_NOWAIT 0x10 0x10 0x10 0x10 0x10 0x10 # unix consensus
|
|
||||||
syscon log LOG_DAEMON 24 24 24 24 24 24 # unix consensus
|
|
||||||
syscon log LOG_NFACILITIES 24 25 24 24 24 24
|
|
||||||
syscon log LOG_AUTH 0x20 0x20 0x20 0x20 0x20 0x20 # unix consensus
|
|
||||||
syscon log LOG_PERROR 0x20 0x20 0x20 0x20 0x20 0x20 # unix consensus
|
|
||||||
syscon log LOG_SYSLOG 40 40 40 40 40 40 # unix consensus
|
|
||||||
syscon log LOG_LPR 48 48 48 48 48 48 # unix consensus
|
|
||||||
syscon log LOG_NEWS 56 56 56 56 56 56 # unix consensus
|
|
||||||
syscon log LOG_UUCP 0x40 0x40 0x40 0x40 0x40 40 # unix consensus
|
|
||||||
syscon log LOG_CRON 72 72 72 72 72 72 # unix consensus
|
|
||||||
syscon log LOG_SELECT 76 0 0 0 0 0
|
|
||||||
syscon log LOG_SENSE 77 0 0 0 0 0
|
|
||||||
syscon log LOG_LOCAL0 0x80 0x80 0x80 0x80 0x80 0x80 # unix consensus
|
|
||||||
syscon log LOG_LOCAL1 136 136 136 136 136 136 # unix consensus
|
|
||||||
syscon log LOG_LOCAL2 144 144 144 144 144 144 # unix consensus
|
|
||||||
syscon log LOG_LOCAL3 152 152 152 152 152 152 # unix consensus
|
|
||||||
syscon log LOG_LOCAL4 160 160 160 160 160 160 # unix consensus
|
|
||||||
syscon log LOG_LOCAL5 168 168 168 168 168 168 # unix consensus
|
|
||||||
syscon log LOG_LOCAL6 176 176 176 176 176 176 # unix consensus
|
|
||||||
syscon log LOG_LOCAL7 184 184 184 184 184 184 # unix consensus
|
|
||||||
syscon log LOG_FACMASK 0x03f8 0x03f8 0x03f8 0x03f8 0x03f8 0x03f8 # unix consensus
|
|
||||||
|
|
||||||
# https://youtu.be/GUQUD3IMbb4?t=85
|
# https://youtu.be/GUQUD3IMbb4?t=85
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_ALERT,1,1,1,1,1,1
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_AUTH,0x20,0x20,0x20,0x20,0x20,0x20
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_CONS,2,2,2,2,2,2
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_CRIT,2,2,2,2,2,2
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_CRON,72,72,72,72,72,72
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_DAEMON,24,24,24,24,24,24
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_DEBUG,7,7,7,7,7,7
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_EMERG,0,0,0,0,0,0
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_ERR,3,3,3,3,3,3
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_FACMASK,0x03f8,0x03f8,0x03f8,0x03f8,0x03f8,0x03f8
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_INFO,6,6,6,6,6,6
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_KERN,0,0,0,0,0,0
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_LOCAL0,0x80,0x80,0x80,0x80,0x80,0x80
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_LOCAL1,136,136,136,136,136,136
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_LOCAL2,144,144,144,144,144,144
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_LOCAL3,152,152,152,152,152,152
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_LOCAL4,160,160,160,160,160,160
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_LOCAL5,168,168,168,168,168,168
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_LOCAL6,176,176,176,176,176,176
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_LOCAL7,184,184,184,184,184,184
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_LPR,48,48,48,48,48,48
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_MAIL,0x10,0x10,0x10,0x10,0x10,0x10
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_NDELAY,8,8,8,8,8,8
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_NEWS,56,56,56,56,56,56
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_NFACILITIES,24,25,24,24,24,24
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_NOTICE,5,5,5,5,5,5
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_NOWAIT,0x10,0x10,0x10,0x10,0x10,0x10
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_ODELAY,4,4,4,4,4,4
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_PERROR,0x20,0x20,0x20,0x20,0x20,0x20
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_PID,1,1,1,1,1,1
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_PRIMASK,7,7,7,7,7,7
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_SELECT,76,0,0,0,0,0
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_SENSE,77,0,0,0,0,0
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_SYSLOG,40,40,40,40,40,40
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_USER,8,8,8,8,8,8
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_UUCP,0x40,0x40,0x40,0x40,0x40,40
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon log,LOG_WARNING,4,4,4,4,4,4
|
|
13
libc/sysv/consts/audit.h
Normal file
13
libc/sysv/consts/audit.h
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_AUDIT_H_
|
||||||
|
#define COSMOPOLITAN_LIBC_SYSV_CONSTS_AUDIT_H_
|
||||||
|
#include "libc/elf/def.h"
|
||||||
|
|
||||||
|
#define __AUDIT_ARCH_64BIT 0x80000000
|
||||||
|
#define __AUDIT_ARCH_LE 0x40000000
|
||||||
|
#define __AUDIT_ARCH_CONVENTION_MASK 0x30000000
|
||||||
|
#define __AUDIT_ARCH_CONVENTION_MIPS64_N32 0x20000000
|
||||||
|
|
||||||
|
#define AUDIT_ARCH_X86_64 (EM_X86_64 | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
|
||||||
|
#define AUDIT_ARCH_I386 (EM_386 | __AUDIT_ARCH_LE)
|
||||||
|
|
||||||
|
#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_AUDIT_H_ */
|
|
@ -1,93 +1,45 @@
|
||||||
#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_LOG_H_
|
#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_LOG_H_
|
||||||
#define COSMOPOLITAN_LIBC_SYSV_CONSTS_LOG_H_
|
#define COSMOPOLITAN_LIBC_SYSV_CONSTS_LOG_H_
|
||||||
#include "libc/runtime/symbolic.h"
|
|
||||||
|
|
||||||
#define LOG_ALERT SYMBOLIC(LOG_ALERT)
|
#define LOG_MASK(pri) (1 << (pri))
|
||||||
#define LOG_AUTH SYMBOLIC(LOG_AUTH)
|
#define LOG_UPTO(pri) ((1 << ((pri) + 1)) - 1)
|
||||||
#define LOG_CONS SYMBOLIC(LOG_CONS)
|
|
||||||
#define LOG_CRIT SYMBOLIC(LOG_CRIT)
|
|
||||||
#define LOG_CRON SYMBOLIC(LOG_CRON)
|
|
||||||
#define LOG_DAEMON SYMBOLIC(LOG_DAEMON)
|
|
||||||
#define LOG_DEBUG SYMBOLIC(LOG_DEBUG)
|
|
||||||
#define LOG_EMERG SYMBOLIC(LOG_EMERG)
|
|
||||||
#define LOG_ERR SYMBOLIC(LOG_ERR)
|
|
||||||
#define LOG_FACMASK SYMBOLIC(LOG_FACMASK)
|
|
||||||
#define LOG_INFO SYMBOLIC(LOG_INFO)
|
|
||||||
#define LOG_KERN SYMBOLIC(LOG_KERN)
|
|
||||||
#define LOG_LOCAL0 SYMBOLIC(LOG_LOCAL0)
|
|
||||||
#define LOG_LOCAL1 SYMBOLIC(LOG_LOCAL1)
|
|
||||||
#define LOG_LOCAL2 SYMBOLIC(LOG_LOCAL2)
|
|
||||||
#define LOG_LOCAL3 SYMBOLIC(LOG_LOCAL3)
|
|
||||||
#define LOG_LOCAL4 SYMBOLIC(LOG_LOCAL4)
|
|
||||||
#define LOG_LOCAL5 SYMBOLIC(LOG_LOCAL5)
|
|
||||||
#define LOG_LOCAL6 SYMBOLIC(LOG_LOCAL6)
|
|
||||||
#define LOG_LOCAL7 SYMBOLIC(LOG_LOCAL7)
|
|
||||||
#define LOG_LPR SYMBOLIC(LOG_LPR)
|
|
||||||
#define LOG_MAIL SYMBOLIC(LOG_MAIL)
|
|
||||||
#define LOG_NDELAY SYMBOLIC(LOG_NDELAY)
|
|
||||||
#define LOG_NEWS SYMBOLIC(LOG_NEWS)
|
|
||||||
#define LOG_NFACILITIES SYMBOLIC(LOG_NFACILITIES)
|
|
||||||
#define LOG_NOTICE SYMBOLIC(LOG_NOTICE)
|
|
||||||
#define LOG_NOWAIT SYMBOLIC(LOG_NOWAIT)
|
|
||||||
#define LOG_ODELAY SYMBOLIC(LOG_ODELAY)
|
|
||||||
#define LOG_PERROR SYMBOLIC(LOG_PERROR)
|
|
||||||
#define LOG_PID SYMBOLIC(LOG_PID)
|
|
||||||
#define LOG_PRIMASK SYMBOLIC(LOG_PRIMASK)
|
|
||||||
#define LOG_SELECT SYMBOLIC(LOG_SELECT)
|
|
||||||
#define LOG_SENSE SYMBOLIC(LOG_SENSE)
|
|
||||||
#define LOG_SYSLOG SYMBOLIC(LOG_SYSLOG)
|
|
||||||
#define LOG_USER SYMBOLIC(LOG_USER)
|
|
||||||
#define LOG_UUCP SYMBOLIC(LOG_UUCP)
|
|
||||||
#define LOG_WARNING SYMBOLIC(LOG_WARNING)
|
|
||||||
|
|
||||||
/*
|
#define LOG_EMERG 0
|
||||||
* arguments to setlogmask.
|
#define LOG_KERN 0
|
||||||
*/
|
#define LOG_ALERT 1
|
||||||
#define LOG_MASK(pri) (1 << (pri)) /* mask for one priority */
|
#define LOG_PID 1
|
||||||
#define LOG_UPTO(pri) ((1 << ((pri)+1)) - 1) /* all priorities through pri */
|
#define LOG_CONS 2
|
||||||
|
#define LOG_CRIT 2
|
||||||
|
#define LOG_ERR 3
|
||||||
|
#define LOG_ODELAY 4
|
||||||
|
#define LOG_WARNING 4
|
||||||
|
#define LOG_NOTICE 5
|
||||||
|
#define LOG_INFO 6
|
||||||
|
#define LOG_DEBUG 7
|
||||||
|
#define LOG_PRIMASK 7
|
||||||
|
#define LOG_NDELAY 8
|
||||||
|
#define LOG_USER 8
|
||||||
|
#define LOG_MAIL 16
|
||||||
|
#define LOG_NOWAIT 16
|
||||||
|
#define LOG_DAEMON 24
|
||||||
|
#define LOG_NFACILITIES 24
|
||||||
|
#define LOG_AUTH 32
|
||||||
|
#define LOG_PERROR 32
|
||||||
|
#define LOG_SYSLOG 40
|
||||||
|
#define LOG_LPR 48
|
||||||
|
#define LOG_NEWS 56
|
||||||
|
#define LOG_UUCP 64
|
||||||
|
#define LOG_CRON 72
|
||||||
|
#define LOG_SELECT 76
|
||||||
|
#define LOG_SENSE 77
|
||||||
|
#define LOG_LOCAL0 128
|
||||||
|
#define LOG_LOCAL1 136
|
||||||
|
#define LOG_LOCAL2 144
|
||||||
|
#define LOG_LOCAL3 152
|
||||||
|
#define LOG_LOCAL4 160
|
||||||
|
#define LOG_LOCAL5 168
|
||||||
|
#define LOG_LOCAL6 176
|
||||||
|
#define LOG_LOCAL7 184
|
||||||
|
#define LOG_FACMASK 0x03f8
|
||||||
|
|
||||||
|
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
|
||||||
COSMOPOLITAN_C_START_
|
|
||||||
|
|
||||||
extern const long LOG_ALERT;
|
|
||||||
extern const long LOG_AUTH;
|
|
||||||
extern const long LOG_CONS;
|
|
||||||
extern const long LOG_CRIT;
|
|
||||||
extern const long LOG_CRON;
|
|
||||||
extern const long LOG_DAEMON;
|
|
||||||
extern const long LOG_DEBUG;
|
|
||||||
extern const long LOG_EMERG;
|
|
||||||
extern const long LOG_ERR;
|
|
||||||
extern const long LOG_FACMASK;
|
|
||||||
extern const long LOG_INFO;
|
|
||||||
extern const long LOG_KERN;
|
|
||||||
extern const long LOG_LOCAL0;
|
|
||||||
extern const long LOG_LOCAL1;
|
|
||||||
extern const long LOG_LOCAL2;
|
|
||||||
extern const long LOG_LOCAL3;
|
|
||||||
extern const long LOG_LOCAL4;
|
|
||||||
extern const long LOG_LOCAL5;
|
|
||||||
extern const long LOG_LOCAL6;
|
|
||||||
extern const long LOG_LOCAL7;
|
|
||||||
extern const long LOG_LPR;
|
|
||||||
extern const long LOG_MAIL;
|
|
||||||
extern const long LOG_NDELAY;
|
|
||||||
extern const long LOG_NEWS;
|
|
||||||
extern const long LOG_NFACILITIES;
|
|
||||||
extern const long LOG_NOTICE;
|
|
||||||
extern const long LOG_NOWAIT;
|
|
||||||
extern const long LOG_ODELAY;
|
|
||||||
extern const long LOG_PERROR;
|
|
||||||
extern const long LOG_PID;
|
|
||||||
extern const long LOG_PRIMASK;
|
|
||||||
extern const long LOG_SELECT;
|
|
||||||
extern const long LOG_SENSE;
|
|
||||||
extern const long LOG_SYSLOG;
|
|
||||||
extern const long LOG_USER;
|
|
||||||
extern const long LOG_UUCP;
|
|
||||||
extern const long LOG_WARNING;
|
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
|
||||||
#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_LOG_H_ */
|
#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_LOG_H_ */
|
||||||
|
|
|
@ -7,6 +7,9 @@
|
||||||
#define SECCOMP_MODE_STRICT 1
|
#define SECCOMP_MODE_STRICT 1
|
||||||
#define SECCOMP_MODE_FILTER 2
|
#define SECCOMP_MODE_FILTER 2
|
||||||
|
|
||||||
|
#define PR_SET_NO_NEW_PRIVS 38
|
||||||
|
#define PR_GET_NO_NEW_PRIVS 39
|
||||||
|
|
||||||
#define PR_SET_NAME 15
|
#define PR_SET_NAME 15
|
||||||
#define PR_GET_NAME 0x10
|
#define PR_GET_NAME 0x10
|
||||||
|
|
||||||
|
@ -85,8 +88,6 @@
|
||||||
#define PR_SET_MM 35
|
#define PR_SET_MM 35
|
||||||
#define PR_SET_CHILD_SUBREAPER 36
|
#define PR_SET_CHILD_SUBREAPER 36
|
||||||
#define PR_GET_CHILD_SUBREAPER 37
|
#define PR_GET_CHILD_SUBREAPER 37
|
||||||
#define PR_SET_NO_NEW_PRIVS 38
|
|
||||||
#define PR_GET_NO_NEW_PRIVS 39
|
|
||||||
#define PR_GET_TID_ADDRESS 40
|
#define PR_GET_TID_ADDRESS 40
|
||||||
#define PR_SET_THP_DISABLE 41
|
#define PR_SET_THP_DISABLE 41
|
||||||
#define PR_GET_THP_DISABLE 42
|
#define PR_GET_THP_DISABLE 42
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_SECCOMP_H_
|
|
||||||
#define COSMOPOLITAN_LIBC_SYSV_CONSTS_SECCOMP_H_
|
|
||||||
|
|
||||||
#define SECCOMP_SET_MODE_STRICT 0
|
|
||||||
#define SECCOMP_SET_MODE_FILTER 1
|
|
||||||
#define SECCOMP_GET_ACTION_AVAIL 2
|
|
||||||
#define SECCOMP_GET_NOTIF_SIZES 3
|
|
||||||
#define SECCOMP_FILTER_FLAG_TSYNC (1UL << 0)
|
|
||||||
#define SECCOMP_FILTER_FLAG_LOG (1UL << 1)
|
|
||||||
#define SECCOMP_FILTER_FLAG_SPEC_ALLOW (1UL << 2)
|
|
||||||
#define SECCOMP_FILTER_FLAG_NEW_LISTENER (1UL << 3)
|
|
||||||
#define SECCOMP_FILTER_FLAG_TSYNC_ESRCH (1UL << 4)
|
|
||||||
#define SECCOMP_RET_KILL_PROCESS 0x80000000U
|
|
||||||
#define SECCOMP_RET_KILL_THREAD 0x00000000U
|
|
||||||
#define SECCOMP_RET_KILL SECCOMP_RET_KILL_THREAD
|
|
||||||
#define SECCOMP_RET_TRAP 0x00030000U
|
|
||||||
#define SECCOMP_RET_ERRNO 0x00050000U
|
|
||||||
#define SECCOMP_RET_USER_NOTIF 0x7fc00000U
|
|
||||||
#define SECCOMP_RET_TRACE 0x7ff00000U
|
|
||||||
#define SECCOMP_RET_LOG 0x7ffc0000U
|
|
||||||
#define SECCOMP_RET_ALLOW 0x7fff0000U
|
|
||||||
#define SECCOMP_RET_ACTION_FULL 0xffff0000U
|
|
||||||
#define SECCOMP_RET_ACTION 0x7fff0000U
|
|
||||||
#define SECCOMP_RET_DATA 0x0000ffffU
|
|
||||||
#define SECCOMP_USER_NOTIF_FLAG_CONTINUE (1UL << 0)
|
|
||||||
#define SECCOMP_ADDFD_FLAG_SETFD (1UL << 0)
|
|
||||||
#define SECCOMP_ADDFD_FLAG_SEND (1UL << 1)
|
|
||||||
|
|
||||||
#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_SECCOMP_H_ */
|
|
|
@ -47,7 +47,7 @@ scall sys_lseek 0x0c70c71de20c7008 globl hidden # netbsd+openbsd:evilpad
|
||||||
scall __sys_mmap 0x0c50c51dd20c5009 globl hidden # netbsd+openbsd:pad
|
scall __sys_mmap 0x0c50c51dd20c5009 globl hidden # netbsd+openbsd:pad
|
||||||
scall sys_msync 0x115100041204101a globl hidden
|
scall sys_msync 0x115100041204101a globl hidden
|
||||||
scall sys_mprotect 0x04a04a04a204a00a globl hidden
|
scall sys_mprotect 0x04a04a04a204a00a globl hidden
|
||||||
scall __sys_munmap 0x049049049204900b globl hidden
|
scall __sys_munmap 0x049049049204090b globl hidden
|
||||||
scall sys_sigaction 0x15402e1a0202e00d globl hidden # rt_sigaction on Lunix; it's complicated on NetBSD
|
scall sys_sigaction 0x15402e1a0202e00d globl hidden # rt_sigaction on Lunix; it's complicated on NetBSD
|
||||||
scall sys_sigprocmask 0x125030154214900e globl hidden # a.k.a. rt_sigprocmask, openbsd:byvalue, a.k.a. pthread_sigmask
|
scall sys_sigprocmask 0x125030154214900e globl hidden # a.k.a. rt_sigprocmask, openbsd:byvalue, a.k.a. pthread_sigmask
|
||||||
scall sys_ioctl 0x0360360362036010 globl hidden
|
scall sys_ioctl 0x0360360362036010 globl hidden
|
||||||
|
|
|
@ -64,8 +64,9 @@ testonly void testlib_showerror_(int line, const char *wantcode,
|
||||||
e = errno;
|
e = errno;
|
||||||
if (!IsWindows()) __getpid();
|
if (!IsWindows()) __getpid();
|
||||||
if (!IsWindows()) __getpid();
|
if (!IsWindows()) __getpid();
|
||||||
__stpcpy(hostname, "unknown");
|
if (gethostname(hostname, sizeof(hostname))) {
|
||||||
gethostname(hostname, sizeof(hostname));
|
__stpcpy(hostname, "unknown");
|
||||||
|
}
|
||||||
kprintf("%serror%s:%s%s:%d%s: %s(%s) on %s\n"
|
kprintf("%serror%s:%s%s:%d%s: %s(%s) on %s\n"
|
||||||
"\t%s(%s, %s)\n",
|
"\t%s(%s, %s)\n",
|
||||||
RED2, UNBOLD, BLUE1, testlib_showerror_file, line, RESET,
|
RED2, UNBOLD, BLUE1, testlib_showerror_file, line, RESET,
|
||||||
|
|
|
@ -17,19 +17,29 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
|
#include "libc/calls/struct/bpf.h"
|
||||||
|
#include "libc/calls/struct/filter.h"
|
||||||
#include "libc/calls/struct/iovec.h"
|
#include "libc/calls/struct/iovec.h"
|
||||||
|
#include "libc/calls/struct/seccomp.h"
|
||||||
|
#include "libc/errno.h"
|
||||||
#include "libc/intrin/kprintf.h"
|
#include "libc/intrin/kprintf.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/sock/sock.h"
|
#include "libc/sock/sock.h"
|
||||||
|
#include "libc/sysv/consts/audit.h"
|
||||||
#include "libc/sysv/consts/o.h"
|
#include "libc/sysv/consts/o.h"
|
||||||
#include "libc/sysv/consts/pr.h"
|
#include "libc/sysv/consts/pr.h"
|
||||||
#include "libc/sysv/consts/seccomp.h"
|
|
||||||
#include "libc/sysv/consts/sig.h"
|
#include "libc/sysv/consts/sig.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
#include "tool/net/sandbox.h"
|
||||||
|
|
||||||
bool __is_linux_2_6_23(void) {
|
bool __is_linux_2_6_23(void) {
|
||||||
|
int rc;
|
||||||
if (!IsLinux()) return false;
|
if (!IsLinux()) return false;
|
||||||
return prctl(PR_GET_SECCOMP) != -1; // errno should be EINVAL
|
asm volatile("syscall"
|
||||||
|
: "=a"(rc)
|
||||||
|
: "0"(157), "D"(PR_GET_SECCOMP)
|
||||||
|
: "rcx", "r11", "memory");
|
||||||
|
return rc != -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetUp(void) {
|
void SetUp(void) {
|
||||||
|
@ -70,3 +80,46 @@ TEST(seccompStrictMode, goodProcess_isAuthorized) {
|
||||||
EXPECT_EQ(0, WEXITSTATUS(ws));
|
EXPECT_EQ(0, WEXITSTATUS(ws));
|
||||||
EXPECT_STREQ("hi", buf);
|
EXPECT_STREQ("hi", buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(seccompFilter, isSoMuchBetter) {
|
||||||
|
char buf[3] = {0};
|
||||||
|
int ws, pid, pfds[2];
|
||||||
|
ASSERT_SYS(0, 0, pipe(pfds));
|
||||||
|
ASSERT_NE(-1, (pid = fork()));
|
||||||
|
if (!pid) {
|
||||||
|
struct sock_filter filter[] = {
|
||||||
|
_SECCOMP_MACHINE(AUDIT_ARCH_X86_64), //
|
||||||
|
_SECCOMP_LOAD_SYSCALL_NR(), //
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0013), // readv
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0014), // writev
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0000), // read
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0001), // write
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0003), // close
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x000f), // rt_sigreturn
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x00e7), // exit_group
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0009), // mmap
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0106), // newfstatat
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0008), // lseek
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x000b), // munmap
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x00e4), // clock_gettime
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x003f), // uname
|
||||||
|
_SECCOMP_LOG_AND_RETURN_ERRNO(1), // EPERM
|
||||||
|
};
|
||||||
|
struct sock_fprog prog = {
|
||||||
|
.len = ARRAYLEN(filter),
|
||||||
|
.filter = filter,
|
||||||
|
};
|
||||||
|
ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
|
||||||
|
ASSERT_EQ(0, prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog));
|
||||||
|
ASSERT_SYS(0, 3, write(pfds[1], "hi", 3));
|
||||||
|
ASSERT_SYS(EPERM, -1, open("/etc/passwd", O_RDONLY));
|
||||||
|
_Exit(0);
|
||||||
|
}
|
||||||
|
EXPECT_SYS(0, 0, close(pfds[1]));
|
||||||
|
EXPECT_SYS(0, 3, read(pfds[0], buf, 3));
|
||||||
|
EXPECT_SYS(0, 0, close(pfds[0]));
|
||||||
|
EXPECT_NE(-1, wait(&ws));
|
||||||
|
EXPECT_TRUE(WIFEXITED(ws));
|
||||||
|
EXPECT_EQ(0, WEXITSTATUS(ws));
|
||||||
|
EXPECT_STREQ("hi", buf);
|
||||||
|
}
|
||||||
|
|
|
@ -166,7 +166,7 @@ static const struct {
|
||||||
{"", "% s"}, //
|
{"", "% s"}, //
|
||||||
{"𐌰𐌱𐌲𐌳𐌴𐌵𐌶𐌷", "%hs", S(u"𐌰𐌱𐌲𐌳𐌴𐌵𐌶𐌷")}, //
|
{"𐌰𐌱𐌲𐌳𐌴𐌵𐌶𐌷", "%hs", S(u"𐌰𐌱𐌲𐌳𐌴𐌵𐌶𐌷")}, //
|
||||||
{"☺☻♥♦♣♠!", "%ls", S(L"☺☻♥♦♣♠!")}, //
|
{"☺☻♥♦♣♠!", "%ls", S(L"☺☻♥♦♣♠!")}, //
|
||||||
{"☺☻♥♦♣♠!\n", "%S", S(L"☺☻♥♦♣♠!\n")}, //
|
{"HELLO", "%^s", S("hello")}, //
|
||||||
{"eeeeeee ", "%10s", S("eeeeeee")}, //
|
{"eeeeeee ", "%10s", S("eeeeeee")}, //
|
||||||
{"hello", "%.*s", 5, S("hello world")}, //
|
{"hello", "%.*s", 5, S("hello world")}, //
|
||||||
{"þell", "%.*s", 5, S("þello world")}, //
|
{"þell", "%.*s", 5, S("þello world")}, //
|
||||||
|
@ -179,7 +179,6 @@ static const struct {
|
||||||
{"\"xx\"", "%#s", S("xx")}, //
|
{"\"xx\"", "%#s", S("xx")}, //
|
||||||
{"u\"☺☺\"", "%#hs", S(u"☺☺")}, //
|
{"u\"☺☺\"", "%#hs", S(u"☺☺")}, //
|
||||||
{"L\"☺☺\"", "%#ls", S(L"☺☺")}, //
|
{"L\"☺☺\"", "%#ls", S(L"☺☺")}, //
|
||||||
{"L\"☺☺\"", "%#S", S(L"☺☺")}, //
|
|
||||||
{"\"\\\\\\\"\\177\"", "%#s", S("\\\"\177")}, //
|
{"\"\\\\\\\"\\177\"", "%#s", S("\\\"\177")}, //
|
||||||
{"%%", "%%%%"}, //
|
{"%%", "%%%%"}, //
|
||||||
{"%", "%.%"}, //
|
{"%", "%.%"}, //
|
||||||
|
|
8
third_party/lua/lauxlib.c
vendored
8
third_party/lua/lauxlib.c
vendored
|
@ -202,16 +202,16 @@ LUALIB_API void luaL_traceback2(lua_State *L, lua_State *L1, const char *msg,
|
||||||
int top = lua_gettop(L);
|
int top = lua_gettop(L);
|
||||||
int last = lastlevel(L1);
|
int last = lastlevel(L1);
|
||||||
int n1 = (last - level > LEVELS1 + LEVELS2) ? LEVELS1 : -1;
|
int n1 = (last - level > LEVELS1 + LEVELS2) ? LEVELS1 : -1;
|
||||||
if (msg) lua_pushfstring(L, "%s\n", msg);
|
if (msg) lua_pushfstring(L, "%s\r\n", msg);
|
||||||
luaL_checkstack(L, 10, NULL);
|
luaL_checkstack(L, 10, NULL);
|
||||||
lua_pushliteral(L, "stack traceback:");
|
lua_pushliteral(L, "stack traceback:");
|
||||||
while (lua_getstack(L1, level++, &ar)) {
|
while (lua_getstack(L1, level++, &ar)) {
|
||||||
if (n1-- == 0) { /* too many levels? */
|
if (n1-- == 0) { /* too many levels? */
|
||||||
lua_pushliteral(L, "\n\t..."); /* add a '...' */
|
lua_pushliteral(L, "\r\n\t..."); /* add a '...' */
|
||||||
level = last - LEVELS2 + 1; /* and skip to last ones */
|
level = last - LEVELS2 + 1; /* and skip to last ones */
|
||||||
} else {
|
} else {
|
||||||
lua_getinfo(L1, "Slntu", &ar);
|
lua_getinfo(L1, "Slntu", &ar);
|
||||||
lua_pushfstring(L, "\n\t%s:", ar.short_src);
|
lua_pushfstring(L, "\r\n\t%s:", ar.short_src);
|
||||||
if (ar.currentline > 0)
|
if (ar.currentline > 0)
|
||||||
lua_pushfstring(L, "%d:", ar.currentline);
|
lua_pushfstring(L, "%d:", ar.currentline);
|
||||||
lua_pushliteral(L, " in ");
|
lua_pushliteral(L, " in ");
|
||||||
|
@ -228,7 +228,7 @@ LUALIB_API void luaL_traceback2(lua_State *L, lua_State *L1, const char *msg,
|
||||||
lua_pop(L, 2);
|
lua_pop(L, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ar.istailcall) lua_pushliteral(L, "\n\t(...tail calls...)");
|
if (ar.istailcall) lua_pushliteral(L, "\r\n\t(...tail calls...)");
|
||||||
lua_concat(L, lua_gettop(L) - top);
|
lua_concat(L, lua_gettop(L) - top);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ FLAGS
|
||||||
-s increase silence [repeatable]
|
-s increase silence [repeatable]
|
||||||
-v increase verbosity [repeatable]
|
-v increase verbosity [repeatable]
|
||||||
-V increase ssl verbosity [repeatable]
|
-V increase ssl verbosity [repeatable]
|
||||||
|
-S increase bpf seccomp sandboxing [repeatable]
|
||||||
-H K:V sets http header globally [repeatable]
|
-H K:V sets http header globally [repeatable]
|
||||||
-D DIR overlay assets in local directory [repeatable]
|
-D DIR overlay assets in local directory [repeatable]
|
||||||
-r /X=/Y redirect X to Y [repeatable]
|
-r /X=/Y redirect X to Y [repeatable]
|
||||||
|
@ -1231,7 +1232,7 @@ UNIX MODULE
|
||||||
|
|
||||||
Reads from file descriptor.
|
Reads from file descriptor.
|
||||||
|
|
||||||
unix.write(fd:int, data[, offset]) → rc:int, errno:int
|
unix.write(fd:int, data[, offset]) → rc:int[, errno:int]
|
||||||
|
|
||||||
Writes to file descriptor.
|
Writes to file descriptor.
|
||||||
|
|
||||||
|
@ -1242,25 +1243,25 @@ UNIX MODULE
|
||||||
`flags` should have one of `O_RDONLY`, `O_WRONLY`, or `O_RDWR`.
|
`flags` should have one of `O_RDONLY`, `O_WRONLY`, or `O_RDWR`.
|
||||||
The following values may also be OR'd into `flags`:
|
The following values may also be OR'd into `flags`:
|
||||||
|
|
||||||
- `O_CREAT`: Create file if it doesn't exist.
|
- `O_CREAT`: create file if it doesn't exist
|
||||||
- `O_TRUNC` Automatic truncate(fd,0) if exists.
|
- `O_TRUNC` automatic ftruncate(fd,0) if exists
|
||||||
- `O_CLOEXEC`: Automatic close() upon execve().
|
- `O_CLOEXEC`: automatic close() upon execve()
|
||||||
- `O_EXCL`: Exclusive access. See below.
|
- `O_EXCL`: exclusive access (see below)
|
||||||
- `O_APPEND`: Open file for append only.
|
- `O_APPEND`: open file for append only
|
||||||
- `O_DIRECT` (not supported on Apple and OpenBSD)
|
- `O_DIRECT` it's complicated (not supported on Apple and OpenBSD)
|
||||||
- `O_DIRECTORY` (hint on UNIX but required on NT)
|
- `O_DIRECTORY` useful for stat'ing (hint on UNIX but required on NT)
|
||||||
- `O_TMPFILE` (for Linux and Windows only)
|
- `O_TMPFILE` try to make temp more secure (Linux and Windows only)
|
||||||
- `O_NOFOLLOW` (zero on Windows)
|
- `O_NOFOLLOW` fail if it's a symlink (zero on Windows)
|
||||||
- `O_DSYNC` (zero on non-Linux/Apple)
|
- `O_DSYNC` it's complicated (zero on non-Linux/Apple)
|
||||||
- `O_RSYNC` (zero on non-Linux/Apple)
|
- `O_RSYNC` it's complicated (zero on non-Linux/Apple)
|
||||||
- `O_PATH` (zero on non-Linux)
|
- `O_PATH` it's complicated (zero on non-Linux)
|
||||||
- `O_VERIFY` (zero on non-FreeBSD)
|
- `O_VERIFY` it's complicated (zero on non-FreeBSD)
|
||||||
- `O_SHLOCK` (zero on non-BSD)
|
- `O_SHLOCK` it's complicated (zero on non-BSD)
|
||||||
- `O_EXLOCK` (zero on non-BSD)
|
- `O_EXLOCK` it's complicated (zero on non-BSD)
|
||||||
- `O_RANDOM` (zero on non-Windows)
|
- `O_RANDOM` hint random access intent (zero on non-Windows)
|
||||||
- `O_SEQUENTIAL` (zero on non-Windows)
|
- `O_SEQUENTIAL` hint sequential access intent (zero on non-Windows)
|
||||||
- `O_COMPRESSED` (zero on non-Windows)
|
- `O_COMPRESSED` ask fs to abstract compression (zero on non-Windows)
|
||||||
- `O_INDEXED` (zero on non-Windows)
|
- `O_INDEXED` turns on that slow performance (zero on non-Windows)
|
||||||
|
|
||||||
There are three regular combinations for the above flags:
|
There are three regular combinations for the above flags:
|
||||||
|
|
||||||
|
@ -1277,7 +1278,7 @@ UNIX MODULE
|
||||||
already. If it does exist then `nil` is returned along with
|
already. If it does exist then `nil` is returned along with
|
||||||
`errno` set to `EEXIST`.
|
`errno` set to `EEXIST`.
|
||||||
|
|
||||||
unix.close(fd:int) → rc:int, errno:int
|
unix.close(fd:int) → rc:int[, errno:int]
|
||||||
|
|
||||||
Closes file descriptor.
|
Closes file descriptor.
|
||||||
|
|
||||||
|
@ -1288,12 +1289,12 @@ UNIX MODULE
|
||||||
will be closed. Any open connections it owns will be reset. This
|
will be closed. Any open connections it owns will be reset. This
|
||||||
function never returns.
|
function never returns.
|
||||||
|
|
||||||
unix.fork() → childpid|0, errno:int
|
unix.fork() → childpid|0:int[, errno:int]
|
||||||
|
|
||||||
Creates a new process mitosis style. This returns twice. The
|
Creates a new process mitosis style. This returns twice. The
|
||||||
parent process gets the nonzero pid. The child gets zero.
|
parent process gets the nonzero pid. The child gets zero.
|
||||||
|
|
||||||
unix.commandv(prog) → path, errno:int
|
unix.commandv(prog:str) → path:str[, errno:int]
|
||||||
|
|
||||||
Performs `$PATH` lookup of executable. We automatically suffix
|
Performs `$PATH` lookup of executable. We automatically suffix
|
||||||
`.com` and `.exe` automatically for all platforms when path
|
`.com` and `.exe` automatically for all platforms when path
|
||||||
|
@ -1302,6 +1303,11 @@ UNIX MODULE
|
||||||
`prog` contains slashes then it's not path searched either and
|
`prog` contains slashes then it's not path searched either and
|
||||||
will be returned if it exists.
|
will be returned if it exists.
|
||||||
|
|
||||||
|
unix.realpath(filename:str) → abspath:str[, errno:int]
|
||||||
|
|
||||||
|
Returns absolute path of filename, with `.` and `..` components
|
||||||
|
removed, and symlinks will be resolved.
|
||||||
|
|
||||||
unix.execve(prog, argv[, envp]) → errno
|
unix.execve(prog, argv[, envp]) → errno
|
||||||
|
|
||||||
Exits current process, replacing it with a new instance of the
|
Exits current process, replacing it with a new instance of the
|
||||||
|
@ -1315,29 +1321,29 @@ UNIX MODULE
|
||||||
The first element in `argv` should be `prog`. This function is
|
The first element in `argv` should be `prog`. This function is
|
||||||
normally called after forking.
|
normally called after forking.
|
||||||
|
|
||||||
unix.access(path:str, how) → rc:int, errno:int
|
unix.access(path:str, how) → rc:int[, errno:int]
|
||||||
|
|
||||||
Checks if effective user of current process has permission to
|
Checks if effective user of current process has permission to
|
||||||
access file. `how` can be `R_OK`, `W_OK`, `X_OK`, or `F_OK` to
|
access file. `how` can be `R_OK`, `W_OK`, `X_OK`, or `F_OK` to
|
||||||
check for read, write, execute, and existence respectively.
|
check for read, write, execute, and existence respectively.
|
||||||
|
|
||||||
unix.mkdir(path:str, mode) → rc:int, errno:int
|
unix.mkdir(path:str, mode) → rc:int[, errno:int]
|
||||||
|
|
||||||
Makes directory. `mode` should be octal, e.g. `0755`.
|
Makes directory. `mode` should be octal, e.g. `0755`.
|
||||||
|
|
||||||
unix.chdir(path:str) → rc:int, errno:int
|
unix.chdir(path:str) → rc:int[, errno:int]
|
||||||
|
|
||||||
Changes current directory to `path`.
|
Changes current directory to `path`.
|
||||||
|
|
||||||
unix.unlink(path:str) → rc:int, errno:int
|
unix.unlink(path:str) → rc:int[, errno:int]
|
||||||
|
|
||||||
Removes file at `path`.
|
Removes file at `path`.
|
||||||
|
|
||||||
unix.rmdir(path:str) → rc:int, errno:int
|
unix.rmdir(path:str) → rc:int[, errno:int]
|
||||||
|
|
||||||
Removes empty directory at `path`.
|
Removes empty directory at `path`.
|
||||||
|
|
||||||
unix.chroot(path:str) → rc:int, errno:int
|
unix.chroot(path:str) → rc:int[, errno:int]
|
||||||
|
|
||||||
Changes root directory. Raises `ENOSYS` on Windows.
|
Changes root directory. Raises `ENOSYS` on Windows.
|
||||||
|
|
||||||
|
@ -1352,44 +1358,95 @@ UNIX MODULE
|
||||||
writing. `flags` can have `O_CLOEXEC`. On error, `reader` and
|
writing. `flags` can have `O_CLOEXEC`. On error, `reader` and
|
||||||
`writer` will be `nil` and `errno` will be set to non-nil.
|
`writer` will be `nil` and `errno` will be set to non-nil.
|
||||||
|
|
||||||
unix.rename(oldpath, newpath) → rc:int, errno:int
|
unix.rename(oldpath:str, newpath:str) → rc:int[, errno:int]
|
||||||
unix.link(existingpath, newpath) → rc:int, errno:int
|
|
||||||
unix.symlink(target, linkpath) → rc:int, errno:int
|
Renames file.
|
||||||
unix.chown(path:str, uid, gid) → rc:int, errno:int
|
|
||||||
unix.chmod(path:str, mode) → rc:int, errno:int
|
unix.link(existingpath:str, newpath:str) → rc:int[, errno:int]
|
||||||
unix.getcwd(path:str, mode) → rc:int, errno:int
|
|
||||||
|
Creates hard link, so your underlying inode has two names.
|
||||||
|
|
||||||
|
unix.symlink(target:str, linkpath:str) → rc:int[, errno:int]
|
||||||
|
|
||||||
|
Creates soft link, or a symbolic link.
|
||||||
|
|
||||||
|
unix.chown(path:str, uid, gid) → rc:int[, errno:int]
|
||||||
|
|
||||||
|
Changes user and gorup on file.
|
||||||
|
|
||||||
|
unix.chmod(path:str, mode) → rc:int[, errno:int]
|
||||||
|
unix.getcwd(path:str, mode) → rc:int[, errno:int]
|
||||||
unix.getpid() → pid
|
unix.getpid() → pid
|
||||||
unix.getppid() → pid
|
unix.getppid() → pid
|
||||||
unix.kill(pid, sig) → rc:int, errno:int
|
unix.kill(pid, sig) → rc:int[, errno:int]
|
||||||
unix.raise(sig) → rc:int, errno:int
|
unix.raise(sig) → rc:int[, errno:int]
|
||||||
unix.wait(pid[, options]) → pid, wstatus, nil, errno:int
|
unix.wait(pid[, options]) → pid, wstatus, nil, errno:int
|
||||||
unix.fcntl(fd:int, cmd[, arg]) → rc:int, errno:int
|
unix.fcntl(fd:int, cmd[, arg]) → rc:int[, errno:int]
|
||||||
unix.getsid(pid) → sid, errno:int
|
unix.getsid(pid) → sid, errno:int
|
||||||
unix.getpgrp() → pgid, errno:int
|
unix.getpgrp() → pgid, errno:int
|
||||||
unix.getpgid(pid) → pgid, errno:int
|
unix.getpgid(pid) → pgid, errno:int
|
||||||
unix.setpgid(pid, pgid) → pgid, errno:int
|
unix.setpgid(pid, pgid) → pgid, errno:int
|
||||||
unix.setsid() → sid, errno:int
|
unix.setsid() → sid, errno:int
|
||||||
unix.getuid() → uid, errno:int
|
unix.getuid() → uid, errno:int
|
||||||
|
unix.setuid(uid:int) → rc:int[, errno:int]
|
||||||
unix.getgid() → gid, errno:int
|
unix.getgid() → gid, errno:int
|
||||||
unix.umask(mask) → rc:int, errno:int
|
unix.setgid(gid:int) → rc:int[, errno:int]
|
||||||
unix.gettime([clock]) → seconds, nanos, errno:int
|
unix.umask(mask) → rc:int[, errno:int]
|
||||||
unix.nanosleep(seconds, nanos) → remseconds, remnanos, errno:int
|
|
||||||
unix.sync(fd:int)
|
|
||||||
unix.fsync(fd:int) → rc:int, errno:int
|
|
||||||
unix.fdatasync(fd:int) → rc:int, errno:int
|
|
||||||
|
|
||||||
unix.seek(fd:int, offset, whence) → newpos, errno:int
|
unix.syslog(priority:str, msg:str)
|
||||||
where whence ∈ {SEEK_SET, SEEK_CUR, SEEK_END}
|
|
||||||
whence defaults to SEEK_SET
|
Generates a log message which will be distributed by syslogd.
|
||||||
unix.truncate(path:str, length) → rc:int, errno:int
|
|
||||||
unix.truncate(fd:int, length) → rc:int, errno:int
|
`priority` is a bitmask containing the facility value and the
|
||||||
|
level value. If no facility value is ORed into priority, then
|
||||||
|
the default value set by openlog() is used. it set to NULL, the
|
||||||
|
program name is used. Level is one of `LOG_EMERG`, `LOG_ALERT`,
|
||||||
|
`LOG_CRIT`, `LOG_ERR`, `LOG_WARNING`, `LOG_NOTICE`, `LOG_INFO`,
|
||||||
|
`LOG_DEBUG`.
|
||||||
|
|
||||||
|
This function currently works on Linux, Windows, and NetBSD. On
|
||||||
|
WIN32 it uses the ReportEvent() facility.
|
||||||
|
|
||||||
|
unix.clock_gettime([clock]) → seconds, nanos, errno:int
|
||||||
|
|
||||||
|
Returns nanosecond precision timestamp from the system.
|
||||||
|
|
||||||
|
`clock` should be `CLOCK_REALTIME`, `CLOCK_MONOTONIC`, or
|
||||||
|
`CLOCK_MONOTONIC_RAW` since they work across platforms.
|
||||||
|
You may also try your luck with `CLOCK_REALTIME_COARSE`,
|
||||||
|
`CLOCK_MONOTONIC_COARSE`, `CLOCK_PROCESS_CPUTIME_ID`,
|
||||||
|
`CLOCK_TAI`, `CLOCK_PROF`, `CLOCK_BOOTTIME`,
|
||||||
|
`CLOCK_REALTIME_ALARM`, and `CLOCK_BOOTTIME_ALARM`,
|
||||||
|
|
||||||
|
unix.nanosleep(seconds, nanos) → remseconds, remnanos, errno:int
|
||||||
|
|
||||||
|
Sleeps with nanosecond precision.
|
||||||
|
|
||||||
|
unix.sync(fd:int)
|
||||||
|
unix.fsync(fd:int) → rc:int[, errno:int]
|
||||||
|
unix.fdatasync(fd:int) → rc:int[, errno:int]
|
||||||
|
|
||||||
|
These functions are used to make programs slower by asking the
|
||||||
|
operating system to flush data to the physical medium.
|
||||||
|
|
||||||
|
unix.seek(fd:int, offset:int, whence:int) → newpos:int[, errno:int]
|
||||||
|
|
||||||
|
Seeks to file position.
|
||||||
|
|
||||||
|
`whence` can be one of `SEEK_SET`, `SEEK_CUR`, or `SEEK_END`.
|
||||||
|
|
||||||
|
unix.truncate(path:str, length) → rc:int[, errno:int]
|
||||||
|
unix.ftruncate(fd:int, length) → rc:int[, errno:int]
|
||||||
|
|
||||||
|
Reduces or extends underlying physical medium of file.
|
||||||
|
If file was originally larger, content >length is lost.
|
||||||
|
|
||||||
unix.socket([family[, type[, protocol]]]) → fd:int[, errno:int]
|
unix.socket([family[, type[, protocol]]]) → fd:int[, errno:int]
|
||||||
|
|
||||||
`SOCK_CLOEXEC` may be or'd into type
|
`SOCK_CLOEXEC` may be or'd into type
|
||||||
`family` defaults to `AF_INET`
|
`family` defaults to `AF_INET` but can be `AF_UNIX`
|
||||||
`type` defaults to `SOCK_STREAM`
|
`type` defaults to `SOCK_STREAM` but can be `SOCK_DGRAM`
|
||||||
`protocol` defaults to `IPPROTO_TCP`
|
`protocol` defaults to `IPPROTO_TCP` but can be `IPPROTO_UDP`
|
||||||
|
|
||||||
unix.socketpair([family[, type[, protocol]]]) → fd1, fd2, errno:int
|
unix.socketpair([family[, type[, protocol]]]) → fd1, fd2, errno:int
|
||||||
|
|
||||||
|
@ -1398,11 +1455,11 @@ UNIX MODULE
|
||||||
`type` defaults to `SOCK_STREAM`
|
`type` defaults to `SOCK_STREAM`
|
||||||
`protocol` defaults to `IPPROTO_TCP`
|
`protocol` defaults to `IPPROTO_TCP`
|
||||||
|
|
||||||
unix.bind(fd:int, ip, port) → rc:int, errno:int
|
unix.bind(fd:int, ip, port) → rc:int[, errno:int]
|
||||||
|
|
||||||
unix.connect(fd:int, ip, port) → rc:int, errno:int
|
unix.connect(fd:int, ip, port) → rc:int[, errno:int]
|
||||||
|
|
||||||
unix.listen(fd:int[, backlog]) → rc:int, errno:int
|
unix.listen(fd:int[, backlog]) → rc:int[, errno:int]
|
||||||
|
|
||||||
unix.getsockname(fd:int) → ip, port, errno:int
|
unix.getsockname(fd:int) → ip, port, errno:int
|
||||||
|
|
||||||
|
@ -1430,7 +1487,7 @@ UNIX MODULE
|
||||||
addresses. The `flags` parameter can have `MSG_OOB`,
|
addresses. The `flags` parameter can have `MSG_OOB`,
|
||||||
`MSG_DONTROUTE`, or `MSG_NOSIGNAL`.
|
`MSG_DONTROUTE`, or `MSG_NOSIGNAL`.
|
||||||
|
|
||||||
unix.shutdown(fd:int, how:int) → rc:int, errno:int
|
unix.shutdown(fd:int, how:int) → rc:int[, errno:int]
|
||||||
|
|
||||||
Partially closes socket. `how` can be `SHUT_RD`, `SHUT_WR`, or
|
Partially closes socket. `how` can be `SHUT_RD`, `SHUT_WR`, or
|
||||||
`SHUT_RDWR`.
|
`SHUT_RDWR`.
|
||||||
|
@ -1602,21 +1659,6 @@ UNIX MODULE
|
||||||
- `ENOSYS`: System call not available on this platform. On Windows
|
- `ENOSYS`: System call not available on this platform. On Windows
|
||||||
this is raised by chroot(), setuid(), setgid().
|
this is raised by chroot(), setuid(), setgid().
|
||||||
|
|
||||||
- `EPERM`: Operation not permitted. Raised by accept(), adjtimex(),
|
|
||||||
arch_prctl(), bdflush(), capget(), chmod(), chown(), chroot(),
|
|
||||||
clock_getres(), copy_file_range(), execve(), fcntl(),
|
|
||||||
get_robust_list(), getdomainname(), getgroups(), gethostname(),
|
|
||||||
getpriority(), getrlimit(), getsid(), gettimeofday(), kill(),
|
|
||||||
link(), mbind(), membarrier(), migrate_pages(), mkdir(), mknod(),
|
|
||||||
mlock(), mmap(), msgctl(), nice(), open(), prctl(), ptrace(),
|
|
||||||
reboot(), rename(), rmdir(), sched_setaffinity(),
|
|
||||||
sched_setattr(), sched_setparam(), sched_setscheduler(),
|
|
||||||
seteuid(), setfsgid(), setfsuid(), setgid(), setpgid(),
|
|
||||||
setresuid(), setreuid(), setsid(), setuid(), setup(), shmget(),
|
|
||||||
sigaltstack(), stime(), swapon(), symlink(), syslog(),
|
|
||||||
timer_create(), timerfd_create(), tkill(), truncate(), u
|
|
||||||
unlink(), utime(), utimensat(), vhangup(), vm86(), write().
|
|
||||||
|
|
||||||
- `ENOENT`: no such file or directory. Raised by access(),
|
- `ENOENT`: no such file or directory. Raised by access(),
|
||||||
alloc_hugepages(), bind(), chdir(), chmod(), chown(), chroot(),
|
alloc_hugepages(), bind(), chdir(), chmod(), chown(), chroot(),
|
||||||
clock_getres(), execve(), opendir(), inotify_add_watch(), kcmp(),
|
clock_getres(), execve(), opendir(), inotify_add_watch(), kcmp(),
|
||||||
|
@ -1692,6 +1734,28 @@ UNIX MODULE
|
||||||
rmdir(), semget(), send(), setpgid(), shmget(), socket(), stat(),
|
rmdir(), semget(), send(), setpgid(), shmget(), socket(), stat(),
|
||||||
symlink(), truncate(), unlink(), uselib(), utime(), utimensat(),
|
symlink(), truncate(), unlink(), uselib(), utime(), utimensat(),
|
||||||
|
|
||||||
|
- `EPERM`: Operation not permitted. Raised by accept(), chmod(),
|
||||||
|
chown(), chroot(), copy_file_range(), execve(), fallocate(),
|
||||||
|
fanotify_init(), fcntl(), futex(), get_robust_list(),
|
||||||
|
getdomainname(), getgroups(), gethostname(), getpriority(),
|
||||||
|
getrlimit(), getsid(), gettimeofday(), idle(), init_module(),
|
||||||
|
io_submit(), ioctl_console(), ioctl_ficlonerange(),
|
||||||
|
ioctl_fideduperange(), ioctl_ns(), ioctl_tty(), ioperm(), iopl(),
|
||||||
|
ioprio_set(), kcmp(), kexec_load(), keyctl(), kill(), link(),
|
||||||
|
lookup_dcookie(), madvise(), mbind(), membarrier(),
|
||||||
|
migrate_pages(), mkdir(), mknod(), mlock(), mmap(), mount(),
|
||||||
|
move_pages(), msgctl(), nice(), open(), open_by_handle_at(),
|
||||||
|
pciconfig_read(), perf_event_open(), pidfd_getfd(),
|
||||||
|
pidfd_send_signal(), pivot_root(), prctl(), process_vm_readv(),
|
||||||
|
ptrace(), quotactl(), reboot(), rename(), request_key(), rmdir(),
|
||||||
|
rt_sigqueueinfo(), sched_setaffinity(), sched_setattr(),
|
||||||
|
sched_setparam(), sched_setscheduler(), semctl(), seteuid(),
|
||||||
|
setfsgid(), setfsuid(), setgid(), setns(), setpgid(),
|
||||||
|
setresuid(), setreuid(), setsid(), setuid(), setup(), setxattr(),
|
||||||
|
shmctl(), shmget(), sigaltstack(), spu_create(), stime(),
|
||||||
|
swapon(), symlink(), syslog(), truncate(), unlink(), utime(),
|
||||||
|
utimensat(), write()
|
||||||
|
|
||||||
- `ENOTBLK`: Block device required. Raised by umount().
|
- `ENOTBLK`: Block device required. Raised by umount().
|
||||||
|
|
||||||
- `EBUSY`: Device or resource busy. Raised by bdflush(), dup(),
|
- `EBUSY`: Device or resource busy. Raised by bdflush(), dup(),
|
||||||
|
|
260
tool/net/lunix.c
260
tool/net/lunix.c
|
@ -37,6 +37,7 @@
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/sock/sock.h"
|
#include "libc/sock/sock.h"
|
||||||
|
#include "libc/sock/syslog.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/sysv/consts/af.h"
|
#include "libc/sysv/consts/af.h"
|
||||||
#include "libc/sysv/consts/at.h"
|
#include "libc/sysv/consts/at.h"
|
||||||
|
@ -46,6 +47,7 @@
|
||||||
#include "libc/sysv/consts/fd.h"
|
#include "libc/sysv/consts/fd.h"
|
||||||
#include "libc/sysv/consts/ipproto.h"
|
#include "libc/sysv/consts/ipproto.h"
|
||||||
#include "libc/sysv/consts/itimer.h"
|
#include "libc/sysv/consts/itimer.h"
|
||||||
|
#include "libc/sysv/consts/log.h"
|
||||||
#include "libc/sysv/consts/msg.h"
|
#include "libc/sysv/consts/msg.h"
|
||||||
#include "libc/sysv/consts/nr.h"
|
#include "libc/sysv/consts/nr.h"
|
||||||
#include "libc/sysv/consts/o.h"
|
#include "libc/sysv/consts/o.h"
|
||||||
|
@ -104,6 +106,16 @@ static int ReturnRc(lua_State *L, int64_t rc, int olderr) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ReturnErrno(lua_State *L, int nils, int olderr) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < nils; ++i) {
|
||||||
|
lua_pushnil(L);
|
||||||
|
}
|
||||||
|
lua_pushinteger(L, errno);
|
||||||
|
errno = olderr;
|
||||||
|
return nils + 1;
|
||||||
|
}
|
||||||
|
|
||||||
static char **ConvertLuaArrayToStringList(lua_State *L, int i) {
|
static char **ConvertLuaArrayToStringList(lua_State *L, int i) {
|
||||||
int j, n;
|
int j, n;
|
||||||
char **p;
|
char **p;
|
||||||
|
@ -133,13 +145,13 @@ static void FreeStringList(char **p) {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// System Calls
|
// System Calls
|
||||||
|
|
||||||
// unix.exit([exitcode]) → ⊥
|
// unix.exit([exitcode:int]) → ⊥
|
||||||
static wontreturn int LuaUnixExit(lua_State *L) {
|
static wontreturn int LuaUnixExit(lua_State *L) {
|
||||||
_Exit(luaL_optinteger(L, 1, 0));
|
_Exit(luaL_optinteger(L, 1, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.access(path, mode) → rc[, errno]
|
// unix.access(path:str, how:int) → rc:int[, errno:int]
|
||||||
// mode can be: R_OK, W_OK, X_OK, F_OK
|
// how can be: R_OK, W_OK, X_OK, F_OK
|
||||||
static int LuaUnixAccess(lua_State *L) {
|
static int LuaUnixAccess(lua_State *L) {
|
||||||
const char *file;
|
const char *file;
|
||||||
int rc, mode, olderr;
|
int rc, mode, olderr;
|
||||||
|
@ -150,19 +162,31 @@ static int LuaUnixAccess(lua_State *L) {
|
||||||
return ReturnRc(L, rc, olderr);
|
return ReturnRc(L, rc, olderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.mkdir(path, mode) → rc[, errno]
|
// unix.mkdir(path:str[, mode:int]) → rc:int[, errno:int]
|
||||||
// mode should be octal
|
// mode should be octal
|
||||||
static int LuaUnixMkdir(lua_State *L) {
|
static int LuaUnixMkdir(lua_State *L) {
|
||||||
const char *file;
|
const char *file;
|
||||||
int rc, mode, olderr;
|
int rc, mode, olderr;
|
||||||
olderr = errno;
|
olderr = errno;
|
||||||
file = luaL_checklstring(L, 1, 0);
|
file = luaL_checklstring(L, 1, 0);
|
||||||
mode = luaL_checkinteger(L, 2);
|
mode = luaL_optinteger(L, 2, 0755);
|
||||||
rc = mkdir(file, mode);
|
rc = mkdir(file, mode);
|
||||||
return ReturnRc(L, rc, olderr);
|
return ReturnRc(L, rc, olderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.chdir(path) → rc[, errno]
|
// unix.makedirs(path:str[, mode:int]) → rc:int[, errno:int]
|
||||||
|
// mode should be octal
|
||||||
|
static int LuaUnixMakedirs(lua_State *L) {
|
||||||
|
const char *file;
|
||||||
|
int rc, mode, olderr;
|
||||||
|
olderr = errno;
|
||||||
|
file = luaL_checklstring(L, 1, 0);
|
||||||
|
mode = luaL_optinteger(L, 2, 0755);
|
||||||
|
rc = makedirs(file, mode);
|
||||||
|
return ReturnRc(L, rc, olderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// unix.chdir(path:str) → rc:int[, errno:int]
|
||||||
static int LuaUnixChdir(lua_State *L) {
|
static int LuaUnixChdir(lua_State *L) {
|
||||||
int rc, olderr;
|
int rc, olderr;
|
||||||
const char *file;
|
const char *file;
|
||||||
|
@ -172,7 +196,7 @@ static int LuaUnixChdir(lua_State *L) {
|
||||||
return ReturnRc(L, rc, olderr);
|
return ReturnRc(L, rc, olderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.unlink(path) → rc[, errno]
|
// unix.unlink(path:str) → rc:int[, errno:int]
|
||||||
static int LuaUnixUnlink(lua_State *L) {
|
static int LuaUnixUnlink(lua_State *L) {
|
||||||
int rc, olderr;
|
int rc, olderr;
|
||||||
const char *file;
|
const char *file;
|
||||||
|
@ -182,7 +206,7 @@ static int LuaUnixUnlink(lua_State *L) {
|
||||||
return ReturnRc(L, rc, olderr);
|
return ReturnRc(L, rc, olderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.rmdir(path) → rc[, errno]
|
// unix.rmdir(path:str) → rc:int[, errno:int]
|
||||||
static int LuaUnixRmdir(lua_State *L) {
|
static int LuaUnixRmdir(lua_State *L) {
|
||||||
const char *file;
|
const char *file;
|
||||||
int rc, olderr;
|
int rc, olderr;
|
||||||
|
@ -192,7 +216,7 @@ static int LuaUnixRmdir(lua_State *L) {
|
||||||
return ReturnRc(L, rc, olderr);
|
return ReturnRc(L, rc, olderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.rename(oldpath, newpath) → rc[, errno]
|
// unix.rename(oldpath:str, newpath:str) → rc:int[, errno:int]
|
||||||
static int LuaUnixRename(lua_State *L) {
|
static int LuaUnixRename(lua_State *L) {
|
||||||
const char *oldpath, *newpath;
|
const char *oldpath, *newpath;
|
||||||
int rc, olderr;
|
int rc, olderr;
|
||||||
|
@ -203,7 +227,7 @@ static int LuaUnixRename(lua_State *L) {
|
||||||
return ReturnRc(L, rc, olderr);
|
return ReturnRc(L, rc, olderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.link(existingpath, newpath) → rc[, errno]
|
// unix.link(existingpath:str, newpath:str) → rc:int[, errno:int]
|
||||||
static int LuaUnixLink(lua_State *L) {
|
static int LuaUnixLink(lua_State *L) {
|
||||||
const char *existingpath, *newpath;
|
const char *existingpath, *newpath;
|
||||||
int rc, olderr;
|
int rc, olderr;
|
||||||
|
@ -214,7 +238,7 @@ static int LuaUnixLink(lua_State *L) {
|
||||||
return ReturnRc(L, rc, olderr);
|
return ReturnRc(L, rc, olderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.symlink(target, linkpath) → rc[, errno]
|
// unix.symlink(target:str, linkpath:str) → rc:int[, errno:int]
|
||||||
static int LuaUnixSymlink(lua_State *L) {
|
static int LuaUnixSymlink(lua_State *L) {
|
||||||
const char *target, *linkpath;
|
const char *target, *linkpath;
|
||||||
int rc, olderr;
|
int rc, olderr;
|
||||||
|
@ -225,7 +249,7 @@ static int LuaUnixSymlink(lua_State *L) {
|
||||||
return ReturnRc(L, rc, olderr);
|
return ReturnRc(L, rc, olderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.chown(path, uid, gid) → rc[, errno]
|
// unix.chown(path:str, uid:int, gid:int) → rc:int[, errno:int]
|
||||||
static int LuaUnixChown(lua_State *L) {
|
static int LuaUnixChown(lua_State *L) {
|
||||||
const char *file;
|
const char *file;
|
||||||
int rc, uid, gid, olderr;
|
int rc, uid, gid, olderr;
|
||||||
|
@ -237,7 +261,7 @@ static int LuaUnixChown(lua_State *L) {
|
||||||
return ReturnRc(L, rc, olderr);
|
return ReturnRc(L, rc, olderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.chmod(path, mode) → rc[, errno]
|
// unix.chmod(path:str, mode:int) → rc:int[, errno:int]
|
||||||
static int LuaUnixChmod(lua_State *L) {
|
static int LuaUnixChmod(lua_State *L) {
|
||||||
const char *file;
|
const char *file;
|
||||||
int rc, mode, olderr;
|
int rc, mode, olderr;
|
||||||
|
@ -248,7 +272,7 @@ static int LuaUnixChmod(lua_State *L) {
|
||||||
return ReturnRc(L, rc, olderr);
|
return ReturnRc(L, rc, olderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.getcwd(path, mode) → rc[, errno]
|
// unix.getcwd(path:str, mode:int) → rc:int[, errno:int]
|
||||||
static int LuaUnixGetcwd(lua_State *L) {
|
static int LuaUnixGetcwd(lua_State *L) {
|
||||||
char *path;
|
char *path;
|
||||||
path = getcwd(0, 0);
|
path = getcwd(0, 0);
|
||||||
|
@ -258,7 +282,7 @@ static int LuaUnixGetcwd(lua_State *L) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.fork() → childpid|0, errno
|
// unix.fork() → childpid|0:int[, errno:int]
|
||||||
static int LuaUnixFork(lua_State *L) {
|
static int LuaUnixFork(lua_State *L) {
|
||||||
int rc, olderr;
|
int rc, olderr;
|
||||||
olderr = errno;
|
olderr = errno;
|
||||||
|
@ -298,7 +322,7 @@ static int LuaUnixExecve(lua_State *L) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.commandv(prog) → path[, errno]
|
// unix.commandv(prog:str) → path:str[, errno:int]
|
||||||
static int LuaUnixCommandv(lua_State *L) {
|
static int LuaUnixCommandv(lua_State *L) {
|
||||||
const char *prog;
|
const char *prog;
|
||||||
int rc, olderr, pushed;
|
int rc, olderr, pushed;
|
||||||
|
@ -319,7 +343,29 @@ static int LuaUnixCommandv(lua_State *L) {
|
||||||
return pushed;
|
return pushed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.chroot(path) → rc[, errno]
|
// unix.realpath(path:str) → path:str[, errno:int]
|
||||||
|
static int LuaUnixRealpath(lua_State *L) {
|
||||||
|
char *resolved;
|
||||||
|
int rc, olderr;
|
||||||
|
const char *path;
|
||||||
|
olderr = errno;
|
||||||
|
path = luaL_checkstring(L, 1);
|
||||||
|
if ((resolved = realpath(path, 0))) {
|
||||||
|
lua_pushstring(L, resolved);
|
||||||
|
free(resolved);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return ReturnErrno(L, 1, olderr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// unix.syslog(priority:str, msg:str)
|
||||||
|
static int LuaUnixSyslog(lua_State *L) {
|
||||||
|
syslog(luaL_checkinteger(L, 1), "%s", luaL_checkstring(L, 2));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// unix.chroot(path:str) → rc:int[, errno:int]
|
||||||
static int LuaUnixChroot(lua_State *L) {
|
static int LuaUnixChroot(lua_State *L) {
|
||||||
int rc, olderr;
|
int rc, olderr;
|
||||||
const char *path;
|
const char *path;
|
||||||
|
@ -351,27 +397,23 @@ static int LuaUnixGetrlimit(lua_State *L) {
|
||||||
lua_pushinteger(L, rlim.rlim_max);
|
lua_pushinteger(L, rlim.rlim_max);
|
||||||
return 2;
|
return 2;
|
||||||
} else {
|
} else {
|
||||||
lua_pushnil(L);
|
return ReturnErrno(L, 2, olderr);
|
||||||
lua_pushnil(L);
|
|
||||||
lua_pushinteger(L, errno);
|
|
||||||
errno = olderr;
|
|
||||||
return 3;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.getpid() → pid
|
// unix.getpid() → pid:int
|
||||||
static int LuaUnixGetpid(lua_State *L) {
|
static int LuaUnixGetpid(lua_State *L) {
|
||||||
lua_pushinteger(L, getpid());
|
lua_pushinteger(L, getpid());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.getppid() → pid
|
// unix.getppid() → pid:int
|
||||||
static int LuaUnixGetppid(lua_State *L) {
|
static int LuaUnixGetppid(lua_State *L) {
|
||||||
lua_pushinteger(L, getppid());
|
lua_pushinteger(L, getppid());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.kill(pid, sig) → rc[, errno]
|
// unix.kill(pid, sig) → rc:int[, errno:int]
|
||||||
static int LuaUnixKill(lua_State *L) {
|
static int LuaUnixKill(lua_State *L) {
|
||||||
int rc, pid, sig, olderr;
|
int rc, pid, sig, olderr;
|
||||||
olderr = errno;
|
olderr = errno;
|
||||||
|
@ -381,7 +423,7 @@ static int LuaUnixKill(lua_State *L) {
|
||||||
return ReturnRc(L, rc, olderr);
|
return ReturnRc(L, rc, olderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.raise(sig) → rc[, errno]
|
// unix.raise(sig) → rc:int[, errno:int]
|
||||||
static int LuaUnixRaise(lua_State *L) {
|
static int LuaUnixRaise(lua_State *L) {
|
||||||
int rc, sig, olderr;
|
int rc, sig, olderr;
|
||||||
olderr = errno;
|
olderr = errno;
|
||||||
|
@ -402,16 +444,11 @@ static int LuaUnixWait(lua_State *L) {
|
||||||
lua_pushinteger(L, wstatus);
|
lua_pushinteger(L, wstatus);
|
||||||
return 2;
|
return 2;
|
||||||
} else {
|
} else {
|
||||||
lua_pushnil(L);
|
return ReturnErrno(L, 3, olderr);
|
||||||
lua_pushnil(L);
|
|
||||||
lua_pushnil(L); // for future use
|
|
||||||
lua_pushinteger(L, errno);
|
|
||||||
errno = olderr;
|
|
||||||
return 4;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.fcntl(fd, cmd[, arg]) → rc[, errno]
|
// unix.fcntl(fd, cmd[, arg]) → rc:int[, errno:int]
|
||||||
static int LuaUnixFcntl(lua_State *L) {
|
static int LuaUnixFcntl(lua_State *L) {
|
||||||
intptr_t arg;
|
intptr_t arg;
|
||||||
int rc, fd, cmd, olderr;
|
int rc, fd, cmd, olderr;
|
||||||
|
@ -450,15 +487,11 @@ static int LuaUnixPipe(lua_State *L) {
|
||||||
lua_pushinteger(L, pipefd[1]);
|
lua_pushinteger(L, pipefd[1]);
|
||||||
return 2;
|
return 2;
|
||||||
} else {
|
} else {
|
||||||
lua_pushnil(L);
|
return ReturnErrno(L, 2, olderr);
|
||||||
lua_pushnil(L);
|
|
||||||
lua_pushinteger(L, errno);
|
|
||||||
errno = olderr;
|
|
||||||
return 3;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.getsid(pid) → sid, errno
|
// unix.getsid(pid) → sid:int[, errno:int]
|
||||||
static int LuaUnixGetsid(lua_State *L) {
|
static int LuaUnixGetsid(lua_State *L) {
|
||||||
int rc, pid, olderr;
|
int rc, pid, olderr;
|
||||||
olderr = errno;
|
olderr = errno;
|
||||||
|
@ -467,7 +500,7 @@ static int LuaUnixGetsid(lua_State *L) {
|
||||||
return ReturnRc(L, rc, olderr);
|
return ReturnRc(L, rc, olderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.getpgrp() → pgid, errno
|
// unix.getpgrp() → pgid:int[, errno:int]
|
||||||
static int LuaUnixGetpgrp(lua_State *L) {
|
static int LuaUnixGetpgrp(lua_State *L) {
|
||||||
int rc, olderr;
|
int rc, olderr;
|
||||||
olderr = errno;
|
olderr = errno;
|
||||||
|
@ -475,7 +508,7 @@ static int LuaUnixGetpgrp(lua_State *L) {
|
||||||
return ReturnRc(L, rc, olderr);
|
return ReturnRc(L, rc, olderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.getpgid(pid) → pgid, errno
|
// unix.getpgid(pid:int) → pgid:int[, errno:int]
|
||||||
static int LuaUnixGetpgid(lua_State *L) {
|
static int LuaUnixGetpgid(lua_State *L) {
|
||||||
int rc, pid, olderr;
|
int rc, pid, olderr;
|
||||||
olderr = errno;
|
olderr = errno;
|
||||||
|
@ -484,7 +517,7 @@ static int LuaUnixGetpgid(lua_State *L) {
|
||||||
return ReturnRc(L, rc, olderr);
|
return ReturnRc(L, rc, olderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.umask(mask) → rc[, errno]
|
// unix.umask(mask:int) → rc:int[, errno:int]
|
||||||
static int LuaUnixUmask(lua_State *L) {
|
static int LuaUnixUmask(lua_State *L) {
|
||||||
int rc, mask, olderr;
|
int rc, mask, olderr;
|
||||||
olderr = errno;
|
olderr = errno;
|
||||||
|
@ -493,7 +526,7 @@ static int LuaUnixUmask(lua_State *L) {
|
||||||
return ReturnRc(L, rc, olderr);
|
return ReturnRc(L, rc, olderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.setpgid(pid, pgid) → pgid, errno
|
// unix.setpgid(pid:int, pgid:int) → pgid:int[, errno:int]
|
||||||
static int LuaUnixSetpgid(lua_State *L) {
|
static int LuaUnixSetpgid(lua_State *L) {
|
||||||
int rc, pid, pgid, olderr;
|
int rc, pid, pgid, olderr;
|
||||||
olderr = errno;
|
olderr = errno;
|
||||||
|
@ -503,7 +536,7 @@ static int LuaUnixSetpgid(lua_State *L) {
|
||||||
return ReturnRc(L, rc, olderr);
|
return ReturnRc(L, rc, olderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.setsid() → sid, errno
|
// unix.setsid() → sid:int[, errno:int]
|
||||||
static int LuaUnixSetsid(lua_State *L) {
|
static int LuaUnixSetsid(lua_State *L) {
|
||||||
int rc, olderr;
|
int rc, olderr;
|
||||||
olderr = errno;
|
olderr = errno;
|
||||||
|
@ -511,7 +544,7 @@ static int LuaUnixSetsid(lua_State *L) {
|
||||||
return ReturnRc(L, rc, olderr);
|
return ReturnRc(L, rc, olderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.getuid() → uid, errno
|
// unix.getuid() → uid[, errno]
|
||||||
static int LuaUnixGetuid(lua_State *L) {
|
static int LuaUnixGetuid(lua_State *L) {
|
||||||
int rc, olderr;
|
int rc, olderr;
|
||||||
olderr = errno;
|
olderr = errno;
|
||||||
|
@ -519,7 +552,13 @@ static int LuaUnixGetuid(lua_State *L) {
|
||||||
return ReturnRc(L, rc, olderr);
|
return ReturnRc(L, rc, olderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.getgid() → gid, errno
|
// unix.setuid(uid:int) → rc:int[, errno:int]
|
||||||
|
static int LuaUnixSetuid(lua_State *L) {
|
||||||
|
int olderr = errno;
|
||||||
|
return ReturnRc(L, setuid(luaL_checkinteger(L, 1)), olderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// unix.getgid() → gid:int[, errno:int]
|
||||||
static int LuaUnixGetgid(lua_State *L) {
|
static int LuaUnixGetgid(lua_State *L) {
|
||||||
int rc, olderr;
|
int rc, olderr;
|
||||||
olderr = errno;
|
olderr = errno;
|
||||||
|
@ -527,7 +566,13 @@ static int LuaUnixGetgid(lua_State *L) {
|
||||||
return ReturnRc(L, rc, olderr);
|
return ReturnRc(L, rc, olderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.gettime([clock]) → seconds, nanos, errno
|
// unix.setgid(gid:int) → rc:int[, errno:int]
|
||||||
|
static int LuaUnixSetgid(lua_State *L) {
|
||||||
|
int olderr = errno;
|
||||||
|
return ReturnRc(L, setgid(luaL_checkinteger(L, 1)), olderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// unix.clock_gettime([clock]) → seconds, nanos, errno
|
||||||
static int LuaUnixGettime(lua_State *L) {
|
static int LuaUnixGettime(lua_State *L) {
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
int rc, clock, olderr;
|
int rc, clock, olderr;
|
||||||
|
@ -539,11 +584,7 @@ static int LuaUnixGettime(lua_State *L) {
|
||||||
lua_pushinteger(L, ts.tv_nsec);
|
lua_pushinteger(L, ts.tv_nsec);
|
||||||
return 2;
|
return 2;
|
||||||
} else {
|
} else {
|
||||||
lua_pushnil(L);
|
return ReturnErrno(L, 2, olderr);
|
||||||
lua_pushnil(L);
|
|
||||||
lua_pushinteger(L, errno);
|
|
||||||
errno = olderr;
|
|
||||||
return 3;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -560,21 +601,17 @@ static int LuaUnixNanosleep(lua_State *L) {
|
||||||
lua_pushinteger(L, rem.tv_nsec);
|
lua_pushinteger(L, rem.tv_nsec);
|
||||||
return 2;
|
return 2;
|
||||||
} else {
|
} else {
|
||||||
lua_pushnil(L);
|
return ReturnErrno(L, 2, olderr);
|
||||||
lua_pushnil(L);
|
|
||||||
lua_pushinteger(L, errno);
|
|
||||||
errno = olderr;
|
|
||||||
return 3;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.sync(fd)
|
// unix.sync(fd:int)
|
||||||
static int LuaUnixSync(lua_State *L) {
|
static int LuaUnixSync(lua_State *L) {
|
||||||
sync();
|
sync();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.fsync(fd) → rc[, errno]
|
// unix.fsync(fd:int) → rc:int[, errno:int]
|
||||||
static int LuaUnixFsync(lua_State *L) {
|
static int LuaUnixFsync(lua_State *L) {
|
||||||
int rc, fd, olderr;
|
int rc, fd, olderr;
|
||||||
olderr = errno;
|
olderr = errno;
|
||||||
|
@ -583,7 +620,7 @@ static int LuaUnixFsync(lua_State *L) {
|
||||||
return ReturnRc(L, rc, olderr);
|
return ReturnRc(L, rc, olderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.fdatasync(fd) → rc[, errno]
|
// unix.fdatasync(fd:int) → rc:int[, errno:int]
|
||||||
static int LuaUnixFdatasync(lua_State *L) {
|
static int LuaUnixFdatasync(lua_State *L) {
|
||||||
int rc, fd, olderr;
|
int rc, fd, olderr;
|
||||||
olderr = errno;
|
olderr = errno;
|
||||||
|
@ -604,7 +641,7 @@ static int LuaUnixOpen(lua_State *L) {
|
||||||
return ReturnRc(L, rc, olderr);
|
return ReturnRc(L, rc, olderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.close(fd) → rc[, errno]
|
// unix.close(fd:int) → rc:int[, errno:int]
|
||||||
static int LuaUnixClose(lua_State *L) {
|
static int LuaUnixClose(lua_State *L) {
|
||||||
int rc, fd, olderr;
|
int rc, fd, olderr;
|
||||||
olderr = errno;
|
olderr = errno;
|
||||||
|
@ -627,8 +664,8 @@ static int LuaUnixSeek(lua_State *L) {
|
||||||
return ReturnRc(L, newpos, olderr);
|
return ReturnRc(L, newpos, olderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.truncate(path, length) → rc[, errno]
|
// unix.truncate(path, length) → rc:int[, errno:int]
|
||||||
// unix.truncate(fd, length) → rc[, errno]
|
// unix.truncate(fd, length) → rc:int[, errno:int]
|
||||||
static int LuaUnixTruncate(lua_State *L) {
|
static int LuaUnixTruncate(lua_State *L) {
|
||||||
int64_t length;
|
int64_t length;
|
||||||
const char *path;
|
const char *path;
|
||||||
|
@ -649,7 +686,7 @@ static int LuaUnixTruncate(lua_State *L) {
|
||||||
return ReturnRc(L, rc, olderr);
|
return ReturnRc(L, rc, olderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.read(fd[, bufsiz, offset]) → data, errno
|
// unix.read(fd:int[, bufsiz:str, offset:int]) → data:str, errno:int
|
||||||
static int LuaUnixRead(lua_State *L) {
|
static int LuaUnixRead(lua_State *L) {
|
||||||
char *buf;
|
char *buf;
|
||||||
size_t got;
|
size_t got;
|
||||||
|
@ -680,7 +717,7 @@ static int LuaUnixRead(lua_State *L) {
|
||||||
return pushed;
|
return pushed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.write(fd, data[, offset]) → rc[, errno]
|
// unix.write(fd:int, data:str[, offset:int]) → rc:int[, errno:int]
|
||||||
static int LuaUnixWrite(lua_State *L) {
|
static int LuaUnixWrite(lua_State *L) {
|
||||||
size_t size;
|
size_t size;
|
||||||
int fd, olderr;
|
int fd, olderr;
|
||||||
|
@ -699,8 +736,8 @@ static int LuaUnixWrite(lua_State *L) {
|
||||||
return ReturnRc(L, rc, olderr);
|
return ReturnRc(L, rc, olderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.stat(path) → UnixStat*[, errno]
|
// unix.stat(path:str) → UnixStat*[, errno]
|
||||||
// unix.stat(fd) → UnixStat*[, errno]
|
// unix.stat(fd:int) → UnixStat*[, errno]
|
||||||
static int LuaUnixStat(lua_State *L) {
|
static int LuaUnixStat(lua_State *L) {
|
||||||
const char *path;
|
const char *path;
|
||||||
int rc, fd, olderr;
|
int rc, fd, olderr;
|
||||||
|
@ -731,8 +768,8 @@ static int LuaUnixStat(lua_State *L) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.opendir(path) → UnixDir*[, errno]
|
// unix.opendir(path:str) → UnixDir*[, errno]
|
||||||
// unix.opendir(fd) → UnixDir*[, errno]
|
// unix.opendir(fd:int) → UnixDir*[, errno]
|
||||||
static int LuaUnixOpendir(lua_State *L) {
|
static int LuaUnixOpendir(lua_State *L) {
|
||||||
DIR *rc;
|
DIR *rc;
|
||||||
int fd, olderr;
|
int fd, olderr;
|
||||||
|
@ -797,15 +834,11 @@ static int LuaUnixSocketpair(lua_State *L) {
|
||||||
lua_pushinteger(L, sv[1]);
|
lua_pushinteger(L, sv[1]);
|
||||||
return 2;
|
return 2;
|
||||||
} else {
|
} else {
|
||||||
lua_pushnil(L);
|
return ReturnErrno(L, 2, olderr);
|
||||||
lua_pushnil(L);
|
|
||||||
lua_pushinteger(L, errno);
|
|
||||||
errno = olderr;
|
|
||||||
return 3;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.bind(fd, ip, port) → rc[, errno]
|
// unix.bind(fd, ip, port) → rc:int[, errno:int]
|
||||||
// SOCK_CLOEXEC may be or'd into type
|
// SOCK_CLOEXEC may be or'd into type
|
||||||
// family defaults to AF_INET
|
// family defaults to AF_INET
|
||||||
// type defaults to SOCK_STREAM
|
// type defaults to SOCK_STREAM
|
||||||
|
@ -822,7 +855,7 @@ static int LuaUnixBind(lua_State *L) {
|
||||||
return ReturnRc(L, rc, olderr);
|
return ReturnRc(L, rc, olderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.connect(fd, ip, port) → rc[, errno]
|
// unix.connect(fd, ip, port) → rc:int[, errno:int]
|
||||||
// SOCK_CLOEXEC may be or'd into type
|
// SOCK_CLOEXEC may be or'd into type
|
||||||
// family defaults to AF_INET
|
// family defaults to AF_INET
|
||||||
// type defaults to SOCK_STREAM
|
// type defaults to SOCK_STREAM
|
||||||
|
@ -839,7 +872,7 @@ static int LuaUnixConnect(lua_State *L) {
|
||||||
return ReturnRc(L, rc, olderr);
|
return ReturnRc(L, rc, olderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.listen(fd[, backlog]) → rc[, errno]
|
// unix.listen(fd[, backlog]) → rc:int[, errno:int]
|
||||||
static int LuaUnixListen(lua_State *L) {
|
static int LuaUnixListen(lua_State *L) {
|
||||||
int rc, fd, olderr, backlog;
|
int rc, fd, olderr, backlog;
|
||||||
olderr = errno;
|
olderr = errno;
|
||||||
|
@ -863,11 +896,7 @@ static int LuaUnixGetsockname(lua_State *L) {
|
||||||
lua_pushinteger(L, ntohs(sa.sin_port));
|
lua_pushinteger(L, ntohs(sa.sin_port));
|
||||||
return 2;
|
return 2;
|
||||||
} else {
|
} else {
|
||||||
lua_pushnil(L);
|
return ReturnErrno(L, 2, olderr);
|
||||||
lua_pushnil(L);
|
|
||||||
lua_pushinteger(L, errno);
|
|
||||||
errno = olderr;
|
|
||||||
return 3;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -885,11 +914,7 @@ static int LuaUnixGetpeername(lua_State *L) {
|
||||||
lua_pushinteger(L, ntohs(sa.sin_port));
|
lua_pushinteger(L, ntohs(sa.sin_port));
|
||||||
return 2;
|
return 2;
|
||||||
} else {
|
} else {
|
||||||
lua_pushnil(L);
|
return ReturnErrno(L, 2, olderr);
|
||||||
lua_pushnil(L);
|
|
||||||
lua_pushinteger(L, errno);
|
|
||||||
errno = olderr;
|
|
||||||
return 3;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -909,12 +934,7 @@ static int LuaUnixAccept(lua_State *L) {
|
||||||
lua_pushinteger(L, ntohs(sa.sin_port));
|
lua_pushinteger(L, ntohs(sa.sin_port));
|
||||||
return 3;
|
return 3;
|
||||||
} else {
|
} else {
|
||||||
lua_pushnil(L);
|
return ReturnErrno(L, 3, olderr);
|
||||||
lua_pushnil(L);
|
|
||||||
lua_pushnil(L);
|
|
||||||
lua_pushinteger(L, errno);
|
|
||||||
errno = olderr;
|
|
||||||
return 4;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1016,7 +1036,7 @@ static int LuaUnixSendto(lua_State *L) {
|
||||||
return ReturnRc(L, rc, olderr);
|
return ReturnRc(L, rc, olderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unix.shutdown(fd, how) → rc[, errno]
|
// unix.shutdown(fd, how) → rc:int[, errno:int]
|
||||||
// how can be SHUT_RD, SHUT_WR, or SHUT_RDWR
|
// how can be SHUT_RD, SHUT_WR, or SHUT_RDWR
|
||||||
static int LuaUnixShutdown(lua_State *L) {
|
static int LuaUnixShutdown(lua_State *L) {
|
||||||
int rc, fd, how, olderr;
|
int rc, fd, how, olderr;
|
||||||
|
@ -1149,12 +1169,7 @@ static int LuaUnixSigaction(lua_State *L) {
|
||||||
lua_pushinteger(L, oldsa.sa_mask.__bits[0]);
|
lua_pushinteger(L, oldsa.sa_mask.__bits[0]);
|
||||||
return 3;
|
return 3;
|
||||||
} else {
|
} else {
|
||||||
lua_pushnil(L);
|
return ReturnErrno(L, 3, olderr);
|
||||||
lua_pushnil(L);
|
|
||||||
lua_pushnil(L);
|
|
||||||
lua_pushinteger(L, errno);
|
|
||||||
errno = olderr;
|
|
||||||
return 4;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1206,13 +1221,7 @@ static int LuaUnixSetitimer(lua_State *L) {
|
||||||
lua_pushinteger(L, oldit.it_value.tv_usec);
|
lua_pushinteger(L, oldit.it_value.tv_usec);
|
||||||
return 4;
|
return 4;
|
||||||
} else {
|
} else {
|
||||||
lua_pushnil(L);
|
return ReturnErrno(L, 4, olderr);
|
||||||
lua_pushnil(L);
|
|
||||||
lua_pushnil(L);
|
|
||||||
lua_pushnil(L);
|
|
||||||
lua_pushinteger(L, errno);
|
|
||||||
errno = olderr;
|
|
||||||
return 5;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1362,7 +1371,7 @@ static int FreeUnixDir(struct UnixDir *dir) {
|
||||||
return closedir(dir->dir);
|
return closedir(dir->dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnixDir:close() → rc[, errno]
|
// UnixDir:close() → rc:int[, errno:int]
|
||||||
// may be called multiple times
|
// may be called multiple times
|
||||||
// called by the garbage collector too
|
// called by the garbage collector too
|
||||||
static int LuaUnixDirClose(lua_State *L) {
|
static int LuaUnixDirClose(lua_State *L) {
|
||||||
|
@ -1393,13 +1402,7 @@ static int LuaUnixDirRead(lua_State *L) {
|
||||||
} else if (!ent && !errno) {
|
} else if (!ent && !errno) {
|
||||||
return 0; // end of listing
|
return 0; // end of listing
|
||||||
} else {
|
} else {
|
||||||
lua_pushnil(L);
|
return ReturnErrno(L, 4, olderr);
|
||||||
lua_pushnil(L);
|
|
||||||
lua_pushnil(L);
|
|
||||||
lua_pushnil(L);
|
|
||||||
lua_pushinteger(L, errno);
|
|
||||||
errno = olderr;
|
|
||||||
return 5;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1414,10 +1417,7 @@ static int LuaUnixDirFd(lua_State *L) {
|
||||||
lua_pushinteger(L, fd);
|
lua_pushinteger(L, fd);
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
lua_pushnil(L);
|
return ReturnErrno(L, 1, olderr);
|
||||||
lua_pushinteger(L, errno);
|
|
||||||
errno = olderr;
|
|
||||||
return 2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1478,12 +1478,15 @@ static const luaL_Reg kLuaUnix[] = {
|
||||||
{"fork", LuaUnixFork}, // make child process via mitosis
|
{"fork", LuaUnixFork}, // make child process via mitosis
|
||||||
{"execve", LuaUnixExecve}, // replace process with program
|
{"execve", LuaUnixExecve}, // replace process with program
|
||||||
{"commandv", LuaUnixCommandv}, // resolve program on $PATH
|
{"commandv", LuaUnixCommandv}, // resolve program on $PATH
|
||||||
|
{"realpath", LuaUnixRealpath}, // abspath without dots/symlinks
|
||||||
|
{"syslog", LuaUnixSyslog}, // logs to system log
|
||||||
{"kill", LuaUnixKill}, // signal child process
|
{"kill", LuaUnixKill}, // signal child process
|
||||||
{"raise", LuaUnixRaise}, // signal this process
|
{"raise", LuaUnixRaise}, // signal this process
|
||||||
{"wait", LuaUnixWait}, // wait for child to change status
|
{"wait", LuaUnixWait}, // wait for child to change status
|
||||||
{"pipe", LuaUnixPipe}, // create two anon fifo fds
|
{"pipe", LuaUnixPipe}, // create two anon fifo fds
|
||||||
{"dup", LuaUnixDup}, // copy fd to lowest empty slot
|
{"dup", LuaUnixDup}, // copy fd to lowest empty slot
|
||||||
{"mkdir", LuaUnixMkdir}, // make directory
|
{"mkdir", LuaUnixMkdir}, // make directory
|
||||||
|
{"makedirs", LuaUnixMakedirs}, // make directory and parents too
|
||||||
{"rmdir", LuaUnixRmdir}, // remove empty directory
|
{"rmdir", LuaUnixRmdir}, // remove empty directory
|
||||||
{"opendir", LuaUnixOpendir}, // read directory entry list
|
{"opendir", LuaUnixOpendir}, // read directory entry list
|
||||||
{"rename", LuaUnixRename}, // rename file or directory
|
{"rename", LuaUnixRename}, // rename file or directory
|
||||||
|
@ -1494,8 +1497,9 @@ static const luaL_Reg kLuaUnix[] = {
|
||||||
{"fsync", LuaUnixFsync}, // flush open file
|
{"fsync", LuaUnixFsync}, // flush open file
|
||||||
{"fdatasync", LuaUnixFdatasync}, // flush open file w/o metadata
|
{"fdatasync", LuaUnixFdatasync}, // flush open file w/o metadata
|
||||||
{"truncate", LuaUnixTruncate}, // shrink or extend file medium
|
{"truncate", LuaUnixTruncate}, // shrink or extend file medium
|
||||||
{"umask", LuaUnixChroot}, // change root directory
|
{"ftruncate", LuaUnixTruncate}, // shrink or extend file medium
|
||||||
{"chroot", LuaUnixGetppid}, // get parent process id
|
{"umask", LuaUnixUmask}, // change root directory
|
||||||
|
{"chroot", LuaUnixChroot}, // get parent process id
|
||||||
{"setrlimit", LuaUnixSetrlimit}, // prevent cpu memory bombs
|
{"setrlimit", LuaUnixSetrlimit}, // prevent cpu memory bombs
|
||||||
{"getrlimit", LuaUnixGetrlimit}, // query resource limits
|
{"getrlimit", LuaUnixGetrlimit}, // query resource limits
|
||||||
{"getppid", LuaUnixGetppid}, // get parent process id
|
{"getppid", LuaUnixGetppid}, // get parent process id
|
||||||
|
@ -1506,8 +1510,10 @@ static const luaL_Reg kLuaUnix[] = {
|
||||||
{"setsid", LuaUnixSetsid}, // create a new session id
|
{"setsid", LuaUnixSetsid}, // create a new session id
|
||||||
{"getpid", LuaUnixGetpid}, // get id of this process
|
{"getpid", LuaUnixGetpid}, // get id of this process
|
||||||
{"getuid", LuaUnixGetuid}, // get real user id of process
|
{"getuid", LuaUnixGetuid}, // get real user id of process
|
||||||
|
{"setuid", LuaUnixSetuid}, // set real user id of process
|
||||||
{"getgid", LuaUnixGetgid}, // get real group id of process
|
{"getgid", LuaUnixGetgid}, // get real group id of process
|
||||||
{"gettime", LuaUnixGettime}, // get timestamp w/ nano precision
|
{"setgid", LuaUnixSetgid}, // set real group id of process
|
||||||
|
{"clock_gettime", LuaUnixGettime}, // get timestamp w/ nano precision
|
||||||
{"nanosleep", LuaUnixNanosleep}, // sleep w/ nano precision
|
{"nanosleep", LuaUnixNanosleep}, // sleep w/ nano precision
|
||||||
{"socket", LuaUnixSocket}, // create network communication fd
|
{"socket", LuaUnixSocket}, // create network communication fd
|
||||||
{"socketpair", LuaUnixSocketpair}, // create bidirectional pipe
|
{"socketpair", LuaUnixSocketpair}, // create bidirectional pipe
|
||||||
|
@ -1685,5 +1691,15 @@ int LuaUnix(lua_State *L) {
|
||||||
LuaSetIntField(L, "ITIMER_PROF", ITIMER_PROF);
|
LuaSetIntField(L, "ITIMER_PROF", ITIMER_PROF);
|
||||||
LuaSetIntField(L, "ITIMER_VIRTUAL", ITIMER_VIRTUAL);
|
LuaSetIntField(L, "ITIMER_VIRTUAL", ITIMER_VIRTUAL);
|
||||||
|
|
||||||
|
// syslog() stuff
|
||||||
|
LuaSetIntField(L, "LOG_EMERG", LOG_EMERG);
|
||||||
|
LuaSetIntField(L, "LOG_ALERT", LOG_ALERT);
|
||||||
|
LuaSetIntField(L, "LOG_CRIT", LOG_CRIT);
|
||||||
|
LuaSetIntField(L, "LOG_ERR", LOG_ERR);
|
||||||
|
LuaSetIntField(L, "LOG_WARNING", LOG_WARNING);
|
||||||
|
LuaSetIntField(L, "LOG_NOTICE", LOG_NOTICE);
|
||||||
|
LuaSetIntField(L, "LOG_INFO", LOG_INFO);
|
||||||
|
LuaSetIntField(L, "LOG_DEBUG", LOG_DEBUG);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,11 +22,11 @@
|
||||||
#include "libc/bits/popcnt.h"
|
#include "libc/bits/popcnt.h"
|
||||||
#include "libc/bits/safemacros.internal.h"
|
#include "libc/bits/safemacros.internal.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/issandboxed.h"
|
|
||||||
#include "libc/calls/math.h"
|
#include "libc/calls/math.h"
|
||||||
#include "libc/calls/sigbits.h"
|
#include "libc/calls/sigbits.h"
|
||||||
#include "libc/calls/strace.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/dirent.h"
|
#include "libc/calls/struct/dirent.h"
|
||||||
|
#include "libc/calls/struct/filter.h"
|
||||||
#include "libc/calls/struct/flock.h"
|
#include "libc/calls/struct/flock.h"
|
||||||
#include "libc/calls/struct/rusage.h"
|
#include "libc/calls/struct/rusage.h"
|
||||||
#include "libc/calls/struct/sigaction.h"
|
#include "libc/calls/struct/sigaction.h"
|
||||||
|
@ -71,6 +71,7 @@
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/str/undeflate.h"
|
#include "libc/str/undeflate.h"
|
||||||
#include "libc/sysv/consts/af.h"
|
#include "libc/sysv/consts/af.h"
|
||||||
|
#include "libc/sysv/consts/audit.h"
|
||||||
#include "libc/sysv/consts/auxv.h"
|
#include "libc/sysv/consts/auxv.h"
|
||||||
#include "libc/sysv/consts/dt.h"
|
#include "libc/sysv/consts/dt.h"
|
||||||
#include "libc/sysv/consts/ex.h"
|
#include "libc/sysv/consts/ex.h"
|
||||||
|
@ -90,7 +91,6 @@
|
||||||
#include "libc/sysv/consts/prot.h"
|
#include "libc/sysv/consts/prot.h"
|
||||||
#include "libc/sysv/consts/rusage.h"
|
#include "libc/sysv/consts/rusage.h"
|
||||||
#include "libc/sysv/consts/s.h"
|
#include "libc/sysv/consts/s.h"
|
||||||
#include "libc/sysv/consts/seccomp.h"
|
|
||||||
#include "libc/sysv/consts/shut.h"
|
#include "libc/sysv/consts/shut.h"
|
||||||
#include "libc/sysv/consts/sig.h"
|
#include "libc/sysv/consts/sig.h"
|
||||||
#include "libc/sysv/consts/so.h"
|
#include "libc/sysv/consts/so.h"
|
||||||
|
@ -144,6 +144,7 @@
|
||||||
#include "tool/build/lib/case.h"
|
#include "tool/build/lib/case.h"
|
||||||
#include "tool/build/lib/psk.h"
|
#include "tool/build/lib/psk.h"
|
||||||
#include "tool/net/luacheck.h"
|
#include "tool/net/luacheck.h"
|
||||||
|
#include "tool/net/sandbox.h"
|
||||||
|
|
||||||
STATIC_STACK_SIZE(0x40000);
|
STATIC_STACK_SIZE(0x40000);
|
||||||
STATIC_YOINK("zip_uri_support");
|
STATIC_YOINK("zip_uri_support");
|
||||||
|
@ -367,7 +368,6 @@ static bool terminated;
|
||||||
static bool uniprocess;
|
static bool uniprocess;
|
||||||
static bool invalidated;
|
static bool invalidated;
|
||||||
static bool logmessages;
|
static bool logmessages;
|
||||||
static bool issandboxed;
|
|
||||||
static bool isinitialized;
|
static bool isinitialized;
|
||||||
static bool checkedmethod;
|
static bool checkedmethod;
|
||||||
static bool sslinitialized;
|
static bool sslinitialized;
|
||||||
|
@ -393,6 +393,7 @@ static int zfd;
|
||||||
static int frags;
|
static int frags;
|
||||||
static int gmtoff;
|
static int gmtoff;
|
||||||
static int client;
|
static int client;
|
||||||
|
static int sandboxed;
|
||||||
static int changeuid;
|
static int changeuid;
|
||||||
static int changegid;
|
static int changegid;
|
||||||
static int isyielding;
|
static int isyielding;
|
||||||
|
@ -1168,10 +1169,10 @@ static void ReportWorkerExit(int pid, int ws) {
|
||||||
static void ReportWorkerResources(int pid, struct rusage *ru) {
|
static void ReportWorkerResources(int pid, struct rusage *ru) {
|
||||||
char *s, *b = 0;
|
char *s, *b = 0;
|
||||||
if (logrusage || LOGGABLE(kLogDebug)) {
|
if (logrusage || LOGGABLE(kLogDebug)) {
|
||||||
AppendResourceReport(&b, ru, "\n");
|
AppendResourceReport(&b, ru, "\r\n");
|
||||||
if (b) {
|
if (b) {
|
||||||
if ((s = IndentLines(b, appendz(b).i - 1, 0, 1))) {
|
if ((s = IndentLines(b, appendz(b).i - 1, 0, 1))) {
|
||||||
LOGF(kLogDebug, "(stat) resource report for pid %d\n%s", pid, s);
|
LOGF(kLogDebug, "(stat) resource report for pid %d\r\n%s", pid, s);
|
||||||
free(s);
|
free(s);
|
||||||
}
|
}
|
||||||
free(b);
|
free(b);
|
||||||
|
@ -2217,15 +2218,44 @@ static void *LoadAsset(struct Asset *a, size_t *out_size) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static wontreturn void PrintUsage(FILE *f, int rc) {
|
static const char *GetPagerPath(char path[PATH_MAX]) {
|
||||||
|
const char *s;
|
||||||
|
if ((s = commandv("less", path))) return s;
|
||||||
|
if ((s = commandv("more", path))) return s;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static wontreturn void PrintUsage(int fd, int rc) {
|
||||||
size_t n;
|
size_t n;
|
||||||
|
int pip[2];
|
||||||
const char *p;
|
const char *p;
|
||||||
struct Asset *a;
|
struct Asset *a;
|
||||||
if ((a = GetAssetZip("/help.txt", 9)) && (p = LoadAsset(a, &n))) {
|
char *args[2] = {0};
|
||||||
fwrite(p, 1, n, f);
|
char pathbuf[PATH_MAX];
|
||||||
free(p);
|
if (!(a = GetAssetZip("/help.txt", 9)) || !(p = LoadAsset(a, &n))) {
|
||||||
|
fprintf(stderr, "error: /help.txt is not a zip asset\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (isatty(0) && isatty(1) && (args[0] = GetPagerPath(pathbuf))) {
|
||||||
|
sigaction(SIGPIPE, &(struct sigaction){.sa_handler = SIG_IGN}, 0);
|
||||||
|
close(0);
|
||||||
|
pipe(pip);
|
||||||
|
if (!fork()) {
|
||||||
|
close(pip[1]);
|
||||||
|
execv(args[0], args);
|
||||||
|
_Exit(127);
|
||||||
|
}
|
||||||
|
close(0);
|
||||||
|
WritevAll(pip[1], &(struct iovec){p, n}, 1);
|
||||||
|
close(pip[1]);
|
||||||
|
wait(0);
|
||||||
|
free(p);
|
||||||
|
exit(0);
|
||||||
|
} else {
|
||||||
|
WritevAll(fd, &(struct iovec){p, n}, 1);
|
||||||
|
free(p);
|
||||||
|
exit(rc);
|
||||||
}
|
}
|
||||||
exit(rc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AppendLogo(void) {
|
static void AppendLogo(void) {
|
||||||
|
@ -3623,7 +3653,7 @@ static void LogMessage(const char *d, const char *s, size_t n) {
|
||||||
while (n && (s[n - 1] == '\r' || s[n - 1] == '\n')) --n;
|
while (n && (s[n - 1] == '\r' || s[n - 1] == '\n')) --n;
|
||||||
if ((s2 = DecodeLatin1(s, n, &n2))) {
|
if ((s2 = DecodeLatin1(s, n, &n2))) {
|
||||||
if ((s3 = IndentLines(s2, n2, &n3, 1))) {
|
if ((s3 = IndentLines(s2, n2, &n3, 1))) {
|
||||||
INFOF("(stat) %s %,ld byte message\n%.*s", d, n, n3, s3);
|
INFOF("(stat) %s %,ld byte message\r\n%.*s", d, n, n3, s3);
|
||||||
free(s3);
|
free(s3);
|
||||||
}
|
}
|
||||||
free(s2);
|
free(s2);
|
||||||
|
@ -3638,7 +3668,7 @@ static void LogBody(const char *d, const char *s, size_t n) {
|
||||||
while (n && (s[n - 1] == '\r' || s[n - 1] == '\n')) --n;
|
while (n && (s[n - 1] == '\r' || s[n - 1] == '\n')) --n;
|
||||||
if ((s2 = VisualizeControlCodes(s, n, &n2))) {
|
if ((s2 = VisualizeControlCodes(s, n, &n2))) {
|
||||||
if ((s3 = IndentLines(s2, n2, &n3, 1))) {
|
if ((s3 = IndentLines(s2, n2, &n3, 1))) {
|
||||||
INFOF("(stat) %s %,ld byte payload\n%.*s", d, n, n3, s3);
|
INFOF("(stat) %s %,ld byte payload\r\n%.*s", d, n, n3, s3);
|
||||||
free(s3);
|
free(s3);
|
||||||
}
|
}
|
||||||
free(s2);
|
free(s2);
|
||||||
|
@ -3772,8 +3802,8 @@ static int LuaFetch(lua_State *L) {
|
||||||
*/
|
*/
|
||||||
DEBUGF("(ftch) client resolving %s", host);
|
DEBUGF("(ftch) client resolving %s", host);
|
||||||
if ((rc = getaddrinfo(host, port, &hints, &addr)) != EAI_SUCCESS) {
|
if ((rc = getaddrinfo(host, port, &hints, &addr)) != EAI_SUCCESS) {
|
||||||
luaL_error(L, "getaddrinfo(%s:%s) error: EAI_%s", host, port,
|
luaL_error(L, "getaddrinfo(%s:%s) error: EAI_%s %s", host, port,
|
||||||
gai_strerror(rc));
|
gai_strerror(rc), strerror(errno));
|
||||||
unreachable;
|
unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5516,11 +5546,6 @@ static const luaL_Reg kLuaFuncs[] = {
|
||||||
{"Underlong", LuaUnderlong}, //
|
{"Underlong", LuaUnderlong}, //
|
||||||
{"VisualizeControlCodes", LuaVisualizeControlCodes}, //
|
{"VisualizeControlCodes", LuaVisualizeControlCodes}, //
|
||||||
{"Write", LuaWrite}, //
|
{"Write", LuaWrite}, //
|
||||||
{"bsf", LuaBsf}, //
|
|
||||||
{"bsr", LuaBsr}, //
|
|
||||||
{"crc32", LuaCrc32}, //
|
|
||||||
{"crc32c", LuaCrc32c}, //
|
|
||||||
{"popcnt", LuaPopcnt}, //
|
|
||||||
#ifndef UNSECURE
|
#ifndef UNSECURE
|
||||||
{"Fetch", LuaFetch}, //
|
{"Fetch", LuaFetch}, //
|
||||||
{"EvadeDragnetSurveillance", LuaEvadeDragnetSurveillance}, //
|
{"EvadeDragnetSurveillance", LuaEvadeDragnetSurveillance}, //
|
||||||
|
@ -6581,13 +6606,90 @@ static void CloseServerFds(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ExitWorker(void) {
|
static int ExitWorker(void) {
|
||||||
if (IsModeDbg() && !issandboxed) {
|
if (IsModeDbg() && !sandboxed) {
|
||||||
isexitingworker = true;
|
isexitingworker = true;
|
||||||
return eintr();
|
return eintr();
|
||||||
}
|
}
|
||||||
_Exit(0);
|
_Exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct sock_filter kSandboxOnline[] = {
|
||||||
|
_SECCOMP_MACHINE(AUDIT_ARCH_X86_64), //
|
||||||
|
_SECCOMP_LOAD_SYSCALL_NR(), //
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0013), // readv
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0014), // writev
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0009), // mmap
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x000b), // munmap
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0000), // read
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0001), // write
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0003), // close
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0008), // lseek
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x000f), // rt_sigreturn
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x00e7), // exit_group
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0106), // newfstatat
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x00e4), // clock_gettime
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x003f), // uname
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0048), // fcntl
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0029), // socket
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x002a), // connect
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x002c), // sendto
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x002d), // recvfrom
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0036), // setsockopt
|
||||||
|
_SECCOMP_LOG_AND_RETURN_ERRNO(1), // EPERM
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct sock_filter kSandboxOffline[] = {
|
||||||
|
_SECCOMP_MACHINE(AUDIT_ARCH_X86_64), //
|
||||||
|
_SECCOMP_LOAD_SYSCALL_NR(), //
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0013), // readv
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0014), // writev
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0000), // read
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0001), // write
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0009), // mmap
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x000b), // munmap
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0003), // close
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0008), // lseek
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x000f), // rt_sigreturn
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x00e7), // exit_group
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0106), // newfstatat
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x00e4), // clock_gettime
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x003f), // uname
|
||||||
|
_SECCOMP_ALLOW_SYSCALL(0x0048), // fcntl
|
||||||
|
_SECCOMP_LOG_AND_RETURN_ERRNO(1), // EPERM
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct sock_fprog kSandboxOnlineProg = {
|
||||||
|
.len = ARRAYLEN(kSandboxOnline),
|
||||||
|
.filter = kSandboxOnline,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct sock_fprog kSandboxOfflineProg = {
|
||||||
|
.len = ARRAYLEN(kSandboxOffline),
|
||||||
|
.filter = kSandboxOffline,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int EnableSandbox(void) {
|
||||||
|
const struct sock_fprog *sandbox;
|
||||||
|
switch (sandboxed) {
|
||||||
|
case 0:
|
||||||
|
return 0;
|
||||||
|
case 1:
|
||||||
|
DEBUGF("(stat) applying '%s' sandbox policy", "online");
|
||||||
|
sandbox = &kSandboxOnlineProg;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DEBUGF("(stat) applying '%s' sandbox policy", "offline");
|
||||||
|
sandbox = &kSandboxOfflineProg;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) != -1 &&
|
||||||
|
prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, sandbox) != -1) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// returns 0 otherwise -1 if worker needs to unwind stack and exit
|
// returns 0 otherwise -1 if worker needs to unwind stack and exit
|
||||||
static int HandleConnection(size_t i) {
|
static int HandleConnection(size_t i) {
|
||||||
int pid, rc = 0;
|
int pid, rc = 0;
|
||||||
|
@ -6595,6 +6697,7 @@ static int HandleConnection(size_t i) {
|
||||||
if ((client = accept4(servers.p[i].fd, &clientaddr, &clientaddrsize,
|
if ((client = accept4(servers.p[i].fd, &clientaddr, &clientaddrsize,
|
||||||
SOCK_CLOEXEC)) != -1) {
|
SOCK_CLOEXEC)) != -1) {
|
||||||
startconnection = nowl();
|
startconnection = nowl();
|
||||||
|
VERBOSEF("(srvr) accept %s via %s", DescribeClient(), DescribeServer());
|
||||||
messageshandled = 0;
|
messageshandled = 0;
|
||||||
if (hasonclientconnection && LuaOnClientConnection()) {
|
if (hasonclientconnection && LuaOnClientConnection()) {
|
||||||
close(client);
|
close(client);
|
||||||
|
@ -6607,11 +6710,19 @@ static int HandleConnection(size_t i) {
|
||||||
switch ((pid = fork())) {
|
switch ((pid = fork())) {
|
||||||
case 0:
|
case 0:
|
||||||
meltdown = false;
|
meltdown = false;
|
||||||
|
__isworker = true;
|
||||||
connectionclose = false;
|
connectionclose = false;
|
||||||
if (!IsTiny()) {
|
if (!IsTiny()) {
|
||||||
if (systrace) __strace = 1;
|
if (systrace) {
|
||||||
if (funtrace) ftrace_install();
|
extern unsigned long long __kbirth;
|
||||||
|
__strace = 1;
|
||||||
|
__kbirth = rdtsc();
|
||||||
|
}
|
||||||
|
if (funtrace) {
|
||||||
|
ftrace_install();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
CHECK_NE(-1, EnableSandbox());
|
||||||
if (hasonworkerstart) {
|
if (hasonworkerstart) {
|
||||||
CallSimpleHook("OnWorkerStart");
|
CallSimpleHook("OnWorkerStart");
|
||||||
}
|
}
|
||||||
|
@ -6632,7 +6743,6 @@ static int HandleConnection(size_t i) {
|
||||||
if (!pid && !IsWindows()) {
|
if (!pid && !IsWindows()) {
|
||||||
CloseServerFds();
|
CloseServerFds();
|
||||||
}
|
}
|
||||||
VERBOSEF("(srvr) accept %s via %s", DescribeClient(), DescribeServer());
|
|
||||||
HandleMessages();
|
HandleMessages();
|
||||||
DEBUGF("(stat) %s closing after %,ldµs", DescribeClient(),
|
DEBUGF("(stat) %s closing after %,ldµs", DescribeClient(),
|
||||||
(long)((nowl() - startconnection) * 1e6L));
|
(long)((nowl() - startconnection) * 1e6L));
|
||||||
|
@ -6809,7 +6919,7 @@ static void Listen(void) {
|
||||||
INFOF("(srvr) listen http://%hhu.%hhu.%hhu.%hhu:%d", ip >> 24, ip >> 16,
|
INFOF("(srvr) listen http://%hhu.%hhu.%hhu.%hhu:%d", ip >> 24, ip >> 16,
|
||||||
ip >> 8, ip, port);
|
ip >> 8, ip, port);
|
||||||
if (printport && !ports.p[j]) {
|
if (printport && !ports.p[j]) {
|
||||||
printf("%d\n", port);
|
printf("%d\r\n", port);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7004,6 +7114,7 @@ static void GetOpts(int argc, char *argv[]) {
|
||||||
bool storeasset = false;
|
bool storeasset = false;
|
||||||
while ((opt = getopt(argc, argv, GETOPTS)) != -1) {
|
while ((opt = getopt(argc, argv, GETOPTS)) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
CASE('S', ++sandboxed);
|
||||||
CASE('v', ++__log_level);
|
CASE('v', ++__log_level);
|
||||||
CASE('s', --__log_level);
|
CASE('s', --__log_level);
|
||||||
CASE('f', funtrace = true);
|
CASE('f', funtrace = true);
|
||||||
|
@ -7014,7 +7125,6 @@ static void GetOpts(int argc, char *argv[]) {
|
||||||
CASE('a', logrusage = true);
|
CASE('a', logrusage = true);
|
||||||
CASE('u', uniprocess = true);
|
CASE('u', uniprocess = true);
|
||||||
CASE('g', loglatency = true);
|
CASE('g', loglatency = true);
|
||||||
CASE('S', issandboxed = true);
|
|
||||||
CASE('m', logmessages = true);
|
CASE('m', logmessages = true);
|
||||||
CASE('l', ProgramAddr(optarg));
|
CASE('l', ProgramAddr(optarg));
|
||||||
CASE('H', ProgramHeader(optarg));
|
CASE('H', ProgramHeader(optarg));
|
||||||
|
@ -7028,7 +7138,7 @@ static void GetOpts(int argc, char *argv[]) {
|
||||||
CASE('c', ProgramCache(ParseInt(optarg)));
|
CASE('c', ProgramCache(ParseInt(optarg)));
|
||||||
CASE('r', ProgramRedirectArg(307, optarg));
|
CASE('r', ProgramRedirectArg(307, optarg));
|
||||||
CASE('t', ProgramTimeout(ParseInt(optarg)));
|
CASE('t', ProgramTimeout(ParseInt(optarg)));
|
||||||
CASE('h', PrintUsage(stdout, EXIT_SUCCESS));
|
CASE('h', PrintUsage(1, EXIT_SUCCESS));
|
||||||
CASE('M', ProgramMaxPayloadSize(ParseInt(optarg)));
|
CASE('M', ProgramMaxPayloadSize(ParseInt(optarg)));
|
||||||
#ifndef STATIC
|
#ifndef STATIC
|
||||||
CASE('e', LuaEvalCode(optarg));
|
CASE('e', LuaEvalCode(optarg));
|
||||||
|
@ -7046,7 +7156,7 @@ static void GetOpts(int argc, char *argv[]) {
|
||||||
CASE('K', ProgramFile(optarg, ProgramPrivateKey));
|
CASE('K', ProgramFile(optarg, ProgramPrivateKey));
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
PrintUsage(stderr, EX_USAGE);
|
PrintUsage(2, EX_USAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if storing asset(s) is requested, don't need to continue
|
// if storing asset(s) is requested, don't need to continue
|
||||||
|
@ -7107,6 +7217,8 @@ void RedBean(int argc, char *argv[]) {
|
||||||
#ifdef STATIC
|
#ifdef STATIC
|
||||||
EventLoop(-1, HEARTBEAT);
|
EventLoop(-1, HEARTBEAT);
|
||||||
#else
|
#else
|
||||||
|
GetResolvConf(); // for effect
|
||||||
|
GetHostsTxt(); // for effect
|
||||||
if (!IsWindows() && isatty(0)) {
|
if (!IsWindows() && isatty(0)) {
|
||||||
ReplEventLoop();
|
ReplEventLoop();
|
||||||
} else {
|
} else {
|
||||||
|
@ -7127,7 +7239,6 @@ void RedBean(int argc, char *argv[]) {
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
if (!IsTiny()) {
|
if (!IsTiny()) {
|
||||||
setenv("GDB", "", true);
|
|
||||||
ShowCrashReports();
|
ShowCrashReports();
|
||||||
}
|
}
|
||||||
RedBean(argc, argv);
|
RedBean(argc, argv);
|
||||||
|
|
23
tool/net/sandbox.h
Normal file
23
tool/net/sandbox.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef COSMOPOLITAN_TOOL_NET_SANDBOX_H_
|
||||||
|
#define COSMOPOLITAN_TOOL_NET_SANDBOX_H_
|
||||||
|
#include "libc/calls/struct/bpf.h"
|
||||||
|
#include "libc/calls/struct/filter.h"
|
||||||
|
#include "libc/calls/struct/seccomp.h"
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
|
#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_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL_PROCESS)
|
||||||
|
|
||||||
|
#define _SECCOMP_LOAD_SYSCALL_NR() \
|
||||||
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, nr))
|
||||||
|
|
||||||
|
#define _SECCOMP_ALLOW_SYSCALL(MAGNUM) \
|
||||||
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, MAGNUM, 0, 1), \
|
||||||
|
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW)
|
||||||
|
|
||||||
|
#define _SECCOMP_LOG_AND_RETURN_ERRNO(MAGNUM) \
|
||||||
|
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | (MAGNUM & SECCOMP_RET_DATA))
|
||||||
|
|
||||||
|
#endif /* COSMOPOLITAN_TOOL_NET_SANDBOX_H_ */
|
Loading…
Add table
Reference in a new issue