OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <endian.h> | 5 #include <endian.h> |
6 #if __BYTE_ORDER == __BIG_ENDIAN | 6 #if __BYTE_ORDER == __BIG_ENDIAN |
7 // The BPF "struct seccomp_data" layout has to deal with storing 64bit | 7 // The BPF "struct seccomp_data" layout has to deal with storing 64bit |
8 // values that need to be inspected by a virtual machine that only ever | 8 // values that need to be inspected by a virtual machine that only ever |
9 // operates on 32bit values. The kernel developers decided how values | 9 // operates on 32bit values. The kernel developers decided how values |
10 // should be split into two 32bit words to achieve this goal. But at this | 10 // should be split into two 32bit words to achieve this goal. But at this |
11 // time, there is no existing BPF implementation in the kernel that uses | 11 // time, there is no existing BPF implementation in the kernel that uses |
12 // 64bit big endian values. So, all we have to go by is the consensus | 12 // 64bit big endian values. So, all we have to go by is the consensus |
13 // from a discussion on LKLM. Actual implementations, if and when they | 13 // from a discussion on LKLM. Actual implementations, if and when they |
14 // happen, might very well differ. | 14 // happen, might very well differ. |
15 // If this code is ever going to be used with such a kernel, you should | 15 // If this code is ever going to be used with such a kernel, you should |
16 // disable the "#error" and carefully test the code (e.g. run the unit | 16 // disable the "#error" and carefully test the code (e.g. run the unit |
17 // tests). If things don't work, search for all occurrences of __BYTE_ORDER | 17 // tests). If things don't work, search for all occurrences of __BYTE_ORDER |
18 // and verify that the proposed implementation agrees with what the kernel | 18 // and verify that the proposed implementation agrees with what the kernel |
19 // actually does. | 19 // actually does. |
20 #error Big endian operation is untested and expected to be broken | 20 #error Big endian operation is untested and expected to be broken |
21 #endif | 21 #endif |
22 | 22 |
| 23 #ifndef SECCOMP_BPF_STANDALONE |
| 24 #include "base/logging.h" |
| 25 #include "base/posix/eintr_wrapper.h" |
| 26 #endif |
| 27 |
23 #include "sandbox/linux/seccomp-bpf/codegen.h" | 28 #include "sandbox/linux/seccomp-bpf/codegen.h" |
24 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" | 29 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" |
25 #include "sandbox/linux/seccomp-bpf/syscall.h" | 30 #include "sandbox/linux/seccomp-bpf/syscall.h" |
26 #include "sandbox/linux/seccomp-bpf/syscall_iterator.h" | 31 #include "sandbox/linux/seccomp-bpf/syscall_iterator.h" |
27 #include "sandbox/linux/seccomp-bpf/verifier.h" | 32 #include "sandbox/linux/seccomp-bpf/verifier.h" |
28 | 33 |
29 namespace { | 34 namespace { |
30 | 35 |
31 void WriteFailedStderrSetupMessage(int out_fd) { | 36 void WriteFailedStderrSetupMessage(int out_fd) { |
32 const char* error_string = strerror(errno); | 37 const char* error_string = strerror(errno); |
33 static const char msg[] = "Failed to set up stderr: "; | 38 static const char msg[] = "You have reproduced a puzzling issue.\n" |
| 39 "Please, report to crbug.com/152530!\n" |
| 40 "Failed to set up stderr: "; |
34 if (HANDLE_EINTR(write(out_fd, msg, sizeof(msg)-1)) > 0 && error_string && | 41 if (HANDLE_EINTR(write(out_fd, msg, sizeof(msg)-1)) > 0 && error_string && |
35 HANDLE_EINTR(write(out_fd, error_string, strlen(error_string))) > 0 && | 42 HANDLE_EINTR(write(out_fd, error_string, strlen(error_string))) > 0 && |
36 HANDLE_EINTR(write(out_fd, "\n", 1))) { | 43 HANDLE_EINTR(write(out_fd, "\n", 1))) { |
37 } | 44 } |
38 } | 45 } |
39 | 46 |
40 // We need to tell whether we are performing a "normal" callback, or | 47 // We need to tell whether we are performing a "normal" callback, or |
41 // whether we were called recursively from within a UnsafeTrap() callback. | 48 // whether we were called recursively from within a UnsafeTrap() callback. |
42 // This is a little tricky to do, because we need to somehow get access to | 49 // This is a little tricky to do, because we need to somehow get access to |
43 // per-thread data from within a signal context. Normal TLS storage is not | 50 // per-thread data from within a signal context. Normal TLS storage is not |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 sigprocmask(SIG_SETMASK, &oldMask, NULL); // OK, if it fails | 151 sigprocmask(SIG_SETMASK, &oldMask, NULL); // OK, if it fails |
145 SANDBOX_DIE("fork() failed unexpectedly"); | 152 SANDBOX_DIE("fork() failed unexpectedly"); |
146 } | 153 } |
147 | 154 |
148 // In the child process | 155 // In the child process |
149 if (!pid) { | 156 if (!pid) { |
150 // Test a very simple sandbox policy to verify that we can | 157 // Test a very simple sandbox policy to verify that we can |
151 // successfully turn on sandboxing. | 158 // successfully turn on sandboxing. |
152 Die::EnableSimpleExit(); | 159 Die::EnableSimpleExit(); |
153 | 160 |
| 161 errno = 0; |
154 if (HANDLE_EINTR(close(fds[0]))) { | 162 if (HANDLE_EINTR(close(fds[0]))) { |
| 163 // This call to close() has been failing in strange ways. See |
| 164 // crbug.com/152530. So we only fail in debug mode now. |
| 165 #if !defined(NDEBUG) |
155 WriteFailedStderrSetupMessage(fds[1]); | 166 WriteFailedStderrSetupMessage(fds[1]); |
156 SANDBOX_DIE(NULL); | 167 SANDBOX_DIE(NULL); |
| 168 #endif |
157 } | 169 } |
158 if (HANDLE_EINTR(dup2(fds[1], 2)) != 2) { | 170 if (HANDLE_EINTR(dup2(fds[1], 2)) != 2) { |
159 // Stderr could very well be a file descriptor to .xsession-errors, or | 171 // Stderr could very well be a file descriptor to .xsession-errors, or |
160 // another file, which could be backed by a file system that could cause | 172 // another file, which could be backed by a file system that could cause |
161 // dup2 to fail while trying to close stderr. It's important that we do | 173 // dup2 to fail while trying to close stderr. It's important that we do |
162 // not fail on trying to close stderr. | 174 // not fail on trying to close stderr. |
163 // If dup2 fails here, we will continue normally, this means that our | 175 // If dup2 fails here, we will continue normally, this means that our |
164 // parent won't cause a fatal failure if something writes to stderr in | 176 // parent won't cause a fatal failure if something writes to stderr in |
165 // this child. | 177 // this child. |
| 178 #if !defined(NDEBUG) |
| 179 // In DEBUG builds, we still want to get a report. |
| 180 WriteFailedStderrSetupMessage(fds[1]); |
| 181 SANDBOX_DIE(NULL); |
| 182 #endif |
166 } | 183 } |
167 if (HANDLE_EINTR(close(fds[1]))) { | 184 if (HANDLE_EINTR(close(fds[1]))) { |
| 185 // This call to close() has been failing in strange ways. See |
| 186 // crbug.com/152530. So we only fail in debug mode now. |
| 187 #if !defined(NDEBUG) |
168 WriteFailedStderrSetupMessage(fds[1]); | 188 WriteFailedStderrSetupMessage(fds[1]); |
169 SANDBOX_DIE(NULL); | 189 SANDBOX_DIE(NULL); |
| 190 #endif |
170 } | 191 } |
171 | 192 |
172 evaluators_.clear(); | 193 evaluators_.clear(); |
173 setSandboxPolicy(syscallEvaluator, aux); | 194 setSandboxPolicy(syscallEvaluator, aux); |
174 setProcFd(proc_fd); | 195 setProcFd(proc_fd); |
175 | 196 |
176 // By passing "quiet=true" to "startSandboxInternal()" we suppress | 197 // By passing "quiet=true" to "startSandboxInternal()" we suppress |
177 // messages for expected and benign failures (e.g. if the current | 198 // messages for expected and benign failures (e.g. if the current |
178 // kernel lacks support for BPF filters). | 199 // kernel lacks support for BPF filters). |
179 startSandboxInternal(true); | 200 startSandboxInternal(true); |
(...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
880 Sandbox::SandboxStatus Sandbox::status_ = STATUS_UNKNOWN; | 901 Sandbox::SandboxStatus Sandbox::status_ = STATUS_UNKNOWN; |
881 int Sandbox::proc_fd_ = -1; | 902 int Sandbox::proc_fd_ = -1; |
882 Sandbox::Evaluators Sandbox::evaluators_; | 903 Sandbox::Evaluators Sandbox::evaluators_; |
883 Sandbox::Traps *Sandbox::traps_ = NULL; | 904 Sandbox::Traps *Sandbox::traps_ = NULL; |
884 Sandbox::TrapIds Sandbox::trapIds_; | 905 Sandbox::TrapIds Sandbox::trapIds_; |
885 ErrorCode *Sandbox::trapArray_ = NULL; | 906 ErrorCode *Sandbox::trapArray_ = NULL; |
886 size_t Sandbox::trapArraySize_ = 0; | 907 size_t Sandbox::trapArraySize_ = 0; |
887 bool Sandbox::has_unsafe_traps_ = false; | 908 bool Sandbox::has_unsafe_traps_ = false; |
888 | 909 |
889 } // namespace | 910 } // namespace |
OLD | NEW |