Home | History | Annotate | Download | only in sandbox_linux
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      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 
      8 #include "base/files/scoped_file.h"
      9 #include "base/macros.h"
     10 #include "base/memory/scoped_ptr.h"
     11 
     12 namespace sandbox {
     13 class SetuidSandboxClient;
     14 }
     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();
     40   ~NaClSandbox();
     41 
     42   // This API will only work if the layer-1 sandbox is not sealed and the
     43   // layer-2 sandbox is not engaged.
     44   bool IsSingleThreaded();
     45   // Check whether the current process owns any directory file descriptors. This
     46   // will ignore any directory file descriptor owned by this object (i.e. those
     47   // that will be closed after SealLayerOneSandbox()) is called.
     48   // This API will only work if the layer-1 sandbox is not sealed and the
     49   // layer-2 sandbox is not engaged.
     50   bool HasOpenDirectory();
     51   // Will attempt to initialize the layer-1 sandbox, depending on flags and the
     52   // environment. It can only succeed if the current process is a child of the
     53   // setuid sandbox.
     54   void InitializeLayerOneSandbox();
     55   // Will attempt to initialize the layer-2 sandbox, depending on flags and the
     56   // environment. |uses_nonsfi_mode| describes which seccomp-bpf policy is
     57   // appropriate.
     58   void InitializeLayerTwoSandbox(bool uses_nonsfi_mode);
     59   // Seal the layer-1 sandbox, making it enforcing.
     60   void SealLayerOneSandbox();
     61   // Check that the current sandboxing state matches the level of sandboxing
     62   // expected for NaCl in the current configuration. Crash if it does not.
     63   void CheckSandboxingStateWithPolicy();
     64 
     65   bool layer_one_enabled() { return layer_one_enabled_; }
     66   bool layer_two_enabled() { return layer_two_enabled_; }
     67 
     68  private:
     69   void CheckForExpectedNumberOfOpenFds();
     70 
     71   bool layer_one_enabled_;
     72   bool layer_one_sealed_;
     73   bool layer_two_enabled_;
     74   bool layer_two_is_nonsfi_;
     75   // |proc_fd_| must be released before the layer-1 sandbox is considered
     76   // enforcing.
     77   base::ScopedFD proc_fd_;
     78   scoped_ptr<sandbox::SetuidSandboxClient> setuid_sandbox_client_;
     79   DISALLOW_COPY_AND_ASSIGN(NaClSandbox);
     80 };
     81 
     82 }  // namespace nacl
     83 
     84 #endif  // COMPONENTS_NACL_LOADER_SANDBOX_LINUX_NACL_SANDBOX_LINUX_H_
     85