Validate privileged code relationships

- Work towards improving non-optimized build support
- Introduce MODE=zero which is -O0 without ASAN/UBSAN
- Use system GCC when ~/.cosmo.mk has USE_SYSTEM_TOOLCHAIN=1
- Have package.com check .privileged code doesn't call non-privileged
This commit is contained in:
Justine Tunney 2023-06-08 04:37:05 -07:00
parent 01fd655097
commit daf4454a06
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
82 changed files with 808 additions and 850 deletions

View file

@ -127,7 +127,7 @@ static int arch_prctl_xnu(int code, int64_t addr) {
}
}
static privileged dontinline int arch_prctl_openbsd(int code, int64_t addr) {
static dontinline int arch_prctl_openbsd(int code, int64_t addr) {
bool failed;
int64_t rax;
switch (code) {

View file

@ -0,0 +1,37 @@
/*-*- 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 2020 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/fmt/itoa.h"
#include "libc/intrin/kprintf.h"
#include "libc/runtime/runtime.h"
#include "libc/runtime/stack.h"
#include "libc/runtime/symbols.internal.h"
void ftrace_hook(void);
_Hide int ftrace_stackdigs;
textstartup int ftrace_install(void) {
if (GetSymbolTable()) {
ftrace_stackdigs = LengthInt64Thousands(GetStackSize());
return __hook(ftrace_hook, GetSymbolTable());
} else {
kprintf("error: --ftrace failed to open symbol table\n");
return -1;
}
}

View file

@ -27,7 +27,6 @@
#include "libc/runtime/internal.h"
#include "libc/runtime/runtime.h"
#include "libc/runtime/stack.h"
#include "libc/runtime/symbols.internal.h"
#include "libc/thread/tls.h"
#include "libc/thread/tls2.h"
@ -47,9 +46,7 @@
#define DETOUR_SKEW 8
#endif
void ftrace_hook(void);
static int g_stackdigs;
extern _Hide int ftrace_stackdigs;
static struct CosmoFtrace g_ftrace;
static privileged inline int GetNestingLevelImpl(struct StackFrame *frame) {
@ -73,9 +70,11 @@ static privileged inline int GetNestingLevel(struct CosmoFtrace *ft,
/**
* Prints name of function being called.
*
* We insert CALL instructions that point to this function, in the
* prologues of other functions. We assume those functions behave
* according to the System Five NexGen32e ABI.
* Whenever a function is called, ftrace_hook() will be called from the
* function prologue which saves the parameter registers and calls this
* function, which is responsible for logging the function call.
*
* @see ftrace_install()
*/
privileged void ftracer(void) {
uintptr_t fn;
@ -101,20 +100,10 @@ privileged void ftracer(void) {
fn = sf->addr + DETOUR_SKEW;
if (fn != ft->ft_lastaddr) {
stackuse = GetStackAddr() + GetStackSize() - (intptr_t)sf;
kprintf("%rFUN %6P %'13T %'*ld %*s%t\n", g_stackdigs, stackuse,
kprintf("%rFUN %6P %'13T %'*ld %*s%t\n", ftrace_stackdigs, stackuse,
GetNestingLevel(ft, sf) * 2, "", fn);
ft->ft_lastaddr = fn;
}
ft->ft_noreentry = false;
}
}
textstartup int ftrace_install(void) {
if (GetSymbolTable()) {
g_stackdigs = LengthInt64Thousands(GetStackSize());
return __hook(ftrace_hook, GetSymbolTable());
} else {
kprintf("error: --ftrace failed to open symbol table\n");
return -1;
}
}

56
libc/runtime/getsymbol.c Normal file
View file

@ -0,0 +1,56 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2023 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/runtime/runtime.h"
#include "libc/runtime/symbols.internal.h"
extern _Hide struct SymbolTable *__symtab;
/**
* Returns low index into symbol table for address.
*
* @param t if null will be auto-populated only if already open
* @return index or -1 if nothing found
*/
noinstrument privileged int __get_symbol(struct SymbolTable *t, intptr_t a) {
// we need privileged because:
// kprintf is privileged and it depends on this
// we don't want function tracing because:
// function tracing depends on this function via kprintf
unsigned l, m, r, n, k;
if (!t && __symtab) {
t = __symtab;
}
if (t) {
l = 0;
r = n = t->count;
k = a - t->addr_base;
while (l < r) {
m = (l + r) >> 1;
if (t->symbols[m].y < k) {
l = m + 1;
} else {
r = m;
}
}
if (l < n && t->symbols[l].x <= k && k <= t->symbols[l].y) {
return l;
}
}
return -1;
}

View file

@ -142,37 +142,3 @@ struct SymbolTable *GetSymbolTable(void) {
pthread_spin_unlock(&g_lock);
return __symtab;
}
/**
* Returns low index into symbol table for address.
*
* @param t if null will be auto-populated only if already open
* @return index or -1 if nothing found
*/
noinstrument privileged int __get_symbol(struct SymbolTable *t, intptr_t a) {
// we need privileged because:
// kprintf is privileged and it depends on this
// we don't want function tracing because:
// function tracing depends on this function via kprintf
unsigned l, m, r, n, k;
if (!t && __symtab) {
t = __symtab;
}
if (t) {
l = 0;
r = n = t->count;
k = a - t->addr_base;
while (l < r) {
m = (l + r) >> 1;
if (t->symbols[m].y < k) {
l = m + 1;
} else {
r = m;
}
}
if (l < n && t->symbols[l].x <= k && k <= t->symbols[l].y) {
return l;
}
}
return -1;
}

View file

@ -68,7 +68,6 @@ static privileged void __morph_mprotect(void *addr, size_t size, int prot,
if (cf) ax = -ax;
if (ax == -EPERM) {
kprintf("error: need pledge(prot_exec) permission to code morph\n");
_Exit(26);
}
#endif
if (ax) notpossible;

View file

@ -78,7 +78,7 @@ void fpreset(void);
void *mmap(void *, uint64_t, int32_t, int32_t, int32_t, int64_t);
void *mremap(void *, size_t, size_t, int, ...);
int munmap(void *, uint64_t);
int mprotect(void *, uint64_t, int) privileged;
int mprotect(void *, uint64_t, int);
int msync(void *, size_t, int);
int mlock(const void *, size_t);
int munlock(const void *, size_t);

View file

@ -70,7 +70,6 @@ o/$(MODE)/libc/runtime/cosmo2.o: private \
o/$(MODE)/libc/runtime/ftracer.o: private \
CFLAGS += \
-x-no-pg \
$(MNO_FENTRY) \
-ffreestanding \
-fno-sanitize=all
@ -124,6 +123,14 @@ o/$(MODE)/libc/runtime/enable_tls.o: private \
-mcmodel=large
endif
# privileged functions
o/$(MODE)/libc/runtime/getsymbol.o \
o/$(MODE)/libc/runtime/enable_threads.o \
o/$(MODE)/libc/runtime/morph_tls.o: private \
CFLAGS += \
-ffreestanding \
-fno-sanitize=all
# these assembly files are safe to build on aarch64
o/$(MODE)/libc/runtime/init.o: libc/runtime/init.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<

View file

@ -17,9 +17,8 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/intrin/kprintf.h"
#include "libc/runtime/internal.h"
privileged noasan noinstrument void __stack_chk_fail(void) {
kprintf("stack smashed\n");
_Exitr(207);
__builtin_trap();
}