Add notpossible keyword

This is the same as `unreachable` except it always traps violations,
even if we're not running in MODE=dbg. This is useful for impossible
conditions relating to system calls. It avoids terrifying bugs where
control falls through to an unrelated function.
This commit is contained in:
Justine Tunney 2022-09-03 20:35:31 -07:00
parent b66bd064d8
commit 0c70e8963d
12 changed files with 27 additions and 26 deletions

View file

@ -46,7 +46,8 @@
"testonly=", "testonly=",
"donothing=", "donothing=",
"nosideeffect=", "nosideeffect=",
"unreachable=", "unreachable=",,
"notpossible=",
"thatispacked=", "thatispacked=",
"dontthrow=", "dontthrow=",
"nocallback=", "nocallback=",

View file

@ -121,5 +121,5 @@ textwindows int sys_execve_nt(const char *program, char *const argv[],
} while (dwExitCode == kNtStillActive); } while (dwExitCode == kNtStillActive);
__imp_CloseHandle(procinfo.hProcess); __imp_CloseHandle(procinfo.hProcess);
__imp_ExitProcess(dwExitCode); __imp_ExitProcess(dwExitCode);
unreachable; notpossible;
} }

View file

@ -74,12 +74,6 @@
#define PLEDGE(pledge) pledge, ARRAYLEN(pledge) #define PLEDGE(pledge) pledge, ARRAYLEN(pledge)
#define OFF(f) offsetof(struct seccomp_data, f) #define OFF(f) offsetof(struct seccomp_data, f)
#define AbortPledge(reason) \
do { \
asm("hlt"); \
unreachable; \
} while (0)
struct Filter { struct Filter {
size_t n; size_t n;
struct sock_filter p[700]; struct sock_filter p[700];
@ -992,7 +986,7 @@ static privileged void OnSigSys(int sig, siginfo_t *si, void *vctx) {
// fallthrough // fallthrough
case PLEDGE_PENALTY_KILL_THREAD: case PLEDGE_PENALTY_KILL_THREAD:
KillThisThread(); KillThisThread();
unreachable; notpossible;
default: default:
break; break;
} }
@ -1006,14 +1000,14 @@ static privileged void MonitorSigSys(void) {
}; };
// we block changing sigsys once pledge is installed // we block changing sigsys once pledge is installed
// so we aren't terribly concerned if this will fail // so we aren't terribly concerned if this will fail
if (SigAction(Sigsys, &sa, 0) == -1) asm("hlt"); if (SigAction(Sigsys, &sa, 0) == -1) {
notpossible;
}
} }
static privileged void AppendFilter(struct Filter *f, struct sock_filter *p, static privileged void AppendFilter(struct Filter *f, struct sock_filter *p,
size_t n) { size_t n) {
if (UNLIKELY(f->n + n > ARRAYLEN(f->p))) { if (UNLIKELY(f->n + n > ARRAYLEN(f->p))) notpossible;
AbortPledge("need to increase array size");
}
MemCpy(f->p + f->n, p, n * sizeof(*f->p)); MemCpy(f->p + f->n, p, n * sizeof(*f->p));
f->n += n; f->n += n;
} }
@ -1857,7 +1851,7 @@ static privileged void AppendPledge(struct Filter *f, //
}; };
AppendFilter(f, PLEDGE(fragment)); AppendFilter(f, PLEDGE(fragment));
} else { } else {
AbortPledge("list of ordinals exceeds max displacement"); notpossible;
} }
} }
@ -1953,7 +1947,7 @@ static privileged void AppendPledge(struct Filter *f, //
AllowTkillSelf(f); AllowTkillSelf(f);
break; break;
default: default:
AbortPledge("switch forgot to define a special ordinal"); notpossible;
} }
} }
} }
@ -1987,7 +1981,7 @@ privileged int sys_pledge_linux(unsigned long ipromises, int mode) {
if (kPledge[i].len) { if (kPledge[i].len) {
AppendPledge(&f, kPledge[i].syscalls, kPledge[i].len); AppendPledge(&f, kPledge[i].syscalls, kPledge[i].len);
} else { } else {
AbortPledge("bad ipromises"); notpossible;
} }
} }
} }
@ -2020,7 +2014,7 @@ privileged int sys_pledge_linux(unsigned long ipromises, int mode) {
sf[0].k = SECCOMP_RET_ERRNO | Eperm; sf[0].k = SECCOMP_RET_ERRNO | Eperm;
break; break;
default: default:
unreachable; return -Einval;
} }
AppendFilter(&f, PLEDGE(sf)); AppendFilter(&f, PLEDGE(sf));
} }

