blob: a21aa60c137df1eb2e30df829adfe241d101900e [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 Evans8e8e3472020-01-23 14:03:50 +090063TEST_F(MinijailProcessRunnerTest, modprobe_all) {
Garrick Evans78b414e2019-03-14 15:58:56 +090064 uint64_t caps = CAP_TO_MASK(CAP_SYS_MODULE);
65
66 const std::vector<std::string> args = {"-a", "module1", "module2"};
67 EXPECT_CALL(mj_, New());
68 EXPECT_CALL(mj_, DropRoot(_, StrEq("nobody"), StrEq("nobody")));
69 EXPECT_CALL(mj_, UseCapabilities(_, Eq(caps)));
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090070 EXPECT_CALL(mj_, RunPipesAndDestroy(_, IsProcessArgs("/sbin/modprobe", args),
71 _, _, _, _));
Garrick Evans8e8e3472020-01-23 14:03:50 +090072 runner_.modprobe_all({"module1", "module2"});
Garrick Evans78b414e2019-03-14 15:58:56 +090073}
74
Garrick Evans8e8e3472020-01-23 14:03:50 +090075TEST_F(MinijailProcessRunnerTest, sysctl_w) {
Garrick Evans6d227b92019-12-03 16:11:29 +090076 const std::vector<std::string> args = {"-w", "a.b.c=1"};
77 EXPECT_CALL(mj_, New());
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090078 EXPECT_CALL(mj_, RunPipesAndDestroy(
79 _, IsProcessArgs("/usr/sbin/sysctl", args), _, _, _, _));
Garrick Evans8e8e3472020-01-23 14:03:50 +090080 runner_.sysctl_w("a.b.c", "1");
Garrick Evans6d227b92019-12-03 16:11:29 +090081}
82
Garrick Evans8e8e3472020-01-23 14:03:50 +090083TEST_F(MinijailProcessRunnerTest, ip) {
84 uint64_t caps = CAP_TO_MASK(CAP_NET_ADMIN) | CAP_TO_MASK(CAP_NET_RAW);
85 const std::vector<std::string> args = {"obj", "cmd", "arg", "arg"};
86
87 EXPECT_CALL(mj_, New());
88 EXPECT_CALL(mj_, DropRoot(_, StrEq("nobody"), StrEq("nobody")));
89 EXPECT_CALL(mj_, UseCapabilities(_, Eq(caps)));
Jie Jiangcf5ce9c2020-07-14 17:22:03 +090090 EXPECT_CALL(
91 mj_, RunPipesAndDestroy(_, IsProcessArgs("/bin/ip", args), _, _, _, _));
Garrick Evans8e8e3472020-01-23 14:03:50 +090092 runner_.ip("obj", "cmd", {"arg", "arg"});
93}
94
95TEST_F(MinijailProcessRunnerTest, ip6) {
96 uint64_t caps = CAP_TO_MASK(CAP_NET_ADMIN) | CAP_TO_MASK(CAP_NET_RAW);
97 const std::vector<std::string> args = {"-6", "obj", "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)));
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900102 EXPECT_CALL(
103 mj_, RunPipesAndDestroy(_, IsProcessArgs("/bin/ip", args), _, _, _, _));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900104 runner_.ip6("obj", "cmd", {"arg", "arg"});
105}
106
107TEST_F(MinijailProcessRunnerTest, iptables) {
108 const std::vector<std::string> args = {"-t", "table", "arg", "arg"};
109
110 EXPECT_CALL(mj_, New());
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900111 EXPECT_CALL(mj_, RunPipesAndDestroy(_, IsProcessArgs("/sbin/iptables", args),
112 _, _, _, _));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900113 runner_.iptables("table", {"arg", "arg"});
114}
115
116TEST_F(MinijailProcessRunnerTest, ip6tables) {
117 const std::vector<std::string> args = {"-t", "table", "arg", "arg"};
118
119 EXPECT_CALL(mj_, New());
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900120 EXPECT_CALL(mj_, RunPipesAndDestroy(_, IsProcessArgs("/sbin/ip6tables", args),
121 _, _, _, _));
Garrick Evans8e8e3472020-01-23 14:03:50 +0900122 runner_.ip6tables("table", {"arg", "arg"});
Garrick Evans6d227b92019-12-03 16:11:29 +0900123}
124
Jie Jiangcf5ce9c2020-07-14 17:22:03 +0900125} // namespace
Garrick Evans3388a032020-03-24 11:25:55 +0900126} // namespace patchpanel