mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-27 14:58:30 +00:00
Fix pledge() thread killing semantics
- tkill(tid, sig) should be allowed by stdio - tgkill(getpid(), tid, sig) should be allowed by stdio Fixes #628
This commit is contained in:
parent
c7a8cd21e9
commit
1ea01fc905
2 changed files with 45 additions and 11 deletions
|
@ -540,7 +540,8 @@ static const uint16_t kPledgeStdio[] = {
|
||||||
__NR_linux_sigsuspend, //
|
__NR_linux_sigsuspend, //
|
||||||
__NR_linux_sigpending, //
|
__NR_linux_sigpending, //
|
||||||
__NR_linux_kill | SELF, //
|
__NR_linux_kill | SELF, //
|
||||||
__NR_linux_tkill | SELF, //
|
__NR_linux_tkill, //
|
||||||
|
__NR_linux_tgkill | SELF, //
|
||||||
__NR_linux_socketpair, //
|
__NR_linux_socketpair, //
|
||||||
__NR_linux_getrusage, //
|
__NR_linux_getrusage, //
|
||||||
__NR_linux_times, //
|
__NR_linux_times, //
|
||||||
|
@ -691,6 +692,7 @@ static const uint16_t kPledgeProc[] = {
|
||||||
__NR_linux_vfork, //
|
__NR_linux_vfork, //
|
||||||
__NR_linux_clone | RESTRICT, //
|
__NR_linux_clone | RESTRICT, //
|
||||||
__NR_linux_kill, //
|
__NR_linux_kill, //
|
||||||
|
__NR_linux_tgkill, //
|
||||||
__NR_linux_setsid, //
|
__NR_linux_setsid, //
|
||||||
__NR_linux_setpgid, //
|
__NR_linux_setpgid, //
|
||||||
__NR_linux_prlimit, //
|
__NR_linux_prlimit, //
|
||||||
|
@ -707,8 +709,6 @@ static const uint16_t kPledgeProc[] = {
|
||||||
__NR_linux_sched_setaffinity, //
|
__NR_linux_sched_setaffinity, //
|
||||||
__NR_linux_sched_getparam, //
|
__NR_linux_sched_getparam, //
|
||||||
__NR_linux_sched_setparam, //
|
__NR_linux_sched_setparam, //
|
||||||
__NR_linux_tkill, //
|
|
||||||
__NR_linux_tgkill, //
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint16_t kPledgeId[] = {
|
static const uint16_t kPledgeId[] = {
|
||||||
|
@ -1028,15 +1028,15 @@ static privileged void AllowKillSelf(struct Filter *f) {
|
||||||
AppendFilter(f, PLEDGE(fragment));
|
AppendFilter(f, PLEDGE(fragment));
|
||||||
}
|
}
|
||||||
|
|
||||||
// The first argument of tkill() must be
|
// The first argument of tgkill() must be
|
||||||
//
|
//
|
||||||
// - gettid()
|
// - getpid()
|
||||||
//
|
//
|
||||||
static privileged void AllowTkillSelf(struct Filter *f) {
|
static privileged void AllowTgkillSelf(struct Filter *f) {
|
||||||
struct sock_filter fragment[] = {
|
struct sock_filter fragment[] = {
|
||||||
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_tkill, 0, 4),
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_tgkill, 0, 4),
|
||||||
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])),
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])),
|
||||||
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, GetTid(), 0, 1),
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, GetPid(), 0, 1),
|
||||||
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
|
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
|
||||||
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
|
||||||
};
|
};
|
||||||
|
@ -1949,8 +1949,8 @@ static privileged void AppendPledge(struct Filter *f, //
|
||||||
case __NR_linux_kill | SELF:
|
case __NR_linux_kill | SELF:
|
||||||
AllowKillSelf(f);
|
AllowKillSelf(f);
|
||||||
break;
|
break;
|
||||||
case __NR_linux_tkill | SELF:
|
case __NR_linux_tgkill | SELF:
|
||||||
AllowTkillSelf(f);
|
AllowTgkillSelf(f);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
notpossible;
|
notpossible;
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/mem/copyfd.internal.h"
|
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/ioctl.h"
|
#include "libc/calls/ioctl.h"
|
||||||
#include "libc/calls/pledge.internal.h"
|
#include "libc/calls/pledge.internal.h"
|
||||||
|
@ -26,11 +25,14 @@
|
||||||
#include "libc/calls/struct/flock.h"
|
#include "libc/calls/struct/flock.h"
|
||||||
#include "libc/calls/struct/seccomp.h"
|
#include "libc/calls/struct/seccomp.h"
|
||||||
#include "libc/calls/struct/sigaction.h"
|
#include "libc/calls/struct/sigaction.h"
|
||||||
|
#include "libc/calls/struct/sigset.h"
|
||||||
#include "libc/calls/struct/stat.h"
|
#include "libc/calls/struct/stat.h"
|
||||||
#include "libc/calls/syscall_support-sysv.internal.h"
|
#include "libc/calls/syscall_support-sysv.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
|
#include "libc/intrin/kprintf.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
|
#include "libc/mem/copyfd.internal.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/runtime/internal.h"
|
#include "libc/runtime/internal.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
@ -53,6 +55,7 @@
|
||||||
#include "libc/sysv/consts/sock.h"
|
#include "libc/sysv/consts/sock.h"
|
||||||
#include "libc/sysv/consts/sol.h"
|
#include "libc/sysv/consts/sol.h"
|
||||||
#include "libc/testlib/ezbench.h"
|
#include "libc/testlib/ezbench.h"
|
||||||
|
#include "libc/testlib/subprocess.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
#include "libc/thread/spawn.h"
|
#include "libc/thread/spawn.h"
|
||||||
#include "libc/time/time.h"
|
#include "libc/time/time.h"
|
||||||
|
@ -143,6 +146,37 @@ TEST(pledge, withThreadMemory) {
|
||||||
EXPECT_EQ(4, job[0]); // check result
|
EXPECT_EQ(4, job[0]); // check result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool gotusr1;
|
||||||
|
|
||||||
|
void OnUsr1(int sig) {
|
||||||
|
gotusr1 = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TgkillWorker(void *arg, int tid) {
|
||||||
|
sigset_t mask;
|
||||||
|
signal(SIGUSR1, OnUsr1);
|
||||||
|
sigemptyset(&mask);
|
||||||
|
ASSERT_SYS(EINTR, -1, sigsuspend(&mask));
|
||||||
|
ASSERT_TRUE(gotusr1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(pledge, tgkill) {
|
||||||
|
// https://github.com/jart/cosmopolitan/issues/628
|
||||||
|
if (!IsLinux()) return;
|
||||||
|
sigset_t mask;
|
||||||
|
struct spawn worker;
|
||||||
|
SPAWN(fork);
|
||||||
|
sigemptyset(&mask);
|
||||||
|
sigaddset(&mask, SIGUSR1);
|
||||||
|
sigprocmask(SIG_BLOCK, &mask, 0);
|
||||||
|
ASSERT_SYS(0, 0, pledge("stdio", 0));
|
||||||
|
ASSERT_SYS(0, 0, _spawn(TgkillWorker, 0, &worker));
|
||||||
|
ASSERT_SYS(0, 0, tgkill(getpid(), worker.ptid, SIGUSR1));
|
||||||
|
ASSERT_SYS(0, 0, _join(&worker));
|
||||||
|
EXITS(0);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(pledge, stdio_forbidsOpeningPasswd1) {
|
TEST(pledge, stdio_forbidsOpeningPasswd1) {
|
||||||
if (!IsLinux()) return;
|
if (!IsLinux()) return;
|
||||||
int ws, pid;
|
int ws, pid;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue