blob: b52ea689cd0417567ddbf73d26e81579b628a640 [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 brctl.
45 virtual int brctl(const std::string& cmd,
46 const std::vector<std::string>& argv,
47 bool log_failures = true);
Garrick Evans6d227b92019-12-03 16:11:29 +090048
49 // Runs chown to update file ownership.
Garrick Evans8e8e3472020-01-23 14:03:50 +090050 virtual int chown(const std::string& uid,
Garrick Evans6d227b92019-12-03 16:11:29 +090051 const std::string& gid,
Garrick Evans8e8e3472020-01-23 14:03:50 +090052 const std::string& file,
53 bool log_failures = true);
54
Garrick Evans8e8e3472020-01-23 14:03:50 +090055 // Runs ip.
56 virtual int ip(const std::string& obj,
57 const std::string& cmd,
58 const std::vector<std::string>& args,
59 bool log_failures = true);
60 virtual int ip6(const std::string& obj,
61 const std::string& cmd,
62 const std::vector<std::string>& args,
63 bool log_failures = true);
64
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090065 // Runs iptables. If |output| is not nullptr, it will be filled with the
66 // result from stdout of iptables command.
Garrick Evans8e8e3472020-01-23 14:03:50 +090067 virtual int iptables(const std::string& table,
68 const std::vector<std::string>& argv,
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090069 bool log_failures = true,
70 std::string* output = nullptr);
Garrick Evans8e8e3472020-01-23 14:03:50 +090071
72 virtual int ip6tables(const std::string& table,
73 const std::vector<std::string>& argv,
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090074 bool log_failures = true,
75 std::string* output = nullptr);
Garrick Evans8e8e3472020-01-23 14:03:50 +090076
77 // Installs all |modules| via modprobe.
78 virtual int modprobe_all(const std::vector<std::string>& modules,
79 bool log_failures = true);
80
81 // Updates kernel parameter |key| to |value| using sysctl.
82 virtual int sysctl_w(const std::string& key,
83 const std::string& value,
84 bool log_failures = true);
85
Hugo Benichi33860d72020-07-09 16:34:01 +090086 // Attaches a name to the network namespace of the given pid
87 // TODO(hugobenichi) How can patchpanel create a |netns_name| file in
88 // /run/netns without running ip as root ?
89 virtual int ip_netns_attach(const std::string& netns_name,
90 pid_t netns_pid,
91 bool log_failures = true);
92
93 virtual int ip_netns_delete(const std::string& netns_name,
94 bool log_failures = true);
95
Garrick Evans8e8e3472020-01-23 14:03:50 +090096 protected:
97 // Runs a process (argv[0]) with optional arguments (argv[1]...)
98 // in a minijail as an unprivileged user with CAP_NET_ADMIN and
99 // CAP_NET_RAW capabilities.
100 virtual int Run(const std::vector<std::string>& argv,
101 bool log_failures = true);
Jie Jiangc9a5cd52020-12-14 17:38:52 +0900102
103 // Invokes RunSyncDestroy() with |mj_|. If |output| is not nullptr, it will be
104 // filled with the result from stdout of the execution.
Hugo Benichib5b44cc2020-12-11 11:01:02 +0900105 virtual int RunSync(const std::vector<std::string>& argv,
Hugo Benichib5b44cc2020-12-11 11:01:02 +0900106 bool log_failures,
Jie Jiangc9a5cd52020-12-14 17:38:52 +0900107 std::string* output);
Garrick Evans6d227b92019-12-03 16:11:29 +0900108
Garrick Evans64a2df32018-12-12 16:53:46 +0900109 private:
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900110 int RunSyncDestroy(const std::vector<std::string>& argv,
111 brillo::Minijail* mj,
112 minijail* jail,
113 bool log_failures,
Jie Jiang0137f5d2020-12-16 16:23:59 +0900114 std::string* output);
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900115
Garrick Evans64a2df32018-12-12 16:53:46 +0900116 brillo::Minijail* mj_;
117
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900118 std::unique_ptr<SyscallImpl> syscall_;
Garrick Evans64a2df32018-12-12 16:53:46 +0900119};
120
Garrick Evans3388a032020-03-24 11:25:55 +0900121} // namespace patchpanel
Garrick Evans64a2df32018-12-12 16:53:46 +0900122
Garrick Evans3388a032020-03-24 11:25:55 +0900123#endif // PATCHPANEL_MINIJAILED_PROCESS_RUNNER_H_