blob: 28be649683be8373dccc7da6bc5e759b3b2a5b01 [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>
8
9#include <brillo/minijail/mock_minijail.h>
10#include <gmock/gmock.h>
11#include <gtest/gtest.h>
12
Garrick Evans3388a032020-03-24 11:25:55 +090013#include "patchpanel/net_util.h"
Garrick Evans7a1a9ee2020-01-28 11:03:57 +090014
Garrick Evans64a2df32018-12-12 16:53:46 +090015using testing::_;
16using testing::DoAll;
17using testing::Eq;
18using testing::Return;
19using testing::SetArgPointee;
20using testing::StrEq;
21
Garrick Evans3388a032020-03-24 11:25:55 +090022namespace patchpanel {
Garrick Evans64a2df32018-12-12 16:53:46 +090023
24class MinijailProcessRunnerTest : public testing::Test {
25 protected:
26 MinijailProcessRunnerTest() : runner_(&mj_) {}
27
28 void SetUp() override {
29 ON_CALL(mj_, DropRoot(_, _, _)).WillByDefault(Return(true));
30 ON_CALL(mj_, RunSyncAndDestroy(_, _, _))
31 .WillByDefault(DoAll(SetArgPointee<2>(0), Return(true)));
32 }
33
34 brillo::MockMinijail mj_;
35 MinijailedProcessRunner runner_;
36};
37
38// Special matcher needed for vector<char*> type.
39// Lifted from shill/process_manager_test.cc
40MATCHER_P2(IsProcessArgs, program, args, "") {
41 if (std::string(arg[0]) != program) {
42 return false;
43 }
44 int index = 1;
45 for (const auto& option : args) {
46 if (std::string(arg[index++]) != option) {
47 return false;
48 }
49 }
50 return arg[index] == nullptr;
51}
52
Garrick Evans2470caa2020-03-04 14:15:41 +090053TEST_F(MinijailProcessRunnerTest, RestoreDefaultNamespace) {
54 const std::vector<std::string> args = {
55 "-t", "12345", "-n", "--", "/bin/ip", "link", "set", "foo", "netns", "1",
Garrick Evans64a2df32018-12-12 16:53:46 +090056 };
Garrick Evans2470caa2020-03-04 14:15:41 +090057 EXPECT_CALL(mj_, New());
Garrick Evans64a2df32018-12-12 16:53:46 +090058 EXPECT_CALL(mj_, DropRoot(_, _, _)).Times(0);
Garrick Evans2470caa2020-03-04 14:15:41 +090059 EXPECT_CALL(mj_,
60 RunSyncAndDestroy(_, IsProcessArgs("/usr/bin/nsenter", args), _));
61 runner_.RestoreDefaultNamespace("foo", 12345);
Garrick Evans64a2df32018-12-12 16:53:46 +090062}
63
Garrick Evans8e8e3472020-01-23 14:03:50 +090064TEST_F(MinijailProcessRunnerTest, modprobe_all) {
Garrick Evans78b414e2019-03-14 15:58:56 +090065 uint64_t caps = CAP_TO_MASK(CAP_SYS_MODULE);
66
67 const std::vector<std::string> args = {"-a", "module1", "module2"};
68 EXPECT_CALL(mj_, New());
69 EXPECT_CALL(mj_, DropRoot(_, StrEq("nobody"), StrEq("nobody")));
70 EXPECT_CALL(mj_, UseCapabilities(_, Eq(caps)));
71 EXPECT_CALL(mj_,
72 RunSyncAndDestroy(_, IsProcessArgs("/sbin/modprobe", args), _));
Garrick Evans8e8e3472020-01-23 14:03:50 +090073 runner_.modprobe_all({"module1", "module2"});
Garrick Evans78b414e2019-03-14 15:58:56 +090074}
75
Garrick Evans8e8e3472020-01-23 14:03:50 +090076TEST_F(MinijailProcessRunnerTest, sysctl_w) {
Garrick Evans6d227b92019-12-03 16:11:29 +090077 const std::vector<std::string> args = {"-w", "a.b.c=1"};
78 EXPECT_CALL(mj_, New());
79 EXPECT_CALL(mj_,
80 RunSyncAndDestroy(_, IsProcessArgs("/usr/sbin/sysctl", args), _));
Garrick Evans8e8e3472020-01-23 14:03:50 +090081 runner_.sysctl_w("a.b.c", "1");
Garrick Evans6d227b92019-12-03 16:11:29 +090082}
83
Garrick Evans8e8e3472020-01-23 14:03:50 +090084TEST_F(MinijailProcessRunnerTest, chown) {
Garrick Evans6d227b92019-12-03 16:11:29 +090085 uint64_t caps = CAP_TO_MASK(CAP_CHOWN);
86
87 const std::vector<std::string> args = {"12345:23456", "foo"};
88 EXPECT_CALL(mj_, New());
89 EXPECT_CALL(mj_, DropRoot(_, StrEq("nobody"), StrEq("nobody")));
90 EXPECT_CALL(mj_, UseCapabilities(_, Eq(caps)));
91 EXPECT_CALL(mj_, RunSyncAndDestroy(_, IsProcessArgs("/bin/chown", args), _));
Garrick Evans8e8e3472020-01-23 14:03:50 +090092 runner_.chown("12345", "23456", "foo");
93}
94
95TEST_F(MinijailProcessRunnerTest, brctl) {
96 uint64_t caps = CAP_TO_MASK(CAP_NET_ADMIN) | CAP_TO_MASK(CAP_NET_RAW);
97 const std::vector<std::string> args = {"cmd", "arg", "arg"};
98
99 EXPECT_CALL(mj_, New());
100 EXPECT_CALL(mj_, DropRoot(_, StrEq("nobody"), StrEq("nobody")));
101 EXPECT_CALL(mj_, UseCapabilities(_, Eq(caps)));
102 EXPECT_CALL(mj_, RunSyncAndDestroy(_, IsProcessArgs("/sbin/brctl", args), _));
103 runner_.brctl("cmd", {"arg", "arg"});
104}
105
Garrick Evans8e8e3472020-01-23 14:03:50 +0900106TEST_F(MinijailProcessRunnerTest, ip) {
107 uint64_t caps = CAP_TO_MASK(CAP_NET_ADMIN) | CAP_TO_MASK(CAP_NET_RAW);
108 const std::vector<std::string> args = {"obj", "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)));
113 EXPECT_CALL(mj_, RunSyncAndDestroy(_, IsProcessArgs("/bin/ip", args), _));
114 runner_.ip("obj", "cmd", {"arg", "arg"});
115}
116
117TEST_F(MinijailProcessRunnerTest, ip6) {
118 uint64_t caps = CAP_TO_MASK(CAP_NET_ADMIN) | CAP_TO_MASK(CAP_NET_RAW);
119 const std::vector<std::string> args = {"-6", "obj", "cmd", "arg", "arg"};
120
121 EXPECT_CALL(mj_, New());
122 EXPECT_CALL(mj_, DropRoot(_, StrEq("nobody"), StrEq("nobody")));
123 EXPECT_CALL(mj_, UseCapabilities(_, Eq(caps)));
124 EXPECT_CALL(mj_, RunSyncAndDestroy(_, IsProcessArgs("/bin/ip", args), _));
125 runner_.ip6("obj", "cmd", {"arg", "arg"});
126}
127
128TEST_F(MinijailProcessRunnerTest, iptables) {
129 const std::vector<std::string> args = {"-t", "table", "arg", "arg"};
130
131 EXPECT_CALL(mj_, New());
132 EXPECT_CALL(mj_,
133 RunSyncAndDestroy(_, IsProcessArgs("/sbin/iptables", args), _));
134 runner_.iptables("table", {"arg", "arg"});
135}
136
137TEST_F(MinijailProcessRunnerTest, ip6tables) {
138 const std::vector<std::string> args = {"-t", "table", "arg", "arg"};
139
140 EXPECT_CALL(mj_, New());
141 EXPECT_CALL(mj_,
142 RunSyncAndDestroy(_, IsProcessArgs("/sbin/ip6tables", args), _));
143 runner_.ip6tables("table", {"arg", "arg"});
Garrick Evans6d227b92019-12-03 16:11:29 +0900144}
145
Garrick Evans3388a032020-03-24 11:25:55 +0900146} // namespace patchpanel