blob: a140436ecd9a3bdcc61d03842a971a445ebd2aff [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
Hugo Benichi33860d72020-07-09 16:34:01 +090075 // Attaches a name to the network namespace of the given pid
76 // TODO(hugobenichi) How can patchpanel create a |netns_name| file in
77 // /run/netns without running ip as root ?
78 virtual int ip_netns_attach(const std::string& netns_name,
79 pid_t netns_pid,
80 bool log_failures = true);
81
82 virtual int ip_netns_delete(const std::string& netns_name,
83 bool log_failures = true);
84
Garrick Evans8e8e3472020-01-23 14:03:50 +090085 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);
Jie Jiangc9a5cd52020-12-14 17:38:52 +090091
92 // Invokes RunSyncDestroy() with |mj_|. If |output| is not nullptr, it will be
93 // filled with the result from stdout of the execution.
Hugo Benichib5b44cc2020-12-11 11:01:02 +090094 virtual int RunSync(const std::vector<std::string>& argv,
Hugo Benichib5b44cc2020-12-11 11:01:02 +090095 bool log_failures,
Jie Jiangc9a5cd52020-12-14 17:38:52 +090096 std::string* output);
Garrick Evans6d227b92019-12-03 16:11:29 +090097
Garrick Evans64a2df32018-12-12 16:53:46 +090098 private:
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090099 int RunSyncDestroy(const std::vector<std::string>& argv,
100 brillo::Minijail* mj,
101 minijail* jail,
102 bool log_failures,
Jie Jiang0137f5d2020-12-16 16:23:59 +0900103 std::string* output);
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900104
Garrick Evans64a2df32018-12-12 16:53:46 +0900105 brillo::Minijail* mj_;
106
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900107 std::unique_ptr<SyscallImpl> syscall_;
Garrick Evans64a2df32018-12-12 16:53:46 +0900108};
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_