View file

@ -531,5 +531,5 @@ privileged void __sigenter_xnu(void *fn, int infostyle, int sig,
: "=a"(ax) : "=a"(ax)
: "0"(0x20000b8 /* sigreturn */), "D"(xnuctx), "S"(infostyle) : "0"(0x20000b8 /* sigreturn */), "D"(xnuctx), "S"(infostyle)
: "rcx", "r11", "memory", "cc"); : "rcx", "r11", "memory", "cc");
unreachable; notpossible;
} }

View file

@ -281,8 +281,7 @@ void statfs2cosmo(struct statfs *f, const union statfs_meta *m) {
memcpy(f_fstypename, m->netbsd.f_fstypename, 16); memcpy(f_fstypename, m->netbsd.f_fstypename, 16);
} else { } else {
asm("hlt"); notpossible;
unreachable;
} }
f->f_type = f_type; f->f_type = f_type;

View file

@ -98,8 +98,7 @@ int tmpfd(void) {
0600)) != -1) { 0600)) != -1) {
if (!IsWindows()) { if (!IsWindows()) {
if (unlink(path)) { if (unlink(path)) {
asm("hlt"); notpossible;
unreachable;
} }
} }
return fd; return fd;

View file

@ -591,6 +591,12 @@ typedef struct {
#endif #endif
#endif #endif
#define notpossible \
do { \
asm("hlt"); \
unreachable; \
} while (0)
#define donothing \ #define donothing \
do { \ do { \
} while (0) } while (0)

View file

@ -40,6 +40,5 @@ wontreturn void abort(void) {
raise(SIGABRT); raise(SIGABRT);
signal(SIGABRT, SIG_DFL); signal(SIGABRT, SIG_DFL);
raise(SIGABRT); raise(SIGABRT);
asm("hlt"); notpossible;
unreachable;
} }

View file

@ -66,8 +66,7 @@
do { \ do { \
if (UNLIKELY((x) == -1)) { \ if (UNLIKELY((x) == -1)) { \
DEBUG("%s:%d: %s failed %m\n", __FILE__, __LINE__, #x); \ DEBUG("%s:%d: %s failed %m\n", __FILE__, __LINE__, #x); \
asm("hlt"); \ notpossible; \
unreachable; \
} \ } \
} while (0) } while (0)

View file

@ -117,6 +117,7 @@ Keywords={
"reallocesque", "reallocesque",
"nullterminated", "nullterminated",
"unreachable", "unreachable",
"notpossible",
"hidden", "hidden",
"privileged", "privileged",
"hasatleast", "hasatleast",

View file

@ -61,6 +61,7 @@
"reallocesque" "reallocesque"
"nullterminated" "nullterminated"
"unreachable" "unreachable"
"notpossible"
"hidden" "hidden"
"privileged" "privileged"
"hasatleast" "hasatleast"

View file

@ -378,6 +378,7 @@ cosmo_kws = frozenset([
"threadlocal", "threadlocal",
"typeof", "typeof",
"unreachable", "unreachable",
"notpossible",
"warnifused", "warnifused",
"winstruct", "winstruct",
"nocallersavedregisters", "nocallersavedregisters",
@ -440,6 +441,7 @@ cosmo_kws = frozenset([
"threadlocal", "threadlocal",
"typeof", "typeof",
"unreachable", "unreachable",
"notpossible",
"warnifused", "warnifused",
"winstruct", "winstruct",
"nocallersavedregisters", "nocallersavedregisters",