| // Copyright (c) 2012 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CROS_DISKS_SANDBOXED_PROCESS_H_ |
| #define CROS_DISKS_SANDBOXED_PROCESS_H_ |
| |
| #include <sys/types.h> |
| |
| #include <memory> |
| #include <optional> |
| #include <string> |
| #include <vector> |
| |
| #include <base/callback.h> |
| #include <base/containers/span.h> |
| #include <base/files/file.h> |
| |
| #include "cros-disks/process.h" |
| #include "cros-disks/sandboxed_init.h" |
| |
| struct minijail; |
| |
| namespace cros_disks { |
| |
| class SandboxedProcess : public Process { |
| public: |
| SandboxedProcess(); |
| SandboxedProcess(const SandboxedProcess&) = delete; |
| SandboxedProcess& operator=(const SandboxedProcess&) = delete; |
| |
| ~SandboxedProcess() override; |
| |
| // Loads the seccomp filters from |policy_file|. The calling process will be |
| // aborted if |policy_file| does not exist, cannot be read or is malformed. |
| void LoadSeccompFilterPolicy(const std::string& policy_file); |
| |
| // Puts the process to be sandboxed in a new cgroup namespace. |
| void NewCgroupNamespace(); |
| |
| // Puts the process to be sandboxed in a new IPC namespace. |
| void NewIpcNamespace(); |
| |
| // Puts the process to be sandboxed in a new mount namespace. |
| void NewMountNamespace(); |
| |
| // Puts the process to be sandboxed in an existing mount namespace. |
| // Can be combined with NewMountNamespace() above: the process will first |
| // enter the existing namespace and then unshare a new child namespace. |
| void EnterExistingMountNamespace(const std::string& ns_path); |
| |
| // Puts the process to be sandboxed in a new network namespace. |
| void NewNetworkNamespace(); |
| |
| // Puts the process to be sandboxed in a new PID namespace. |
| void NewPidNamespace(); |
| |
| // Assuming the process is sandboxed in a new mount namespace, some essential |
| // mountpoints like / and /proc are being set up. |
| bool SetUpMinimalMounts(); |
| |
| // Maps a file or a folder into process' mount namespace. |
| bool BindMount(const std::string& from, |
| const std::string& to, |
| bool writeable, |
| bool recursive); |
| |
| // Mounts source to the specified folder in the new mount namespace. |
| bool Mount(const std::string& src, |
| const std::string& to, |
| const std::string& type, |
| const char* data); |
| |
| // Makes the process to call pivot_root for an empty /. |
| bool EnterPivotRoot(); |
| |
| // Sets the no_new_privs bit. |
| void SetNoNewPrivileges(); |
| |
| // Sets the process capabilities of the process to be sandboxed. |
| void SetCapabilities(uint64_t capabilities); |
| |
| // Sets the primary group ID of the process to be sandboxed. |
| void SetGroupId(gid_t group_id); |
| |
| // Sets the user ID of the process to be sandboxed. |
| void SetUserId(uid_t user_id); |
| |
| // Sets supplementary group IDs of the process to be sandboxed. |
| void SetSupplementaryGroupIds(base::span<const gid_t> gids); |
| |
| // Adds the minijail to |cgroup|. |
| bool AddToCgroup(const std::string& cgroup); |
| |
| // Preserves the given file descriptor to still be available in the sandboxed |
| // process. |
| void PreserveFile(int fd); |
| |
| private: |
| // Process overrides: |
| pid_t StartImpl(base::ScopedFD in_fd, base::ScopedFD out_fd) override; |
| int WaitImpl() override; |
| int WaitNonBlockingImpl() override; |
| |
| // Minijail object. |
| minijail* jail_; |
| |
| // Does this SandboxedProcess use a PID namespace? |
| bool use_pid_namespace_ = false; |
| |
| // Write end of the pipe used to terminate the init process inside the PID |
| // namespace. This end of the pipe is closed when the SandboxedProcess |
| // instance is destroyed, generating a SIGIO in the child init process, which |
| // triggers termination of init and all its nested children. Only used when |
| // |use_pid_namespace_| is true. |
| base::ScopedFD termination_fd_; |
| }; |
| |
| // Interface for creating preconfigured instances of |SandboxedProcess|. |
| class SandboxedProcessFactory { |
| public: |
| SandboxedProcessFactory() = default; |
| virtual ~SandboxedProcessFactory() = default; |
| virtual std::unique_ptr<SandboxedProcess> CreateSandboxedProcess() const = 0; |
| }; |
| |
| // Ties executable with the corresponding seccomp policy configuration. |
| struct SandboxedExecutable { |
| base::FilePath executable; |
| std::optional<base::FilePath> seccomp_policy = {}; |
| }; |
| |
| // Fake SandboxedProcess for testing. Doesn't launch any actual process. |
| class FakeSandboxedProcess : public SandboxedProcess { |
| public: |
| virtual int OnProcessLaunch(const std::vector<std::string>& argv); |
| |
| private: |
| pid_t StartImpl(base::ScopedFD, base::ScopedFD) final; |
| int WaitImpl() final; |
| int WaitNonBlockingImpl() final; |
| |
| std::optional<int> ret_code_; |
| }; |
| |
| } // namespace cros_disks |
| |
| #endif // CROS_DISKS_SANDBOXED_PROCESS_H_ |