blob: 77c6c62b531f7bfa5310107525a0e2949540b4b0 [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>
Hugo Benichi33860d72020-07-09 16:34:01 +09009#include <sys/types.h>
10
Garrick Evans64a2df32018-12-12 16:53:46 +090011#include <string>
12#include <vector>
13
14#include <brillo/minijail/minijail.h>
15
Garrick Evans3388a032020-03-24 11:25:55 +090016namespace patchpanel {
Garrick Evans64a2df32018-12-12 16:53:46 +090017
Jason Jeremy Imand89b5f52019-10-24 10:39:17 +090018// Runs the current process with minimal privileges. This function is expected
19// to be used by child processes that need only CAP_NET_RAW and to run as the
Garrick Evans6776b502020-05-01 10:41:56 +090020// patchpaneld user.
Jason Jeremy Imand89b5f52019-10-24 10:39:17 +090021void EnterChildProcessJail();
22
Garrick Evans64a2df32018-12-12 16:53:46 +090023// Enforces the expected processes are run with the correct privileges.
24class MinijailedProcessRunner {
25 public:
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090026 // For mocking waitpid().
27 class SyscallImpl {
28 public:
29 virtual pid_t WaitPID(pid_t pid, int* wstatus, int options = 0);
30 virtual ~SyscallImpl() = default;
31 };
32
Garrick Evans64a2df32018-12-12 16:53:46 +090033 // Ownership of |mj| is not assumed and must be managed by the caller.
34 // If |mj| is null, the default instance will be used.
35 explicit MinijailedProcessRunner(brillo::Minijail* mj = nullptr);
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090036 // Provided for testing only.
37 MinijailedProcessRunner(brillo::Minijail* mj,
38 std::unique_ptr<SyscallImpl> syscall);
Qijiang Fan6bc59e12020-11-11 02:51:06 +090039 MinijailedProcessRunner(const MinijailedProcessRunner&) = delete;
40 MinijailedProcessRunner& operator=(const MinijailedProcessRunner&) = delete;
41
Garrick Evans64a2df32018-12-12 16:53:46 +090042 virtual ~MinijailedProcessRunner() = default;
43
Garrick Evans8e8e3472020-01-23 14:03:50 +090044 // Runs ip.
45 virtual int ip(const std::string& obj,
46 const std::string& cmd,
47 const std::vector<std::string>& args,
48 bool log_failures = true);
49 virtual int ip6(const std::string& obj,
50 const std::string& cmd,
51 const std::vector<std::string>& args,
52 bool log_failures = true);
53
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090054 // Runs iptables. If |output| is not nullptr, it will be filled with the
55 // result from stdout of iptables command.
Garrick Evans8e8e3472020-01-23 14:03:50 +090056 virtual int iptables(const std::string& table,
57 const std::vector<std::string>& argv,
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090058 bool log_failures = true,
59 std::string* output = nullptr);
Garrick Evans8e8e3472020-01-23 14:03:50 +090060
61 virtual int ip6tables(const std::string& table,
62 const std::vector<std::string>& argv,
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090063 bool log_failures = true,
64 std::string* output = nullptr);
Garrick Evans8e8e3472020-01-23 14:03:50 +090065
66 // Installs all |modules| via modprobe.
67 virtual int modprobe_all(const std::vector<std::string>& modules,
68 bool log_failures = true);
69
70 // Updates kernel parameter |key| to |value| using sysctl.
71 virtual int sysctl_w(const std::string& key,
72 const std::string& value,
73 bool log_failures = true);
74
Jie Jiangf6799312021-05-14 16:27:03 +090075 // Creates a new named network namespace with name |netns_name|.
76 virtual int ip_netns_add(const std::string& netns_name,
77 bool log_failures = true);
78
Hugo Benichi33860d72020-07-09 16:34:01 +090079 // Attaches a name to the network namespace of the given pid
80 // TODO(hugobenichi) How can patchpanel create a |netns_name| file in
81 // /run/netns without running ip as root ?
82 virtual int ip_netns_attach(const std::string& netns_name,
83 pid_t netns_pid,
84 bool log_failures = true);
85
86 virtual int ip_netns_delete(const std::string& netns_name,
87 bool log_failures = true);
88
Garrick Evans8e8e3472020-01-23 14:03:50 +090089 protected:
90 // Runs a process (argv[0]) with optional arguments (argv[1]...)
91 // in a minijail as an unprivileged user with CAP_NET_ADMIN and
92 // CAP_NET_RAW capabilities.
93 virtual int Run(const std::vector<std::string>& argv,
94 bool log_failures = true);
Jie Jiangc9a5cd52020-12-14 17:38:52 +090095
96 // Invokes RunSyncDestroy() with |mj_|. If |output| is not nullptr, it will be
97 // filled with the result from stdout of the execution.
Hugo Benichib5b44cc2020-12-11 11:01:02 +090098 virtual int RunSync(const std::vector<std::string>& argv,
Hugo Benichib5b44cc2020-12-11 11:01:02 +090099 bool log_failures,
Jie Jiangc9a5cd52020-12-14 17:38:52 +0900100 std::string* output);
Garrick Evans6d227b92019-12-03 16:11:29 +0900101
Garrick Evans64a2df32018-12-12 16:53:46 +0900102 private:
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900103 int RunSyncDestroy(const std::vector<std::string>& argv,
104 brillo::Minijail* mj,
105 minijail* jail,
106 bool log_failures,
Jie Jiang0137f5d2020-12-16 16:23:59 +0900107 std::string* output);
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900108
Garrick Evans64a2df32018-12-12 16:53:46 +0900109 brillo::Minijail* mj_;
110
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900111 std::unique_ptr<SyscallImpl> syscall_;
Garrick Evans64a2df32018-12-12 16:53:46 +0900112};
113
Garrick Evans3388a032020-03-24 11:25:55 +0900114} // namespace patchpanel
Garrick Evans64a2df32018-12-12 16:53:46 +0900115
Garrick Evans3388a032020-03-24 11:25:55 +0900116#endif // PATCHPANEL_MINIJAILED_PROCESS_RUNNER_H_