summaryrefslogtreecommitdiffstats
path: root/sandbox
diff options
context:
space:
mode:
authorjln@chromium.org <jln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-29 18:42:09 +0000
committerjln@chromium.org <jln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-29 18:42:09 +0000
commitf700f51f5aafb24272990444d5ca392004d7e19f (patch)
treefa37318673b658ede829a34661d8f41be2db764d /sandbox
parentaf3486d738af606f6c9bdc267c2b9e3abab28a21 (diff)
downloadchromium_src-f700f51f5aafb24272990444d5ca392004d7e19f.zip
chromium_src-f700f51f5aafb24272990444d5ca392004d7e19f.tar.gz
chromium_src-f700f51f5aafb24272990444d5ca392004d7e19f.tar.bz2
Linux sandbox: restrict *kill to the current process.
Restrict tgkill(2) and kill(2) to the current process, forbid tkill. BUG=367986 R=jorgelo@chromium.org Review URL: https://codereview.chromium.org/258073008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@266926 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox')
-rw-r--r--sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc31
-rw-r--r--sandbox/linux/seccomp-bpf-helpers/baseline_policy.h7
-rw-r--r--sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.cc17
-rw-r--r--sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h3
-rw-r--r--sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc16
-rw-r--r--sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h7
-rw-r--r--sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc3
7 files changed, 73 insertions, 11 deletions
diff --git a/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc b/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc
index c72b53a..508ae3e 100644
--- a/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc
+++ b/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc
@@ -6,8 +6,10 @@
#include <errno.h>
#include <sys/mman.h>
-#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <unistd.h>
#include "base/logging.h"
#include "build/build_config.h"
@@ -42,7 +44,6 @@ bool IsBaselinePolicyAllowed(int sysno) {
#if defined(__arm__)
SyscallSets::IsArmPrivate(sysno) ||
#endif
- SyscallSets::IsKill(sysno) ||
SyscallSets::IsAllowedOperationOnFd(sysno);
}
@@ -63,6 +64,7 @@ bool IsBaselinePolicyWatched(int sysno) {
SyscallSets::IsInotify(sysno) ||
SyscallSets::IsKernelModule(sysno) ||
SyscallSets::IsKeyManagement(sysno) ||
+ SyscallSets::IsKill(sysno) ||
SyscallSets::IsMessageQueue(sysno) ||
SyscallSets::IsMisc(sysno) ||
#if defined(__x86_64__)
@@ -80,7 +82,9 @@ bool IsBaselinePolicyWatched(int sysno) {
}
// |fs_denied_errno| is the errno return for denied filesystem access.
-ErrorCode EvaluateSyscallImpl(int fs_denied_errno, SandboxBPF* sandbox,
+ErrorCode EvaluateSyscallImpl(int fs_denied_errno,
+ pid_t current_pid,
+ SandboxBPF* sandbox,
int sysno) {
if (IsBaselinePolicyAllowed(sysno)) {
return ErrorCode(ErrorCode::ERR_ALLOWED);
@@ -125,6 +129,10 @@ ErrorCode EvaluateSyscallImpl(int fs_denied_errno, SandboxBPF* sandbox,
return RestrictFcntlCommands(sandbox);
#endif
+ if (SyscallSets::IsKill(sysno)) {
+ return RestrictKillTarget(current_pid, sandbox, sysno);
+ }
+
if (SyscallSets::IsFileSystem(sysno) ||
SyscallSets::IsCurrentDirectory(sysno)) {
return ErrorCode(fs_denied_errno);
@@ -151,6 +159,7 @@ ErrorCode EvaluateSyscallImpl(int fs_denied_errno, SandboxBPF* sandbox,
// be denied gracefully right away.
return sandbox->Trap(CrashSIGSYS_Handler, NULL);
}
+
// In any other case crash the program with our SIGSYS handler.
return sandbox->Trap(CrashSIGSYS_Handler, NULL);
}
@@ -160,16 +169,24 @@ ErrorCode EvaluateSyscallImpl(int fs_denied_errno, SandboxBPF* sandbox,
// Unfortunately C++03 doesn't allow delegated constructors.
// Call other constructor when C++11 lands.
BaselinePolicy::BaselinePolicy()
- : fs_denied_errno_(EPERM) {}
+ : fs_denied_errno_(EPERM), current_pid_(syscall(__NR_getpid)) {}
BaselinePolicy::BaselinePolicy(int fs_denied_errno)
- : fs_denied_errno_(fs_denied_errno) {}
+ : fs_denied_errno_(fs_denied_errno), current_pid_(syscall(__NR_getpid)) {}
-BaselinePolicy::~BaselinePolicy() {}
+BaselinePolicy::~BaselinePolicy() {
+ // Make sure that this policy is created, used and destroyed by a single
+ // process.
+ DCHECK_EQ(syscall(__NR_getpid), current_pid_);
+}
ErrorCode BaselinePolicy::EvaluateSyscall(SandboxBPF* sandbox,
int sysno) const {
- return EvaluateSyscallImpl(fs_denied_errno_, sandbox, sysno);
+ // Make sure that this policy is used in the creating process.
+ if (1 == sysno) {
+ DCHECK_EQ(syscall(__NR_getpid), current_pid_);
+ }
+ return EvaluateSyscallImpl(fs_denied_errno_, current_pid_, sandbox, sysno);
}
} // namespace sandbox.
diff --git a/sandbox/linux/seccomp-bpf-helpers/baseline_policy.h b/sandbox/linux/seccomp-bpf-helpers/baseline_policy.h
index f1e4bb9..fe7c5dc 100644
--- a/sandbox/linux/seccomp-bpf-helpers/baseline_policy.h
+++ b/sandbox/linux/seccomp-bpf-helpers/baseline_policy.h
@@ -18,11 +18,13 @@ class SandboxBPFPolicy;
// that reduces the Linux kernel's attack surface. Given its nature, it doesn't
// have a clear semantics and is mostly "implementation-defined".
//
-// This returns an object that implements the SandboxBPFPolicy interface with
-// a "baseline" policy within Chromium.
+// This class implements the SandboxBPFPolicy interface with a "baseline"
+// policy for us within Chromium.
// The "baseline" policy is somewhat arbitrary. All Chromium policies are an
// alteration of it, and it represents a reasonable common ground to run most
// code in a sandboxed environment.
+// A baseline policy is only valid for the process for which this object was
+// instantiated (so do not fork() and use it in a child).
class SANDBOX_EXPORT BaselinePolicy : public SandboxBPFPolicy {
public:
BaselinePolicy();
@@ -36,6 +38,7 @@ class SANDBOX_EXPORT BaselinePolicy : public SandboxBPFPolicy {
private:
int fs_denied_errno_;
+ pid_t current_pid_;
DISALLOW_COPY_AND_ASSIGN(BaselinePolicy);
};
diff --git a/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.cc b/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.cc
index 47c9989..c4a6f92 100644
--- a/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.cc
+++ b/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.cc
@@ -17,6 +17,7 @@
#define SECCOMP_MESSAGE_CLONE_CONTENT "clone() failure"
#define SECCOMP_MESSAGE_PRCTL_CONTENT "prctl() failure"
#define SECCOMP_MESSAGE_IOCTL_CONTENT "ioctl() failure"
+#define SECCOMP_MESSAGE_KILL_CONTENT "(tg)kill() failure"
namespace {
@@ -147,6 +148,22 @@ intptr_t SIGSYSIoctlFailure(const struct arch_seccomp_data& args,
_exit(1);
}
+intptr_t SIGSYSKillFailure(const struct arch_seccomp_data& args,
+ void* /* aux */) {
+ static const char kSeccompKillError[] =
+ __FILE__":**CRASHING**:" SECCOMP_MESSAGE_KILL_CONTENT "\n";
+ WriteToStdErr(kSeccompKillError, sizeof(kSeccompKillError) - 1);
+ // Make "request" volatile so that we can see it on the stack in a minidump.
+ volatile uint64_t pid = args.args[0];
+ volatile char* addr = reinterpret_cast<volatile char*>(pid & 0xFFF);
+ *addr = '\0';
+ // Hit the NULL page if this fails.
+ addr = reinterpret_cast<volatile char*>(pid & 0xFFF);
+ *addr = '\0';
+ for (;;)
+ _exit(1);
+}
+
const char* GetErrorMessageContentForTests() {
return SECCOMP_MESSAGE_COMMON_CONTENT;
}
diff --git a/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h b/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h
index b8f626a..fdfbb66 100644
--- a/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h
+++ b/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h
@@ -38,6 +38,9 @@ SANDBOX_EXPORT intptr_t
// argument.
SANDBOX_EXPORT intptr_t
SIGSYSIoctlFailure(const struct arch_seccomp_data& args, void* aux);
+// The crashing address will be (pid & 0xFFF), where pid is the first
+// argument (and can be a tid).
+intptr_t SIGSYSKillFailure(const struct arch_seccomp_data& args, void* aux);
// Following four functions return substrings of error messages used
// in the above four functions. They are useful in death tests.
diff --git a/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc b/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc
index 9b417ce..e0e1ddca 100644
--- a/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc
+++ b/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc
@@ -211,4 +211,20 @@ ErrorCode RestrictSocketcallCommand(SandboxBPF* sandbox) {
}
#endif
+ErrorCode RestrictKillTarget(pid_t target_pid, SandboxBPF* sandbox, int sysno) {
+ switch (sysno) {
+ case __NR_kill:
+ case __NR_tgkill:
+ return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
+ target_pid,
+ ErrorCode(ErrorCode::ERR_ALLOWED),
+ sandbox->Trap(SIGSYSKillFailure, NULL));
+ case __NR_tkill:
+ return sandbox->Trap(SIGSYSKillFailure, NULL);
+ default:
+ NOTREACHED();
+ return sandbox->Trap(CrashSIGSYS_Handler, NULL);
+ }
+}
+
} // namespace sandbox.
diff --git a/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h b/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h
index aa1e0d1..5283b49 100644
--- a/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h
+++ b/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h
@@ -5,6 +5,8 @@
#ifndef SANDBOX_LINUX_SECCOMP_BPF_HELPERS_SYSCALL_PARAMETERS_RESTRICTIONS_H_
#define SANDBOX_LINUX_SECCOMP_BPF_HELPERS_SYSCALL_PARAMETERS_RESTRICTIONS_H_
+#include <unistd.h>
+
#include "build/build_config.h"
#include "sandbox/linux/sandbox_export.h"
@@ -55,6 +57,11 @@ SANDBOX_EXPORT ErrorCode RestrictFcntlCommands(SandboxBPF* sandbox);
SANDBOX_EXPORT ErrorCode RestrictSocketcallCommand(SandboxBPF* sandbox);
#endif
+// Restrict |sysno| (which must be kill, tkill or tgkill) by allowing tgkill or
+// kill iff the first parameter is |target_pid|, crashing otherwise or if
+// |sysno| is tkill.
+ErrorCode RestrictKillTarget(pid_t target_pid, SandboxBPF* sandbox, int sysno);
+
} // namespace sandbox.
#endif // SANDBOX_LINUX_SECCOMP_BPF_HELPERS_SYSCALL_PARAMETERS_RESTRICTIONS_H_
diff --git a/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc b/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc
index 032f6c3..792807a 100644
--- a/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc
+++ b/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc
@@ -14,12 +14,11 @@ namespace sandbox {
// The implicitly defined sets form a partition of the sets of
// system calls.
-// TODO(jln) we need to restrict the first parameter!
bool SyscallSets::IsKill(int sysno) {
switch (sysno) {
case __NR_kill:
- case __NR_tkill:
case __NR_tgkill:
+ case __NR_tkill: // Deprecated.
return true;
default:
return false;