Skip to content

Commit

Permalink
executor: drop CAP_SYS_NICE
Browse files Browse the repository at this point in the history
A process with CAP_SYS_NICE can bring kernel down by asking for too high SCHED_DEADLINE priority,
as the result rcu and other system services that use kernel threads will stop functioning.
Some parameters for SCHED_DEADLINE should be OK, but we don't have means to enforce
values of indirect syscall arguments. Peter Zijlstra proposed sysctl_deadline_period_{min,max}
which could be used to enfore safe limits without droppping CAP_SYS_NICE, but we don't have it yet.
See the following bug for details:
https://groups.google.com/forum/#!topic/syzkaller-bugs/G6Wl_PKPIWI
  • Loading branch information
dvyukov committed Jul 22, 2019
1 parent be348f6 commit f3ad684
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 5 deletions.
16 changes: 12 additions & 4 deletions executor/common_linux.h
Expand Up @@ -1981,16 +1981,24 @@ int wait_for_loop(int pid)

static void drop_caps(void)
{
// Drop CAP_SYS_PTRACE so that test processes can't attach to parent processes.
// Previously it lead to hangs because the loop process stopped due to SIGSTOP.
// Note that a process can always ptrace its direct children, which is enough for testing purposes.
struct __user_cap_header_struct cap_hdr = {};
struct __user_cap_data_struct cap_data[2] = {};
cap_hdr.version = _LINUX_CAPABILITY_VERSION_3;
cap_hdr.pid = getpid();
if (syscall(SYS_capget, &cap_hdr, &cap_data))
fail("capget failed");
const int drop = (1 << CAP_SYS_PTRACE);
// Drop CAP_SYS_PTRACE so that test processes can't attach to parent processes.
// Previously it lead to hangs because the loop process stopped due to SIGSTOP.
// Note that a process can always ptrace its direct children, which is enough for testing purposes.
//
// A process with CAP_SYS_NICE can bring kernel down by asking for too high SCHED_DEADLINE priority,
// as the result rcu and other system services that use kernel threads will stop functioning.
// Some parameters for SCHED_DEADLINE should be OK, but we don't have means to enforce
// values of indirect syscall arguments. Peter Zijlstra proposed sysctl_deadline_period_{min,max}
// which could be used to enfore safe limits without droppping CAP_SYS_NICE, but we don't have it yet.
// See the following bug for details:
// https://groups.google.com/forum/#!topic/syzkaller-bugs/G6Wl_PKPIWI
const int drop = (1 << CAP_SYS_PTRACE) | (1 << CAP_SYS_NICE);
cap_data[0].effective &= ~drop;
cap_data[0].permitted &= ~drop;
cap_data[0].inheritable &= ~drop;
Expand Down
2 changes: 1 addition & 1 deletion pkg/csource/generated.go
Expand Up @@ -4441,7 +4441,7 @@ static void drop_caps(void)
cap_hdr.pid = getpid();
if (syscall(SYS_capget, &cap_hdr, &cap_data))
fail("capget failed");
const int drop = (1 << CAP_SYS_PTRACE);
const int drop = (1 << CAP_SYS_PTRACE) | (1 << CAP_SYS_NICE);
cap_data[0].effective &= ~drop;
cap_data[0].permitted &= ~drop;
cap_data[0].inheritable &= ~drop;
Expand Down
3 changes: 3 additions & 0 deletions sys/linux/test/caps
Expand Up @@ -3,3 +3,6 @@
# requires: -sandbox=

ptrace(0x10, 0x1) # EPERM
sched_setattr(0x0, &AUTO={AUTO, 0x6, 0x0, 0x0, 0x0, 0x8000000009917, 0x400000000000fffd, 0x0}, 0x0) # EPERM
sched_setattr(0x0, &AUTO={AUTO, 0x0, 0x0, 0xffffffffffffffff, 0x0, 0x0, 0x0, 0x0}, 0x0) # EPERM
sched_setattr(0x0, &AUTO={AUTO, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0}, 0x0)

0 comments on commit f3ad684

Please sign in to comment.