Skip to content

Commit

Permalink
executor: drop CAP_SYS_PTRACE with sandbox=none
Browse files Browse the repository at this point in the history
We only drop CAP_SYS_PTRACE for sandbox=namespace,
but it can equally affect testing with sandbox=none.
Drop it for sandbox=none, add a test.
  • Loading branch information
dvyukov committed Jul 22, 2019
1 parent e530ec1 commit 5181b54
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 29 deletions.
42 changes: 25 additions & 17 deletions executor/common_linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -1976,6 +1976,29 @@ int wait_for_loop(int pid)
}
#endif

#if SYZ_EXECUTOR || SYZ_SANDBOX_NONE || SYZ_SANDBOX_NAMESPACE
#include <linux/capability.h>

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);
cap_data[0].effective &= ~drop;
cap_data[0].permitted &= ~drop;
cap_data[0].inheritable &= ~drop;
if (syscall(SYS_capset, &cap_hdr, &cap_data))
fail("capset failed");
}
#endif

#if SYZ_EXECUTOR || SYZ_SANDBOX_NONE
#include <sched.h>
#include <sys/types.h>
Expand All @@ -1997,6 +2020,7 @@ static int do_sandbox_none(void)

setup_common();
sandbox_common();
drop_caps();
#if SYZ_EXECUTOR || SYZ_ENABLE_NETDEV
initialize_netdevices_init();
#endif
Expand Down Expand Up @@ -2063,7 +2087,6 @@ static int do_sandbox_setuid(void)
#endif

#if SYZ_EXECUTOR || SYZ_SANDBOX_NAMESPACE
#include <linux/capability.h>
#include <sched.h>
#include <sys/mman.h>
#include <sys/mount.h>
Expand Down Expand Up @@ -2151,22 +2174,7 @@ static int namespace_sandbox_proc(void* arg)
fail("chroot failed");
if (chdir("/"))
fail("chdir failed");

// 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");
cap_data[0].effective &= ~(1 << CAP_SYS_PTRACE);
cap_data[0].permitted &= ~(1 << CAP_SYS_PTRACE);
cap_data[0].inheritable &= ~(1 << CAP_SYS_PTRACE);
if (syscall(SYS_capset, &cap_hdr, &cap_data))
fail("capset failed");
drop_caps();

loop();
doexit(1);
Expand Down
34 changes: 22 additions & 12 deletions pkg/csource/generated.go
Original file line number Diff line number Diff line change
Expand Up @@ -4430,6 +4430,26 @@ int wait_for_loop(int pid)
}
#endif
#if SYZ_EXECUTOR || SYZ_SANDBOX_NONE || SYZ_SANDBOX_NAMESPACE
#include <linux/capability.h>
static void drop_caps(void)
{
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);
cap_data[0].effective &= ~drop;
cap_data[0].permitted &= ~drop;
cap_data[0].inheritable &= ~drop;
if (syscall(SYS_capset, &cap_hdr, &cap_data))
fail("capset failed");
}
#endif
#if SYZ_EXECUTOR || SYZ_SANDBOX_NONE
#include <sched.h>
#include <sys/types.h>
Expand All @@ -4445,6 +4465,7 @@ static int do_sandbox_none(void)
setup_common();
sandbox_common();
drop_caps();
#if SYZ_EXECUTOR || SYZ_ENABLE_NETDEV
initialize_netdevices_init();
#endif
Expand Down Expand Up @@ -4507,7 +4528,6 @@ static int do_sandbox_setuid(void)
#endif
#if SYZ_EXECUTOR || SYZ_SANDBOX_NAMESPACE
#include <linux/capability.h>
#include <sched.h>
#include <sys/mman.h>
#include <sys/mount.h>
Expand Down Expand Up @@ -4585,17 +4605,7 @@ static int namespace_sandbox_proc(void* arg)
fail("chroot failed");
if (chdir("/"))
fail("chdir failed");
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");
cap_data[0].effective &= ~(1 << CAP_SYS_PTRACE);
cap_data[0].permitted &= ~(1 << CAP_SYS_PTRACE);
cap_data[0].inheritable &= ~(1 << CAP_SYS_PTRACE);
if (syscall(SYS_capset, &cap_hdr, &cap_data))
fail("capset failed");
drop_caps();
loop();
doexit(1);
Expand Down
5 changes: 5 additions & 0 deletions sys/linux/test/caps
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Ensure that test processes don't have capabilities to do dangerious things,
# see drop_caps function in executor for details.
# requires: -sandbox=

ptrace(0x10, 0x1) # EPERM
1 change: 1 addition & 0 deletions sys/linux/test/vusb
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@

# Temporary disabled because deserialization fails (run go test ./pkg/csource).
#syz_usb_connect(0x0, 0x24, &(0x7f0000000000)={0x12, 0x1, 0x0, 0x97, 0xff, 0x82, 0x8, 0x2058, 0x1005, 0xc19b, 0x0, 0x0, 0x0, 0x1, [{0x9, 0x2, 0x12, 0x1, 0x0, 0x0, 0x0, 0x0, [{0x9, 0x4, 0x8f, 0x0, 0x0, 0xbf, 0x57, 0x5a, 0x0, [], []}]}]}, 0x0)

getpid()

0 comments on commit 5181b54

Please sign in to comment.