blob: 6b9cacd9b2a0407afa9392526b29e50f7c51cc31 [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#include "patchpanel/minijailed_process_runner.h"
Garrick Evans64a2df32018-12-12 16:53:46 +09006
7#include <linux/capability.h>
Jie Jiangcf5ce9c2020-07-14 17:22:03 +09008#include <memory>
Garrick Evans64a2df32018-12-12 16:53:46 +09009
10#include <brillo/minijail/mock_minijail.h>
11#include <gmock/gmock.h>
12#include <gtest/gtest.h>
13
Garrick Evans3388a032020-03-24 11:25:55 +090014#include "patchpanel/net_util.h"
Garrick Evans7a1a9ee2020-01-28 11:03:57 +090015
Garrick Evans64a2df32018-12-12 16:53:46 +090016using testing::_;
17using testing::DoAll;
18using testing::Eq;
19using testing::Return;
20using testing::SetArgPointee;
21using testing::StrEq;
22
Garrick Evans3388a032020-03-24 11:25:55 +090023namespace patchpanel {
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090024namespace {
25
26constexpr pid_t kFakePid = 123;
27
28class FakeSyscallImpl : public MinijailedProcessRunner::SyscallImpl {
29 public:
30 pid_t WaitPID(pid_t pid, int* wstatus, int options) override { return pid; }
31};
Garrick Evans64a2df32018-12-12 16:53:46 +090032
33class MinijailProcessRunnerTest : public testing::Test {
34 protected:
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090035 MinijailProcessRunnerTest()
36 : runner_(&mj_, std::make_unique<FakeSyscallImpl>()) {}
Garrick Evans64a2df32018-12-12 16:53:46 +090037
38 void SetUp() override {
39 ON_CALL(mj_, DropRoot(_, _, _)).WillByDefault(Return(true));
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090040 ON_CALL(mj_, RunPipesAndDestroy(_, _, _, _, _, _))
41 .WillByDefault(DoAll(SetArgPointee<2>(kFakePid), Return(true)));
Garrick Evans64a2df32018-12-12 16:53:46 +090042 }
43
44 brillo::MockMinijail mj_;
45 MinijailedProcessRunner runner_;
46};
47
48// Special matcher needed for vector<char*> type.
49// Lifted from shill/process_manager_test.cc
50MATCHER_P2(IsProcessArgs, program, args, "") {
51 if (std::string(arg[0]) != program) {
52 return false;
53 }
54 int index = 1;
55 for (const auto& option : args) {
56 if (std::string(arg[index++]) != option) {
57 return false;
58 }
59 }
60 return arg[index] == nullptr;
61}
62
Garrick Evans2470caa2020-03-04 14:15:41 +090063TEST_F(MinijailProcessRunnerTest, RestoreDefaultNamespace) {
64 const std::vector<std::string> args = {
65 "-t", "12345", "-n", "--", "/bin/ip", "link", "set", "foo", "netns", "1",
Garrick Evans64a2df32018-12-12 16:53:46 +090066 };
Garrick Evans2470caa2020-03-04 14:15:41 +090067 EXPECT_CALL(mj_, New());
Garrick Evans64a2df32018-12-12 16:53:46 +090068 EXPECT_CALL(mj_, DropRoot(_, _, _)).Times(0);
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090069 EXPECT_CALL(mj_, RunPipesAndDestroy(
70 _, IsProcessArgs("/usr/bin/nsenter", args), _, _, _, _));
Garrick Evans2470caa2020-03-04 14:15:41 +090071 runner_.RestoreDefaultNamespace("foo", 12345);
Garrick Evans64a2df32018-12-12 16:53:46 +090072}
73
Garrick Evans8e8e3472020-01-23 14:03:50 +090074TEST_F(MinijailProcessRunnerTest, modprobe_all) {
Garrick Evans78b414e2019-03-14 15:58:56 +090075 uint64_t caps = CAP_TO_MASK(CAP_SYS_MODULE);
76
77 const std::vector<std::string> args = {"-a", "module1", "module2"};
78 EXPECT_CALL(mj_, New());
79 EXPECT_CALL(mj_, DropRoot(_, StrEq("nobody"), StrEq("nobody")));
80 EXPECT_CALL(mj_, UseCapabilities(_, Eq(caps)));
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090081 EXPECT_CALL(mj_, RunPipesAndDestroy(_, IsProcessArgs("/sbin/modprobe", args),
82 _, _, _, _));
Garrick Evans8e8e3472020-01-23 14:03:50 +090083 runner_.modprobe_all({"module1", "module2"});
Garrick Evans78b414e2019-03-14 15:58:56 +090084}
85
Garrick Evans8e8e3472020-01-23 14:03:50 +090086TEST_F(MinijailProcessRunnerTest, sysctl_w) {
Garrick Evans6d227b92019-12-03 16:11:29 +090087 const std::vector<std::string> args = {"-w", "a.b.c=1"};
88 EXPECT_CALL(mj_, New());
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090089 EXPECT_CALL(mj_, RunPipesAndDestroy(
90 _, IsProcessArgs("/usr/sbin/sysctl", args), _, _, _, _));
Garrick Evans8e8e3472020-01-23 14:03:50 +090091 runner_.sysctl_w("a.b.c", "1");
Garrick Evans6d227b92019-12-03 16:11:29 +090092}
93
Garrick Evans8e8e3472020-01-23 14:03:50 +090094TEST_F(MinijailProcessRunnerTest, chown) {
Garrick Evans6d227b92019-12-03 16:11:29 +090095 uint64_t caps = CAP_TO_MASK(CAP_CHOWN);
96
97 const std::vector<std::string> args = {"12345:23456", "foo"};
98 EXPECT_CALL(mj_, New());
99 EXPECT_CALL(mj_, DropRoot(_, StrEq("nobody"), StrEq("nobody")));
100 EXPECT_CALL(mj_, UseCapabilities(_, Eq(caps)));
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900101 EXPECT_CALL(mj_, RunPipesAndDestroy(_, IsProcessArgs("/bin/chown", args), _,
102 _, _, _));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900103 runner_.chown("12345", "23456", "foo");
104}
105
106TEST_F(MinijailProcessRunnerTest, brctl) {
107 uint64_t caps = CAP_TO_MASK(CAP_NET_ADMIN) | CAP_TO_MASK(CAP_NET_RAW);
108 const std::vector<std::string> args = {"cmd", "arg", "arg"};
109
110 EXPECT_CALL(mj_, New());
111 EXPECT_CALL(mj_, DropRoot(_, StrEq("nobody"), StrEq("nobody")));
112 EXPECT_CALL(mj_, UseCapabilities(_, Eq(caps)));
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900113 EXPECT_CALL(mj_, RunPipesAndDestroy(_, IsProcessArgs("/sbin/brctl", args), _,
114 _, _, _));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900115 runner_.brctl("cmd", {"arg", "arg"});
116}
117
Garrick Evans8e8e3472020-01-23 14:03:50 +0900118TEST_F(MinijailProcessRunnerTest, ip) {
119 uint64_t caps = CAP_TO_MASK(CAP_NET_ADMIN) | CAP_TO_MASK(CAP_NET_RAW);
120 const std::vector<std::string> args = {"obj", "cmd", "arg", "arg"};
121
122 EXPECT_CALL(mj_, New());
123 EXPECT_CALL(mj_, DropRoot(_, StrEq("nobody"), StrEq("nobody")));
124 EXPECT_CALL(mj_, UseCapabilities(_, Eq(caps)));
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900125 EXPECT_CALL(
126 mj_, RunPipesAndDestroy(_, IsProcessArgs("/bin/ip", args), _, _, _, _));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900127 runner_.ip("obj", "cmd", {"arg", "arg"});
128}
129
130TEST_F(MinijailProcessRunnerTest, ip6) {
131 uint64_t caps = CAP_TO_MASK(CAP_NET_ADMIN) | CAP_TO_MASK(CAP_NET_RAW);
132 const std::vector<std::string> args = {"-6", "obj", "cmd", "arg", "arg"};
133
134 EXPECT_CALL(mj_, New());
135 EXPECT_CALL(mj_, DropRoot(_, StrEq("nobody"), StrEq("nobody")));
136 EXPECT_CALL(mj_, UseCapabilities(_, Eq(caps)));
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900137 EXPECT_CALL(
138 mj_, RunPipesAndDestroy(_, IsProcessArgs("/bin/ip", args), _, _, _, _));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900139 runner_.ip6("obj", "cmd", {"arg", "arg"});
140}
141
142TEST_F(MinijailProcessRunnerTest, iptables) {
143 const std::vector<std::string> args = {"-t", "table", "arg", "arg"};
144
145 EXPECT_CALL(mj_, New());
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900146 EXPECT_CALL(mj_, RunPipesAndDestroy(_, IsProcessArgs("/sbin/iptables", args),
147 _, _, _, _));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900148 runner_.iptables("table", {"arg", "arg"});
149}
150
151TEST_F(MinijailProcessRunnerTest, ip6tables) {
152 const std::vector<std::string> args = {"-t", "table", "arg", "arg"};
153
154 EXPECT_CALL(mj_, New());
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900155 EXPECT_CALL(mj_, RunPipesAndDestroy(_, IsProcessArgs("/sbin/ip6tables", args),
156 _, _, _, _));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900157 runner_.ip6tables("table", {"arg", "arg"});
Garrick Evans6d227b92019-12-03 16:11:29 +0900158}
159
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900160} // namespace
Garrick Evans3388a032020-03-24 11:25:55 +0900161} // namespace patchpanel