blob: 1fc11b5b1b0ae61fe15ede946f560d12c1ff1637 [file] [log] [blame]
Garrick Evans64a2df32018-12-12 16:53:46 +09001// Copyright 2019 The Chromium OS 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
Garrick Evans3388a032020-03-24 11:25:55 +09005#ifndef PATCHPANEL_MINIJAILED_PROCESS_RUNNER_H_
6#define PATCHPANEL_MINIJAILED_PROCESS_RUNNER_H_
Garrick Evans64a2df32018-12-12 16:53:46 +09007
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09008#include <memory>
Garrick Evans64a2df32018-12-12 16:53:46 +09009#include <string>
10#include <vector>
11
12#include <brillo/minijail/minijail.h>
13
Garrick Evans3388a032020-03-24 11:25:55 +090014namespace patchpanel {
Garrick Evans64a2df32018-12-12 16:53:46 +090015
Jason Jeremy Imand89b5f52019-10-24 10:39:17 +090016// Runs the current process with minimal privileges. This function is expected
17// to be used by child processes that need only CAP_NET_RAW and to run as the
Garrick Evans6776b502020-05-01 10:41:56 +090018// patchpaneld user.
Jason Jeremy Imand89b5f52019-10-24 10:39:17 +090019void EnterChildProcessJail();
20
Garrick Evans64a2df32018-12-12 16:53:46 +090021// Enforces the expected processes are run with the correct privileges.
22class MinijailedProcessRunner {
23 public:
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090024 // For mocking waitpid().
25 class SyscallImpl {
26 public:
27 virtual pid_t WaitPID(pid_t pid, int* wstatus, int options = 0);
28 virtual ~SyscallImpl() = default;
29 };
30
Garrick Evans64a2df32018-12-12 16:53:46 +090031 // Ownership of |mj| is not assumed and must be managed by the caller.
32 // If |mj| is null, the default instance will be used.
33 explicit MinijailedProcessRunner(brillo::Minijail* mj = nullptr);
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090034 // Provided for testing only.
35 MinijailedProcessRunner(brillo::Minijail* mj,
36 std::unique_ptr<SyscallImpl> syscall);
Garrick Evans64a2df32018-12-12 16:53:46 +090037 virtual ~MinijailedProcessRunner() = default;
38
Garrick Evans2470caa2020-03-04 14:15:41 +090039 // Moves interface |ifname| back into the default namespace
40 // |pid| identifies the pid of the current namespace.
41 virtual int RestoreDefaultNamespace(const std::string& ifname, pid_t pid);
Garrick Evans64a2df32018-12-12 16:53:46 +090042
Garrick Evans8e8e3472020-01-23 14:03:50 +090043 // Runs brctl.
44 virtual int brctl(const std::string& cmd,
45 const std::vector<std::string>& argv,
46 bool log_failures = true);
Garrick Evans6d227b92019-12-03 16:11:29 +090047
48 // Runs chown to update file ownership.
Garrick Evans8e8e3472020-01-23 14:03:50 +090049 virtual int chown(const std::string& uid,
Garrick Evans6d227b92019-12-03 16:11:29 +090050 const std::string& gid,
Garrick Evans8e8e3472020-01-23 14:03:50 +090051 const std::string& file,
52 bool log_failures = true);
53
Garrick Evans8e8e3472020-01-23 14:03:50 +090054 // Runs ip.
55 virtual int ip(const std::string& obj,
56 const std::string& cmd,
57 const std::vector<std::string>& args,
58 bool log_failures = true);
59 virtual int ip6(const std::string& obj,
60 const std::string& cmd,
61 const std::vector<std::string>& args,
62 bool log_failures = true);
63
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090064 // Runs iptables. If |output| is not nullptr, it will be filled with the
65 // result from stdout of iptables command.
Garrick Evans8e8e3472020-01-23 14:03:50 +090066 virtual int iptables(const std::string& table,
67 const std::vector<std::string>& argv,
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090068 bool log_failures = true,
69 std::string* output = nullptr);
Garrick Evans8e8e3472020-01-23 14:03:50 +090070
71 virtual int ip6tables(const std::string& table,
72 const std::vector<std::string>& argv,
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090073 bool log_failures = true,
74 std::string* output = nullptr);
Garrick Evans8e8e3472020-01-23 14:03:50 +090075
76 // Installs all |modules| via modprobe.
77 virtual int modprobe_all(const std::vector<std::string>& modules,
78 bool log_failures = true);
79
80 // Updates kernel parameter |key| to |value| using sysctl.
81 virtual int sysctl_w(const std::string& key,
82 const std::string& value,
83 bool log_failures = true);
84
85 protected:
86 // Runs a process (argv[0]) with optional arguments (argv[1]...)
87 // in a minijail as an unprivileged user with CAP_NET_ADMIN and
88 // CAP_NET_RAW capabilities.
89 virtual int Run(const std::vector<std::string>& argv,
90 bool log_failures = true);
Garrick Evans6d227b92019-12-03 16:11:29 +090091
Garrick Evans64a2df32018-12-12 16:53:46 +090092 private:
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090093 int RunSyncDestroy(const std::vector<std::string>& argv,
94 brillo::Minijail* mj,
95 minijail* jail,
96 bool log_failures,
97 int* fd_stdout);
98 int RunSync(const std::vector<std::string>& argv,
99 brillo::Minijail* mj,
100 bool log_failures,
101 int* fd_stdout);
102
Garrick Evans64a2df32018-12-12 16:53:46 +0900103 brillo::Minijail* mj_;
104
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900105 std::unique_ptr<SyscallImpl> syscall_;
106
Garrick Evans64a2df32018-12-12 16:53:46 +0900107 DISALLOW_COPY_AND_ASSIGN(MinijailedProcessRunner);
108};
109
Garrick Evans3388a032020-03-24 11:25:55 +0900110} // namespace patchpanel
Garrick Evans64a2df32018-12-12 16:53:46 +0900111
Garrick Evans3388a032020-03-24 11:25:55 +0900112#endif // PATCHPANEL_MINIJAILED_PROCESS_RUNNER_H_