mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-27 14:58:30 +00:00
Fix pledge to process lists with zero index syscalls (#402)
This commit is contained in:
parent
15c59e716f
commit
b30f5c0c4f
1 changed files with 25 additions and 34 deletions
|
@ -33,7 +33,6 @@
|
||||||
static const uint16_t kPledgeLinuxDefault[] = {
|
static const uint16_t kPledgeLinuxDefault[] = {
|
||||||
__NR_linux_exit, //
|
__NR_linux_exit, //
|
||||||
__NR_linux_exit_group, //
|
__NR_linux_exit_group, //
|
||||||
0, //
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint16_t kPledgeLinuxStdio[] = {
|
static const uint16_t kPledgeLinuxStdio[] = {
|
||||||
|
@ -96,7 +95,6 @@ static const uint16_t kPledgeLinuxStdio[] = {
|
||||||
__NR_linux_wait4, //
|
__NR_linux_wait4, //
|
||||||
__NR_linux_write, //
|
__NR_linux_write, //
|
||||||
__NR_linux_writev, //
|
__NR_linux_writev, //
|
||||||
0, //
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint16_t kPledgeLinuxRpath[] = {
|
static const uint16_t kPledgeLinuxRpath[] = {
|
||||||
|
@ -114,7 +112,6 @@ static const uint16_t kPledgeLinuxRpath[] = {
|
||||||
__NR_linux_fchown, //
|
__NR_linux_fchown, //
|
||||||
__NR_linux_fchownat, //
|
__NR_linux_fchownat, //
|
||||||
__NR_linux_fstat, //
|
__NR_linux_fstat, //
|
||||||
0, //
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint16_t kPledgeLinuxWpath[] = {
|
static const uint16_t kPledgeLinuxWpath[] = {
|
||||||
|
@ -131,7 +128,6 @@ static const uint16_t kPledgeLinuxWpath[] = {
|
||||||
__NR_linux_fchown, //
|
__NR_linux_fchown, //
|
||||||
__NR_linux_fchownat, //
|
__NR_linux_fchownat, //
|
||||||
__NR_linux_fstat, //
|
__NR_linux_fstat, //
|
||||||
0, //
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint16_t kPledgeLinuxCpath[] = {
|
static const uint16_t kPledgeLinuxCpath[] = {
|
||||||
|
@ -146,12 +142,10 @@ static const uint16_t kPledgeLinuxCpath[] = {
|
||||||
__NR_linux_mkdir, //
|
__NR_linux_mkdir, //
|
||||||
__NR_linux_mkdirat, //
|
__NR_linux_mkdirat, //
|
||||||
__NR_linux_rmdir, //
|
__NR_linux_rmdir, //
|
||||||
0, //
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint16_t kPledgeLinuxDpath[] = {
|
static const uint16_t kPledgeLinuxDpath[] = {
|
||||||
__NR_linux_mknod, //
|
__NR_linux_mknod, //
|
||||||
0, //
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint16_t kPledgeLinuxTmppath[] = {
|
static const uint16_t kPledgeLinuxTmppath[] = {
|
||||||
|
@ -160,7 +154,6 @@ static const uint16_t kPledgeLinuxTmppath[] = {
|
||||||
__NR_linux_chown, //
|
__NR_linux_chown, //
|
||||||
__NR_linux_unlink, //
|
__NR_linux_unlink, //
|
||||||
__NR_linux_fstat, //
|
__NR_linux_fstat, //
|
||||||
0, //
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint16_t kPledgeLinuxInet[] = {
|
static const uint16_t kPledgeLinuxInet[] = {
|
||||||
|
@ -174,7 +167,6 @@ static const uint16_t kPledgeLinuxInet[] = {
|
||||||
__NR_linux_getsockname, //
|
__NR_linux_getsockname, //
|
||||||
__NR_linux_setsockopt, //
|
__NR_linux_setsockopt, //
|
||||||
__NR_linux_getsockopt, //
|
__NR_linux_getsockopt, //
|
||||||
0, //
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint16_t kPledgeLinuxFattr[] = {
|
static const uint16_t kPledgeLinuxFattr[] = {
|
||||||
|
@ -188,7 +180,6 @@ static const uint16_t kPledgeLinuxFattr[] = {
|
||||||
__NR_linux_lchown, //
|
__NR_linux_lchown, //
|
||||||
__NR_linux_fchown, //
|
__NR_linux_fchown, //
|
||||||
__NR_linux_utimes, //
|
__NR_linux_utimes, //
|
||||||
0, //
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint16_t kPledgeLinuxUnix[] = {
|
static const uint16_t kPledgeLinuxUnix[] = {
|
||||||
|
@ -202,7 +193,6 @@ static const uint16_t kPledgeLinuxUnix[] = {
|
||||||
__NR_linux_getsockname, //
|
__NR_linux_getsockname, //
|
||||||
__NR_linux_setsockopt, //
|
__NR_linux_setsockopt, //
|
||||||
__NR_linux_getsockopt, //
|
__NR_linux_getsockopt, //
|
||||||
0, //
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint16_t kPledgeLinuxDns[] = {
|
static const uint16_t kPledgeLinuxDns[] = {
|
||||||
|
@ -210,7 +200,6 @@ static const uint16_t kPledgeLinuxDns[] = {
|
||||||
__NR_linux_recvfrom, //
|
__NR_linux_recvfrom, //
|
||||||
__NR_linux_socket, //
|
__NR_linux_socket, //
|
||||||
__NR_linux_connect, //
|
__NR_linux_connect, //
|
||||||
0, //
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint16_t kPledgeLinuxProc[] = {
|
static const uint16_t kPledgeLinuxProc[] = {
|
||||||
|
@ -222,12 +211,10 @@ static const uint16_t kPledgeLinuxProc[] = {
|
||||||
__NR_linux_setrlimit, //
|
__NR_linux_setrlimit, //
|
||||||
__NR_linux_setpgid, //
|
__NR_linux_setpgid, //
|
||||||
__NR_linux_setsid, //
|
__NR_linux_setsid, //
|
||||||
0, //
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint16_t kPledgeLinuxExec[] = {
|
static const uint16_t kPledgeLinuxExec[] = {
|
||||||
__NR_linux_execve, //
|
__NR_linux_execve, //
|
||||||
0, //
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint16_t kPledgeLinuxId[] = {
|
static const uint16_t kPledgeLinuxId[] = {
|
||||||
|
@ -241,27 +228,29 @@ static const uint16_t kPledgeLinuxId[] = {
|
||||||
__NR_linux_setrlimit, //
|
__NR_linux_setrlimit, //
|
||||||
__NR_linux_getpriority, //
|
__NR_linux_getpriority, //
|
||||||
__NR_linux_setpriority, //
|
__NR_linux_setpriority, //
|
||||||
0, //
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define PLEDGELEN(pledge) pledge, ARRAYLEN(pledge)
|
||||||
|
|
||||||
static const struct Pledges {
|
static const struct Pledges {
|
||||||
const char *name;
|
const char *name;
|
||||||
const uint16_t *syscalls;
|
const uint16_t *syscalls;
|
||||||
|
const size_t len;
|
||||||
} kPledgeLinux[] = {
|
} kPledgeLinux[] = {
|
||||||
{"default", kPledgeLinuxDefault}, //
|
{"default", PLEDGELEN(kPledgeLinuxDefault)}, //
|
||||||
{"stdio", kPledgeLinuxStdio}, //
|
{"stdio", PLEDGELEN(kPledgeLinuxStdio)}, //
|
||||||
{"rpath", kPledgeLinuxRpath}, //
|
{"rpath", PLEDGELEN(kPledgeLinuxRpath)}, //
|
||||||
{"wpath", kPledgeLinuxWpath}, //
|
{"wpath", PLEDGELEN(kPledgeLinuxWpath)}, //
|
||||||
{"cpath", kPledgeLinuxCpath}, //
|
{"cpath", PLEDGELEN(kPledgeLinuxCpath)}, //
|
||||||
{"dpath", kPledgeLinuxDpath}, //
|
{"dpath", PLEDGELEN(kPledgeLinuxDpath)}, //
|
||||||
{"tmppath", kPledgeLinuxTmppath}, //
|
{"tmppath", PLEDGELEN(kPledgeLinuxTmppath)}, //
|
||||||
{"inet", kPledgeLinuxInet}, //
|
{"inet", PLEDGELEN(kPledgeLinuxInet)}, //
|
||||||
{"fattr", kPledgeLinuxFattr}, //
|
{"fattr", PLEDGELEN(kPledgeLinuxFattr)}, //
|
||||||
{"unix", kPledgeLinuxUnix}, //
|
{"unix", PLEDGELEN(kPledgeLinuxUnix)}, //
|
||||||
{"dns", kPledgeLinuxDns}, //
|
{"dns", PLEDGELEN(kPledgeLinuxDns)}, //
|
||||||
{"proc", kPledgeLinuxProc}, //
|
{"proc", PLEDGELEN(kPledgeLinuxProc)}, //
|
||||||
{"exec", kPledgeLinuxExec}, //
|
{"exec", PLEDGELEN(kPledgeLinuxExec)}, //
|
||||||
{"id", kPledgeLinuxId}, //
|
{"id", PLEDGELEN(kPledgeLinuxId)}, //
|
||||||
{0}, //
|
{0}, //
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -290,9 +279,9 @@ static bool AppendFilter(struct Filter *f, struct sock_filter *p, size_t n) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool AppendPledge(struct Filter *f, const uint16_t *p) {
|
static bool AppendPledge(struct Filter *f, const uint16_t *p, size_t len) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; p[i]; ++i) {
|
for (i = 0; i < len; ++i) {
|
||||||
struct sock_filter fragment[] = {_SECCOMP_ALLOW_SYSCALL(p[i])};
|
struct sock_filter fragment[] = {_SECCOMP_ALLOW_SYSCALL(p[i])};
|
||||||
if (!AppendFilter(f, fragment, ARRAYLEN(fragment))) {
|
if (!AppendFilter(f, fragment, ARRAYLEN(fragment))) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -301,10 +290,11 @@ static bool AppendPledge(struct Filter *f, const uint16_t *p) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint16_t *FindPledge(const struct Pledges *p, const char *name) {
|
static const uint16_t *FindPledge(const struct Pledges *p, const char *name, size_t *len) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; p[i].name; ++i) {
|
for (i = 0; p[i].name; ++i) {
|
||||||
if (!strcasecmp(name, p[i].name)) {
|
if (!strcasecmp(name, p[i].name)) {
|
||||||
|
*len = p[i].len;
|
||||||
return p[i].syscalls;
|
return p[i].syscalls;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -314,20 +304,21 @@ static const uint16_t *FindPledge(const struct Pledges *p, const char *name) {
|
||||||
static int sys_pledge_linux(const char *promises, const char *execpromises) {
|
static int sys_pledge_linux(const char *promises, const char *execpromises) {
|
||||||
bool ok;
|
bool ok;
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
|
size_t plen;
|
||||||
struct Filter f = {0};
|
struct Filter f = {0};
|
||||||
const uint16_t *pledge;
|
const uint16_t *pledge;
|
||||||
char *s, *tok, *state, *start;
|
char *s, *tok, *state, *start;
|
||||||
if (execpromises) return einval();
|
if (execpromises) return einval();
|
||||||
if ((start = s = strdup(promises)) &&
|
if ((start = s = strdup(promises)) &&
|
||||||
AppendFilter(&f, kFilterStart, ARRAYLEN(kFilterStart)) &&
|
AppendFilter(&f, kFilterStart, ARRAYLEN(kFilterStart)) &&
|
||||||
AppendPledge(&f, kPledgeLinuxDefault)) {
|
AppendPledge(&f, kPledgeLinuxDefault, ARRAYLEN(kPledgeLinuxDefault))) {
|
||||||
for (ok = true; (tok = strtok_r(start, " \t\r\n", &state)); start = 0) {
|
for (ok = true; (tok = strtok_r(start, " \t\r\n", &state)); start = 0) {
|
||||||
if (!(pledge = FindPledge(kPledgeLinux, tok))) {
|
if (!(pledge = FindPledge(kPledgeLinux, tok, &plen))) {
|
||||||
ok = false;
|
ok = false;
|
||||||
rc = einval();
|
rc = einval();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!AppendPledge(&f, pledge)) {
|
if (!AppendPledge(&f, pledge, plen)) {
|
||||||
ok = false;
|
ok = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue