blob: 24fb50e1df9edb25845c640e40f8f28107debc17 [file] [log] [blame]
Ben Chan6f391cb2012-03-21 17:38:21 -07001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Ben Chanf68ea492011-08-23 10:11:08 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CROS_DISKS_SANDBOXED_PROCESS_H_
6#define CROS_DISKS_SANDBOXED_PROCESS_H_
7
8#include <sys/types.h>
9
Sergei Datsenkoadd282e2020-11-16 15:41:24 +110010#include <memory>
Ben Chanf68ea492011-08-23 10:11:08 -070011#include <string>
Austin Tankiang93185022019-05-20 14:13:20 +100012#include <vector>
13
François Degros54abc1d2020-02-05 18:43:21 +110014#include <base/containers/span.h>
Austin Tankiang93185022019-05-20 14:13:20 +100015#include <base/files/file.h>
Ben Chanf68ea492011-08-23 10:11:08 -070016
Ben Chan6f391cb2012-03-21 17:38:21 -070017#include "cros-disks/process.h"
Ben Chanf68ea492011-08-23 10:11:08 -070018
19struct minijail;
20
21namespace cros_disks {
22
Ben Chan6f391cb2012-03-21 17:38:21 -070023class SandboxedProcess : public Process {
Ben Chanf68ea492011-08-23 10:11:08 -070024 public:
25 SandboxedProcess();
Qijiang Fan6bc59e12020-11-11 02:51:06 +090026 SandboxedProcess(const SandboxedProcess&) = delete;
27 SandboxedProcess& operator=(const SandboxedProcess&) = delete;
28
Ben Chan1c6c1942014-08-12 09:48:29 -070029 ~SandboxedProcess() override;
Ben Chanf68ea492011-08-23 10:11:08 -070030
Ben Chan98f8ae02011-10-04 16:34:34 -070031 // Loads the seccomp filters from |policy_file|. The calling process will be
32 // aborted if |policy_file| does not exist, cannot be read or is malformed.
33 void LoadSeccompFilterPolicy(const std::string& policy_file);
34
Ben Chan0dd41882017-05-24 00:46:10 -070035 // Puts the process to be sandboxed in a new cgroup namespace.
36 void NewCgroupNamespace();
37
38 // Puts the process to be sandboxed in a new IPC namespace.
39 void NewIpcNamespace();
40
Ben Chan44125df2017-05-22 11:29:11 -070041 // Puts the process to be sandboxed in a new mount namespace.
42 void NewMountNamespace();
43
Jorge Lucangeli Obes0a388a22020-04-06 11:43:21 -040044 // Puts the process to be sandboxed in an existing mount namespace.
45 // Can be combined with NewMountNamespace() above: the process will first
46 // enter the existing namespace and then unshare a new child namespace.
47 void EnterExistingMountNamespace(const std::string& ns_path);
48
Ben Chan0dd41882017-05-24 00:46:10 -070049 // Puts the process to be sandboxed in a new network namespace.
50 void NewNetworkNamespace();
51
Sergei Datsenko495f5da2019-06-06 17:44:23 +100052 // Puts the process to be sandboxed in a new PID namespace.
53 void NewPidNamespace();
54
Sergei Datsenko1cf9f3d2019-01-02 14:39:48 +110055 // Assuming the process is sandboxed in a new mount namespace, some essential
56 // mountpoints like / and /proc are being set up.
57 bool SetUpMinimalMounts();
58
59 // Maps a file or a folder into process' mount namespace.
60 bool BindMount(const std::string& from,
61 const std::string& to,
Anand K Mistry956a5502019-03-06 17:12:59 +110062 bool writeable,
63 bool recursive);
Sergei Datsenko1cf9f3d2019-01-02 14:39:48 +110064
65 // Mounts source to the specified folder in the new mount namespace.
66 bool Mount(const std::string& src,
67 const std::string& to,
68 const std::string& type,
69 const char* data);
70
71 // Makes the process to call pivot_root for an empty /.
72 bool EnterPivotRoot();
73
Ben Chan44125df2017-05-22 11:29:11 -070074 // Skips re-marking existing mounts as private.
75 void SkipRemountPrivate();
76
Ben Chan0dd41882017-05-24 00:46:10 -070077 // Sets the no_new_privs bit.
78 void SetNoNewPrivileges();
79
Ben Chanf68ea492011-08-23 10:11:08 -070080 // Sets the process capabilities of the process to be sandboxed.
81 void SetCapabilities(uint64_t capabilities);
82
François Degros54abc1d2020-02-05 18:43:21 +110083 // Sets the primary group ID of the process to be sandboxed.
Ben Chanf68ea492011-08-23 10:11:08 -070084 void SetGroupId(gid_t group_id);
85
86 // Sets the user ID of the process to be sandboxed.
87 void SetUserId(uid_t user_id);
88
François Degros54abc1d2020-02-05 18:43:21 +110089 // Sets supplementary group IDs of the process to be sandboxed.
90 void SetSupplementaryGroupIds(base::span<const gid_t> gids);
91
Derek Basehore1709caf2020-07-17 17:06:38 -070092 // Adds the minijail to |cgroup|.
93 bool AddToCgroup(const std::string& cgroup);
94
Austin Tankiang93185022019-05-20 14:13:20 +100095 // Close all open fds on fork.
96 void CloseOpenFds();
97
98 // Preserves |file| to still be available in the sandboxed process with the
99 // same file descriptor. Only effective if CloseOpenFds has been called.
100 bool PreserveFile(const base::File& file);
101
Sergei Datsenkocd676b72019-05-10 11:42:05 +1000102 protected:
103 // Process overrides:
François Degros1ef69942019-10-01 15:31:17 +1000104 pid_t StartImpl(base::ScopedFD in_fd,
105 base::ScopedFD out_fd,
106 base::ScopedFD err_fd) override;
Sergei Datsenkocd676b72019-05-10 11:42:05 +1000107 int WaitImpl() override;
François Degros92bbea42019-09-13 10:42:52 +1000108 int WaitNonBlockingImpl() override;
Ben Chanf68ea492011-08-23 10:11:08 -0700109
110 private:
Ben Chan71daeac2014-09-08 09:03:36 -0700111 minijail* jail_;
Sergei Datsenko495f5da2019-06-06 17:44:23 +1000112 bool run_custom_init_ = false;
113 base::ScopedFD custom_init_control_fd_;
Ben Chanf68ea492011-08-23 10:11:08 -0700114};
115
Sergei Datsenkoadd282e2020-11-16 15:41:24 +1100116// Interface for creating preconfigured instances of |SandboxedProcess|.
117class SandboxedProcessFactory {
118 public:
119 SandboxedProcessFactory() = default;
120 virtual ~SandboxedProcessFactory() = default;
121 virtual std::unique_ptr<SandboxedProcess> CreateSandboxedProcess() const = 0;
122};
123
124// Ties executable with the corresponding seccomp policy configuration.
125struct SandboxedExecutable {
126 base::FilePath executable;
127 base::Optional<base::FilePath> seccomp_policy = {};
128};
129
Sergei Datsenkof5553d12020-11-25 07:51:59 +1100130// Fake SandboxedProcess for testing. Doesn't launch any actual process.
131class FakeSandboxedProcess : public SandboxedProcess {
132 public:
133 virtual int OnProcessLaunch(const std::vector<std::string>& argv);
134
135 private:
136 pid_t StartImpl(base::ScopedFD, base::ScopedFD, base::ScopedFD) final;
137 int WaitImpl() final;
138 int WaitNonBlockingImpl() final;
139
140 base::Optional<int> ret_code_;
141};
142
Ben Chanf68ea492011-08-23 10:11:08 -0700143} // namespace cros_disks
144
145#endif // CROS_DISKS_SANDBOXED_PROCESS_H_