From f3ad68446455acbe562e0057931e6256b8b991e8 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Mon, 22 Jul 2019 11:59:00 +0200 Subject: [PATCH] executor: drop CAP_SYS_NICE 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 --- executor/common_linux.h | 16 ++++++++++++---- pkg/csource/generated.go | 2 +- sys/linux/test/caps | 3 +++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/executor/common_linux.h b/executor/common_linux.h index 682425a3dc4..2d36b998ecb 100644 --- a/executor/common_linux.h +++ b/executor/common_linux.h @@ -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; diff --git a/pkg/csource/generated.go b/pkg/csource/generated.go index eb863e8e19b..58ccf11b00f 100644 --- a/pkg/csource/generated.go +++ b/pkg/csource/generated.go @@ -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; diff --git a/sys/linux/test/caps b/sys/linux/test/caps index f3ef3a9e025..6f580210e28 100644 --- a/sys/linux/test/caps +++ b/sys/linux/test/caps @@ -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)