Chromium Code Reviews| Index: sandbox/linux/services/yama.cc |
| diff --git a/sandbox/linux/services/yama.cc b/sandbox/linux/services/yama.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..101590861ded6b922789ea795dd25d73afb2605a |
| --- /dev/null |
| +++ b/sandbox/linux/services/yama.cc |
| @@ -0,0 +1,107 @@ |
| +// Copyright 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "sandbox/linux/services/yama.h" |
| + |
| +#include <fcntl.h> |
| +#include <sys/prctl.h> |
| +#include <sys/stat.h> |
| +#include <sys/types.h> |
| +#include <unistd.h> |
| + |
| +#include "base/basictypes.h" |
| +#include "base/file_util.h" |
| +#include "base/logging.h" |
| +#include "base/posix/eintr_wrapper.h" |
| + |
| +namespace sandbox { |
| + |
| +namespace { |
| + |
| +// Enable or disable the Yama ptracers restrictions. |
| +// Return false if Yama is not present on this kernel. |
| +bool SetYamaPtracersRestriction(bool enabled) { |
| + unsigned long set_ptracer_arg; |
| + if (enabled) { |
| + set_ptracer_arg = 0; |
| + } else { |
| + set_ptracer_arg = PR_SET_PTRACER_ANY; |
|
Kees Cook
2014/03/06 00:49:30
PR_SET_PTRACE_ANY is an extreme disabling state --
jln (very slow on Chromium)
2014/03/06 05:06:08
This is mostly for testing.
I've added a comment
|
| + } |
| + |
| + const int ret = prctl(PR_SET_PTRACER, set_ptracer_arg); |
| + const int prctl_errno = errno; |
| + |
| + if (0 == ret) { |
| + return true; |
| + } else { |
| + // This means Yama is not available on this kernel and should be the |
| + // only possibility of failure. |
| + CHECK(ENOSYS == prctl_errno || EINVAL == prctl_errno); |
| + return false; |
| + } |
| +} |
| + |
| +bool CanAccessProcFS() { |
| + const char kProcfsKernelSysPath[] = "/proc/sys/kernel/"; |
|
mdempsky
2014/03/06 01:56:28
Can this be made static? (kPtraceScopePath below
jln (very slow on Chromium)
2014/03/06 05:06:08
Done.
|
| + struct stat buf; |
| + int ret = stat(kProcfsKernelSysPath, &buf); |
|
mdempsky
2014/03/06 01:56:28
Since you don't care about the 'stat' buf, would a
jln (very slow on Chromium)
2014/03/06 05:06:08
Done.
|
| + if (ret) { |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| +} // namespace |
| + |
| +// static |
| +bool Yama::RestrictPtracersToAncestors() { |
| + return SetYamaPtracersRestriction(true /* enabled */); |
| +} |
| + |
| +// static |
| +bool Yama::DisableYamaRestrictions() { |
| + return SetYamaPtracersRestriction(false /* enabled */); |
| +} |
| + |
| +// static |
| +Yama::GlobalStatus Yama::GetStatus() { |
| + if (!CanAccessProcFS()) { |
| + return STATUS_DONT_KNOW; |
| + } |
| + |
| + const char kPtraceScopePath[] = "/proc/sys/kernel/yama/ptrace_scope"; |
| + |
| + int yama_scope = open(kPtraceScopePath, O_RDONLY); |
| + |
| + if (yama_scope < 0) { |
| + const int open_errno = errno; |
| + DCHECK(ENOENT == open_errno); |
| + return STATUS_NOT_PRESENT; |
| + } |
| + |
| + file_util::ScopedFDCloser yama_scope_closer(&yama_scope); |
| + char yama_scope_value = 0; |
| + ssize_t num_read = read(yama_scope, &yama_scope_value, 1); |
| + PCHECK(1 == num_read); |
| + |
| + switch (yama_scope_value) { |
| + case '0': |
| + return STATUS_NOT_ENFORCING; |
| + case '1': |
| + case '2': |
| + case '3': |
| + return STATUS_ENFORCING; |
| + default: |
| + NOTREACHED(); |
| + return STATUS_DONT_KNOW; |
| + } |
| +} |
| + |
| +// static |
| +bool Yama::IsAvailable() { |
| + const GlobalStatus status = GetStatus(); |
| + return (STATUS_NOT_ENFORCING == status) || (STATUS_ENFORCING == status); |
| +} |
| + |
| +} // namespace sandbox |