mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-05 09:20:29 +00:00
Merge branch 'master' into apeflags
This commit is contained in:
commit
27e3b1df18
17 changed files with 103 additions and 64 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -7,6 +7,7 @@
|
|||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
||||
|
@ -18,6 +19,17 @@ void crash(long x0, long x1, long x2, //
|
|||
void (*pCrash)(long, long, long, double, double, double) = crash;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
// // by default we launch an addr2line subprocess to print backtraces
|
||||
// // with line numbers. you can force it to use the embedded solution
|
||||
// setenv("ADDR2LINE", "", true);
|
||||
|
||||
// // using a seccomp sandbox is another way to force embedded backtraces
|
||||
// pledge("stdio", NULL);
|
||||
|
||||
// enable the crash reporting feature
|
||||
ShowCrashReports();
|
||||
|
||||
// time to die
|
||||
pCrash(1, 2, 3, NAN, NAN, NAN);
|
||||
}
|
||||
|
|
|
@ -24,11 +24,13 @@
|
|||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/promises.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/nexgen32e/vendor.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/symbols.internal.h"
|
||||
#include "libc/runtime/zipos.internal.h"
|
||||
#include "libc/sysv/consts/pr.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
|
@ -199,22 +201,22 @@
|
|||
* `__pledge_mode` is available to improve the experience of pledge() on
|
||||
* Linux. It should specify one of the following penalties:
|
||||
*
|
||||
* - `PLEDGE_PENALTY_RETURN_EPERM` causes system calls to just return an
|
||||
* `EPERM` error instead of killing. This is the default on Linux.
|
||||
* This is a gentler solution that allows code to display a friendly
|
||||
* warning. Please note this may lead to weird behaviors if the
|
||||
* software being sandboxed is lazy about checking error results.
|
||||
*
|
||||
* - `PLEDGE_PENALTY_KILL_THREAD` causes the violating thread to be
|
||||
* killed. This is the default on Linux. It's effectively the same as
|
||||
* killing the process, since redbean has no threads. The termination
|
||||
* signal can't be caught and will be either `SIGSYS` or `SIGABRT`.
|
||||
* Consider enabling stderr logging below so you'll know why your
|
||||
* program failed. Otherwise check the system log.
|
||||
* killed. It's effectively the same as killing the process, since
|
||||
* redbean has no threads. The termination signal can't be caught and
|
||||
* will be either `SIGSYS` or `SIGABRT`. Consider enabling stderr
|
||||
* logging below so you'll know why your program failed. Otherwise
|
||||
* check the system log.
|
||||
*
|
||||
* - `PLEDGE_PENALTY_KILL_PROCESS` causes the process and all its
|
||||
* threads to be killed. This is always the case on OpenBSD.
|
||||
*
|
||||
* - `PLEDGE_PENALTY_RETURN_EPERM` causes system calls to just return an
|
||||
* `EPERM` error instead of killing. This is a gentler solution that
|
||||
* allows code to display a friendly warning. Please note this may
|
||||
* lead to weird behaviors if the software being sandboxed is lazy
|
||||
* about checking error results.
|
||||
*
|
||||
* `mode` may optionally bitwise or the following flags:
|
||||
*
|
||||
* - `PLEDGE_STDERR_LOGGING` enables friendly error message logging
|
||||
|
@ -240,6 +242,8 @@
|
|||
int pledge(const char *promises, const char *execpromises) {
|
||||
int e, rc;
|
||||
unsigned long ipromises, iexecpromises;
|
||||
if (_weaken(GetSymbolTable))
|
||||
_weaken(GetSymbolTable)();
|
||||
if (!promises) {
|
||||
// OpenBSD says NULL argument means it doesn't change, i.e.
|
||||
// pledge(0,0) on OpenBSD does nothing. The Cosmopolitan Libc
|
||||
|
|
|
@ -21,6 +21,6 @@
|
|||
|
||||
// XXX: should be inherited thread local
|
||||
// see also sys_pledge_linux() which is 100% pure
|
||||
int __pledge_mode;
|
||||
int __pledge_mode = PLEDGE_PENALTY_RETURN_EPERM;
|
||||
unsigned long __promises;
|
||||
unsigned long __execpromises;
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
COSMOPOLITAN_C_START_
|
||||
|
||||
enum VendorSignatures {
|
||||
SIG_INTEL = 0x756e6547, // Genu
|
||||
SIG_AMD = 0x68747541, // Auth
|
||||
SIG_INTEL = 0x756e6547, /* Genu */
|
||||
SIG_AMD = 0x68747541, /* Auth */
|
||||
};
|
||||
|
||||
enum ProcessorVendors {
|
||||
|
@ -139,7 +139,7 @@ struct __processor_model {
|
|||
const char *__cpu_march;
|
||||
};
|
||||
|
||||
struct __processor_model __cpu_model;
|
||||
extern struct __processor_model __cpu_model;
|
||||
|
||||
const char *__cpu_march(unsigned);
|
||||
|
||||
|
|
|
@ -37,9 +37,14 @@ static struct {
|
|||
} g_addr2line;
|
||||
|
||||
void GetAddr2linePathInit(void) {
|
||||
char *res;
|
||||
int e = errno;
|
||||
const char *path;
|
||||
if (!(path = getenv("ADDR2LINE"))) {
|
||||
const char *env, *cmd, *path;
|
||||
if ((env = getenv("ADDR2LINE"))) {
|
||||
cmd = env;
|
||||
path = env;
|
||||
} else {
|
||||
cmd = "addr2line";
|
||||
path = ADDR2LINE;
|
||||
}
|
||||
char *buf = g_addr2line.buf;
|
||||
|
@ -48,12 +53,11 @@ void GetAddr2linePathInit(void) {
|
|||
strlcat(buf, "/", PATH_MAX);
|
||||
}
|
||||
strlcat(buf, path, PATH_MAX);
|
||||
}
|
||||
if (*buf) {
|
||||
g_addr2line.res = buf;
|
||||
res = buf;
|
||||
} else {
|
||||
g_addr2line.res = commandv("addr2line", buf, PATH_MAX);
|
||||
res = commandv(cmd, buf, PATH_MAX);
|
||||
}
|
||||
g_addr2line.res = res;
|
||||
errno = e;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) {
|
|||
}
|
||||
|
||||
if (!PLEDGED(STDIO) || !PLEDGED(EXEC) || !PLEDGED(EXEC)) {
|
||||
ShowHint("won't print addr2line backtrace because pledge");
|
||||
ShowHint("pledge() sandboxing makes backtraces not as good");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/cosmo.h"
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
|
@ -29,6 +30,7 @@
|
|||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/symbols.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/thread/thread.h"
|
||||
#include "libc/thread/tls.h"
|
||||
|
||||
#define LIMIT 100
|
||||
|
@ -47,8 +49,11 @@ dontinstrument dontasan int PrintBacktraceUsingSymbols(
|
|||
int fd, const struct StackFrame *bp, struct SymbolTable *st) {
|
||||
size_t gi;
|
||||
intptr_t addr;
|
||||
const char *name;
|
||||
int i, symbol, addend;
|
||||
static char cxxbuf[8192];
|
||||
struct Garbages *garbage;
|
||||
static pthread_spinlock_t lock;
|
||||
const struct StackFrame *frame;
|
||||
(void)gi;
|
||||
if (!bp)
|
||||
|
@ -83,8 +88,15 @@ dontinstrument dontasan int PrintBacktraceUsingSymbols(
|
|||
symbol = 0;
|
||||
addend = 0;
|
||||
}
|
||||
kprintf("%012lx %lx %s%+d\n", frame, addr, __get_symbol_name(st, symbol),
|
||||
addend);
|
||||
if ((name = __get_symbol_name(st, symbol)) && __is_mangled(name)) {
|
||||
pthread_spin_lock(&lock);
|
||||
__demangle(cxxbuf, name, sizeof(cxxbuf));
|
||||
kprintf("%012lx %lx %s%+d\n", frame, addr, cxxbuf, addend);
|
||||
pthread_spin_unlock(&lock);
|
||||
name = cxxbuf;
|
||||
} else {
|
||||
kprintf("%012lx %lx %s%+d\n", frame, addr, name, addend);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "libc/calls/struct/utsname.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/calls/ucontext.h"
|
||||
#include "libc/cosmo.h"
|
||||
#include "libc/cxxabi.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/atomic.h"
|
||||
|
@ -40,7 +41,6 @@
|
|||
#include "libc/log/internal.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nexgen32e/stackframe.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
@ -178,15 +178,15 @@ static relegated bool AppendFileLine(struct Buffer *b, const char *addr2line,
|
|||
}
|
||||
}
|
||||
|
||||
static relegated char *GetSymbolName(struct SymbolTable *st, int symbol,
|
||||
char **mem, size_t *memsz) {
|
||||
char *s, *t;
|
||||
if ((s = __get_symbol_name(st, symbol)) && //
|
||||
s[0] == '_' && s[1] == 'Z' && //
|
||||
(t = __cxa_demangle(s, *mem, memsz, 0))) {
|
||||
*mem = s = t;
|
||||
}
|
||||
return s;
|
||||
static relegated char *GetSymbolName(struct SymbolTable *st, int symbol) {
|
||||
char *str;
|
||||
static char buf[8192];
|
||||
if (!(str = __get_symbol_name(st, symbol)))
|
||||
return str;
|
||||
if (!__is_mangled(str))
|
||||
return str;
|
||||
__demangle(buf, str, sizeof(buf));
|
||||
return buf;
|
||||
}
|
||||
|
||||
static relegated void __oncrash_impl(int sig, struct siginfo *si,
|
||||
|
@ -241,8 +241,6 @@ static relegated void __oncrash_impl(int sig, struct siginfo *si,
|
|||
: (struct StackFrame *)__builtin_frame_address(0)));
|
||||
if (ctx) {
|
||||
long pc;
|
||||
char *mem = 0;
|
||||
size_t memsz = 0;
|
||||
int addend, symbol;
|
||||
const char *debugbin;
|
||||
const char *addr2line;
|
||||
|
@ -305,7 +303,7 @@ static relegated void __oncrash_impl(int sig, struct siginfo *si,
|
|||
addend -= st->symbols[symbol].x;
|
||||
Append(b, " ");
|
||||
if (!AppendFileLine(b, addr2line, debugbin, pc)) {
|
||||
Append(b, "%s", GetSymbolName(st, symbol, &mem, &memsz));
|
||||
Append(b, "%s", GetSymbolName(st, symbol));
|
||||
if (addend)
|
||||
Append(b, "%+d", addend);
|
||||
}
|
||||
|
@ -327,7 +325,7 @@ static relegated void __oncrash_impl(int sig, struct siginfo *si,
|
|||
addend -= st->symbols[symbol].x;
|
||||
Append(b, " ");
|
||||
if (!AppendFileLine(b, addr2line, debugbin, pc)) {
|
||||
Append(b, "%s", GetSymbolName(st, symbol, &mem, &memsz));
|
||||
Append(b, "%s", GetSymbolName(st, symbol));
|
||||
if (addend)
|
||||
Append(b, "%+d", addend);
|
||||
}
|
||||
|
@ -367,13 +365,12 @@ static relegated void __oncrash_impl(int sig, struct siginfo *si,
|
|||
}
|
||||
Append(b, " %016lx fp %lx lr ", fp, pc);
|
||||
if (!AppendFileLine(b, addr2line, debugbin, pc) && st) {
|
||||
Append(b, "%s", GetSymbolName(st, symbol, &mem, &memsz));
|
||||
Append(b, "%s", GetSymbolName(st, symbol));
|
||||
if (addend)
|
||||
Append(b, "%+d", addend);
|
||||
}
|
||||
Append(b, "\n");
|
||||
}
|
||||
free(mem);
|
||||
}
|
||||
b->p[b->n - 1] = '\n';
|
||||
klog(b->p, MIN(b->i, b->n));
|
||||
|
|
|
@ -19,10 +19,18 @@
|
|||
#include "libc/stdckdint.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
#ifndef TINYMALLOC_MAX_BYTES
|
||||
#define TINYMALLOC_MAX_BYTES 1073741824
|
||||
#endif
|
||||
|
||||
#ifndef TINYMALLOC_MAX_ALIGN
|
||||
#define TINYMALLOC_MAX_ALIGN 4096
|
||||
#endif
|
||||
|
||||
#ifndef MODE_DBG /* don't interfere with asan dlmalloc hooking */
|
||||
|
||||
_Alignas(65536) static struct {
|
||||
char memory[1024 * 1024 * 1024];
|
||||
_Alignas(TINYMALLOC_MAX_ALIGN) static struct {
|
||||
char memory[TINYMALLOC_MAX_BYTES];
|
||||
unsigned used, last, free;
|
||||
} heap;
|
||||
|
||||
|
@ -59,7 +67,7 @@ void *memalign(size_t align, size_t need) {
|
|||
need = sizeof(unsigned);
|
||||
if (align < sizeof(unsigned))
|
||||
align = sizeof(unsigned);
|
||||
if (align > 65536)
|
||||
if (align > TINYMALLOC_MAX_ALIGN)
|
||||
goto InvalidArgument;
|
||||
if (ckd_add(&need, need, sizeof(unsigned) - 1))
|
||||
goto OutOfMemory;
|
||||
|
@ -86,7 +94,7 @@ void *memalign(size_t align, size_t need) {
|
|||
base &= -align;
|
||||
if (ckd_add(&toto, base, need))
|
||||
goto OutOfMemory;
|
||||
if (toto > sizeof(heap.memory))
|
||||
if (toto > TINYMALLOC_MAX_BYTES)
|
||||
goto OutOfMemory;
|
||||
res = heap.memory + base;
|
||||
((unsigned *)res)[-1] = need;
|
||||
|
@ -139,7 +147,7 @@ void *realloc(void *ptr, size_t need) {
|
|||
need &= -sizeof(unsigned);
|
||||
if (ckd_add(&toto, base, need))
|
||||
goto OutOfMemory;
|
||||
if (toto > sizeof(heap.memory))
|
||||
if (toto > TINYMALLOC_MAX_BYTES)
|
||||
goto OutOfMemory;
|
||||
((unsigned *)mem)[-1] = need;
|
||||
heap.used = toto;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/promises.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
|
@ -124,6 +125,7 @@ struct SymbolTable *GetSymbolTable(void) {
|
|||
struct Zipos *z;
|
||||
if (pthread_spin_trylock(&g_lock))
|
||||
return 0;
|
||||
int e = errno;
|
||||
if (!__symtab && !__isworker) {
|
||||
if (_weaken(__zipos_get) && (z = _weaken(__zipos_get)())) {
|
||||
if ((__symtab = GetSymbolTableFromZip(z))) {
|
||||
|
@ -137,6 +139,7 @@ struct SymbolTable *GetSymbolTable(void) {
|
|||
__symtab = GetSymbolTableFromElf();
|
||||
}
|
||||
}
|
||||
errno = e;
|
||||
pthread_spin_unlock(&g_lock);
|
||||
return __symtab;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ Copyright (c) 2007 Hyogeol Lee <hyogeollee@gmail.com>\n\
|
|||
Copyright (c) 2015-2017 Kai Wang <kaiwang27@gmail.com>\n\
|
||||
Copyright (c) 2024 Justine Tunney <jtunney@gmail.com>");
|
||||
// https://github.com/freebsd/freebsd-src/blob/2176c9ab71c85efd90a6c7af4a9e04fe8e3d49ca/contrib/libcxxrt/libelftc_dem_gnu3.c
|
||||
// clang -format off
|
||||
// clang-format off
|
||||
|
||||
/**
|
||||
* @file demangle.c
|
||||
|
@ -321,9 +321,9 @@ static char *
|
|||
vector_str_get_flat(struct cpp_demangle_data *ddata, const struct vector_str *v,
|
||||
size_t *l)
|
||||
{
|
||||
ssize_t elem_pos, elem_size, rtn_size;
|
||||
size_t i;
|
||||
char *rtn;
|
||||
char *rtn, *p;
|
||||
ssize_t rtn_size;
|
||||
|
||||
if (!v || !v->size)
|
||||
return 0;
|
||||
|
@ -334,14 +334,9 @@ vector_str_get_flat(struct cpp_demangle_data *ddata, const struct vector_str *v,
|
|||
if (!(rtn = (char *)alloc(ddata, 1, rtn_size + 1)))
|
||||
return 0;
|
||||
|
||||
elem_pos = 0;
|
||||
for (i = 0; i < v->size; ++i) {
|
||||
elem_size = strlen(v->container[i]);
|
||||
memcpy(rtn + elem_pos, v->container[i], elem_size);
|
||||
elem_pos += elem_size;
|
||||
}
|
||||
|
||||
rtn[rtn_size] = '\0';
|
||||
p = rtn;
|
||||
for (i = 0; i < v->size; ++i)
|
||||
p = stpcpy(p, v->container[i]);
|
||||
|
||||
if (l)
|
||||
*l = rtn_size;
|
||||
|
@ -2878,7 +2873,7 @@ static int
|
|||
cpp_demangle_read_tmpl_args(struct cpp_demangle_data *ddata)
|
||||
{
|
||||
struct vector_str *v;
|
||||
size_t arg_len, idx, limit, size;
|
||||
size_t arg_len, idx, limit;
|
||||
char *arg;
|
||||
|
||||
if (!ddata || *ddata->cur == '\0')
|
||||
|
@ -2907,12 +2902,7 @@ cpp_demangle_read_tmpl_args(struct cpp_demangle_data *ddata)
|
|||
|
||||
if (*ddata->cur == 'E') {
|
||||
++ddata->cur;
|
||||
size = v->size;
|
||||
ASSERT(size > 0);
|
||||
if (!strncmp(v->container[size - 1], ">", 1)) {
|
||||
if (!DEM_PUSH_STR(ddata, ">"))
|
||||
return 0;
|
||||
} else if (!DEM_PUSH_STR(ddata, ">"))
|
||||
if (!DEM_PUSH_STR(ddata, ">"))
|
||||
return 0;
|
||||
ddata->is_tmpl = true;
|
||||
break;
|
||||
|
@ -4070,6 +4060,7 @@ failure(char *buf, const char *org, size_t buflen)
|
|||
* be a partially copied result. In both cases, -1 is returned. The size
|
||||
* of the output is only returned if this routine is fully succesful. To
|
||||
* successfully cover nearly all the test cases from libcxxabi use 65536
|
||||
* and to be able to print 99% of the symbols LLVM's libcxx.a, use 5632.
|
||||
*
|
||||
* It's important to call ismangled() before this, since non-c++ symbols
|
||||
* have a special meaning; for example, "g" will return "__float128". It
|
||||
|
|
|
@ -94,6 +94,12 @@ dontasan int main(int argc, char *argv[]) {
|
|||
struct Dll *e;
|
||||
struct TestAspect *a;
|
||||
|
||||
if (errno) {
|
||||
tinyprint(2, "error: the errno variable was contaminated by constructors\n",
|
||||
NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
__ubsan_strict = true;
|
||||
__log_level = kLogInfo;
|
||||
GetOpts(argc, argv);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/landlock.h"
|
||||
#include "libc/calls/pledge.h"
|
||||
#include "libc/calls/struct/dirent.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
|
@ -337,6 +338,7 @@ TEST(unveil, usedTwice_forbidden_worksWithPledge) {
|
|||
ASSERT_NE(-1, (gotsome = _mapshared(FRAMESIZE)));
|
||||
ASSERT_NE(-1, (pid = fork()));
|
||||
if (!pid) {
|
||||
__pledge_mode = PLEDGE_PENALTY_KILL_PROCESS;
|
||||
// install our first seccomp filter
|
||||
ASSERT_SYS(0, 0, pledge("stdio rpath wpath cpath unveil", 0));
|
||||
ASSERT_SYS(0, 0, mkdir("jail", 0755));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue