Avi Drissman | 8ba1bad | 2022-09-13 19:22:36 | [diff] [blame] | 1 | // Copyright 2014 The Chromium Authors |
[email protected] | 55a2bbe | 2014-04-29 01:53:54 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #ifndef COMPONENTS_NACL_LOADER_SANDBOX_LINUX_NACL_SANDBOX_LINUX_H_ |
| 6 | #define COMPONENTS_NACL_LOADER_SANDBOX_LINUX_NACL_SANDBOX_LINUX_H_ |
| 7 | |
dcheng | 24f43a5e9 | 2016-04-22 18:29:09 | [diff] [blame] | 8 | #include <memory> |
| 9 | |
[email protected] | 55a2bbe | 2014-04-29 01:53:54 | [diff] [blame] | 10 | #include "base/files/scoped_file.h" |
[email protected] | a77d3fa | 2014-05-20 06:23:48 | [diff] [blame] | 11 | |
| 12 | namespace sandbox { |
| 13 | class SetuidSandboxClient; |
| 14 | } |
[email protected] | 55a2bbe | 2014-04-29 01:53:54 | [diff] [blame] | 15 | |
| 16 | namespace nacl { |
| 17 | |
| 18 | // NaClSandbox supports two independent layers of sandboxing. |
| 19 | // layer-1 uses a chroot. It requires both InitializeLayerOneSandbox() and |
| 20 | // SealLayerOneSandbox() to have been called to be enforcing. |
| 21 | // layer-2 uses seccomp-bpf. It requires the layer-1 sandbox to not yet be |
| 22 | // sealed when being engaged. |
| 23 | // For the layer-1 sandbox to work, the current process must be a child of |
| 24 | // the setuid sandbox. InitializeLayerOneSandbox() can only be called once |
| 25 | // per instance of the setuid sandbox. |
| 26 | // |
| 27 | // A typical use case of this class would be: |
| 28 | // 1. Load libraries and do some pre-initialization |
| 29 | // 2. InitializeLayerOneSandbox(); |
| 30 | // 3. Do some more initializations (it is ok to fork() here). |
| 31 | // 4. CHECK(!HasOpenDirectory)); |
| 32 | // (This check is not strictly necessary, as the only possibility for a |
| 33 | // new directory descriptor to exist after (2) has been called is via IPC)). |
| 34 | // 5. InitializeLayerTwoSandbox(); |
| 35 | // 6. SealLayerOneSandbox(); |
| 36 | // 7. CheckSandboxingStateWithPolicy(); |
| 37 | class NaClSandbox { |
| 38 | public: |
| 39 | NaClSandbox(); |
Peter Boström | 09c0182 | 2021-09-20 22:43:27 | [diff] [blame] | 40 | |
| 41 | NaClSandbox(const NaClSandbox&) = delete; |
| 42 | NaClSandbox& operator=(const NaClSandbox&) = delete; |
| 43 | |
[email protected] | 55a2bbe | 2014-04-29 01:53:54 | [diff] [blame] | 44 | ~NaClSandbox(); |
| 45 | |
| 46 | // This API will only work if the layer-1 sandbox is not sealed and the |
| 47 | // layer-2 sandbox is not engaged. |
| 48 | bool IsSingleThreaded(); |
| 49 | // Check whether the current process owns any directory file descriptors. This |
| 50 | // will ignore any directory file descriptor owned by this object (i.e. those |
| 51 | // that will be closed after SealLayerOneSandbox()) is called. |
| 52 | // This API will only work if the layer-1 sandbox is not sealed and the |
| 53 | // layer-2 sandbox is not engaged. |
| 54 | bool HasOpenDirectory(); |
| 55 | // Will attempt to initialize the layer-1 sandbox, depending on flags and the |
| 56 | // environment. It can only succeed if the current process is a child of the |
jln | 97718598 | 2015-02-13 20:58:41 | [diff] [blame] | 57 | // setuid sandbox or was started by the namespace sandbox. |
[email protected] | 55a2bbe | 2014-04-29 01:53:54 | [diff] [blame] | 58 | void InitializeLayerOneSandbox(); |
| 59 | // Will attempt to initialize the layer-2 sandbox, depending on flags and the |
Hidehiko Abe | 2a32553 | 2021-12-14 21:47:41 | [diff] [blame] | 60 | // environment. |
jln | 97718598 | 2015-02-13 20:58:41 | [diff] [blame] | 61 | // This layer will also add a limit to how much of the address space can be |
| 62 | // used. |
Hidehiko Abe | 2a32553 | 2021-12-14 21:47:41 | [diff] [blame] | 63 | void InitializeLayerTwoSandbox(); |
[email protected] | 55a2bbe | 2014-04-29 01:53:54 | [diff] [blame] | 64 | // Seal the layer-1 sandbox, making it enforcing. |
| 65 | void SealLayerOneSandbox(); |
| 66 | // Check that the current sandboxing state matches the level of sandboxing |
| 67 | // expected for NaCl in the current configuration. Crash if it does not. |
| 68 | void CheckSandboxingStateWithPolicy(); |
| 69 | |
| 70 | bool layer_one_enabled() { return layer_one_enabled_; } |
| 71 | bool layer_two_enabled() { return layer_two_enabled_; } |
| 72 | |
| 73 | private: |
[email protected] | a77d3fa | 2014-05-20 06:23:48 | [diff] [blame] | 74 | void CheckForExpectedNumberOfOpenFds(); |
| 75 | |
[email protected] | 55a2bbe | 2014-04-29 01:53:54 | [diff] [blame] | 76 | bool layer_one_enabled_; |
| 77 | bool layer_one_sealed_; |
| 78 | bool layer_two_enabled_; |
[email protected] | 55a2bbe | 2014-04-29 01:53:54 | [diff] [blame] | 79 | // |proc_fd_| must be released before the layer-1 sandbox is considered |
| 80 | // enforcing. |
| 81 | base::ScopedFD proc_fd_; |
dcheng | 24f43a5e9 | 2016-04-22 18:29:09 | [diff] [blame] | 82 | std::unique_ptr<sandbox::SetuidSandboxClient> setuid_sandbox_client_; |
[email protected] | 55a2bbe | 2014-04-29 01:53:54 | [diff] [blame] | 83 | }; |
| 84 | |
| 85 | } // namespace nacl |
| 86 | |
| 87 | #endif // COMPONENTS_NACL_LOADER_SANDBOX_LINUX_NACL_SANDBOX_LINUX_H_ |