blob: 43e9fbea3fadf1d993a9f4af2bc209c1e3ab6649 [file] [log] [blame]
Rajat Jain5bf732b2021-01-22 14:57:59 -08001// Copyright 2021 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
5#include <base/files/scoped_temp_dir.h>
6#include <memory>
7#include <gmock/gmock.h>
8
9#include "pciguard/sysfs_utils.h"
10
11using base::CreateDirectory;
12using base::CreateSymbolicLink;
13using base::FilePath;
14using base::WriteFile;
15
16namespace pciguard {
17
18namespace {
19
20constexpr char kMockTestDevice1[] =
21 "/sys/devices/pci0000:00/0000:00:0d.2/domain0/0-0/0-1";
22constexpr char kMockTestDevice2[] =
23 "/sys/devices/pci0000:00/0000:00:0d.2/domain0/0-0/0-2";
24constexpr char kMockPciDevice[] = "/sys/bus/pci/devices/0000:04:00.0";
25constexpr char kBusThunderboltPath[] = "/sys/bus/thunderbolt";
26
27} // namespace
28
29class SysfsUtilsTest : public ::testing::Test {
30 protected:
31 void SetUp() override {
32 // Create a "fake root"
33 ASSERT_TRUE(root_dir_.CreateUniqueTempDir());
34 auto root_path = root_dir_.GetPath();
35 root_ = root_path.value();
36
37 // Create SysfsUtils and make it use the fake root.
38 utils_ = std::make_unique<SysfsUtils>(root_path);
39
40 // Setup fake sysfs in the fake root
41 ASSERT_TRUE(base::CreateDirectory(utils_->tbt_devices_path_));
42
43 // Create thunderbolt dev 1
44 auto dev = FilePath(root_ + kMockTestDevice1);
45 ASSERT_TRUE(CreateDirectory(dev));
46 ASSERT_TRUE(WriteFile(dev.Append("authorized"), "0"));
47 ASSERT_TRUE(CreateSymbolicLink(FilePath(root_ + kBusThunderboltPath),
48 dev.Append("subsystem")));
49 ASSERT_TRUE(CreateSymbolicLink(
50 dev, FilePath(root_ + "/sys/bus/thunderbolt/devices/0-1")));
51
52 // Create thunderbolt dev 2
53 dev = FilePath(root_ + kMockTestDevice2);
54 ASSERT_TRUE(CreateDirectory(dev));
55 ASSERT_TRUE(WriteFile(dev.Append("authorized"), "0"));
56 ASSERT_TRUE(CreateSymbolicLink(FilePath(root_ + kBusThunderboltPath),
57 dev.Append("subsystem")));
58 ASSERT_TRUE(CreateSymbolicLink(
59 dev, FilePath(root_ + "/sys/bus/thunderbolt/devices/0-2")));
60
61 // Create PCI dev
62 dev = base::FilePath(root_ + kMockPciDevice);
63 ASSERT_TRUE(base::CreateDirectory(dev));
64 ASSERT_TRUE(WriteFile(dev.Append("untrusted"), "1"));
65 ASSERT_TRUE(WriteFile(dev.Append("remove"), "0"));
66
67 ASSERT_TRUE(base::WriteFile(utils_->pci_lockdown_path_, "1"));
68 }
69
70 std::string root_;
71 base::ScopedTempDir root_dir_;
72 std::unique_ptr<SysfsUtils> utils_;
73};
74
75TEST_F(SysfsUtilsTest, CheckAuthorizeThunderboltDev) {
76 // Set authorized to 0 for device 1
77 auto dev1 = FilePath(root_ + kMockTestDevice1);
78 auto file1 = dev1.Append("authorized");
79 ASSERT_TRUE(WriteFile(file1, "0"));
80
81 // This should set it to "1"
82 utils_->AuthorizeThunderboltDev(dev1);
83
84 // Verify
85 std::string data = "0";
86 ASSERT_TRUE(ReadFileToString(file1, &data));
87 EXPECT_EQ(data, "1");
88
89 // Set authorized to 0 to device 2
90 auto dev2 = FilePath(root_ + kMockTestDevice2);
91 auto file2 = dev2.Append("authorized");
92 ASSERT_TRUE(WriteFile(file2, "0"));
93
94 // This should set it to "1"
95 utils_->AuthorizeThunderboltDev(dev2);
96
97 // Verify
98 data = "0";
99 ASSERT_TRUE(ReadFileToString(file2, &data));
100 EXPECT_EQ(data, "1");
101}
102
103TEST_F(SysfsUtilsTest, CheckDenyNewDevices) {
104 // Intialize lockdown with "0"
105 ASSERT_TRUE(base::WriteFile(utils_->pci_lockdown_path_, "0"));
106
107 // This should set it to "1"
108 utils_->DenyNewDevices();
109
110 // Verify
111 std::string data = "0";
112 ASSERT_TRUE(ReadFileToString(utils_->pci_lockdown_path_, &data));
113 EXPECT_EQ(data, "1");
114}
115
116TEST_F(SysfsUtilsTest, CheckAuthorizeAllDevices) {
117 // Intialize lockdown with "1""
118 ASSERT_TRUE(WriteFile(utils_->pci_lockdown_path_, "1"));
119
120 // Intialize rescan with "1""
121 ASSERT_TRUE(WriteFile(utils_->pci_rescan_path_, "0"));
122
123 // Set authorized to 0 for device 1
124 auto file1 = FilePath(root_ + kMockTestDevice1 + "/authorized");
125 ASSERT_TRUE(WriteFile(file1, "0"));
126
127 // Set authorized to 0 for device 2
128 auto file2 = FilePath(root_ + kMockTestDevice2 + "/authorized");
129 ASSERT_TRUE(WriteFile(file1, "0"));
130
131 utils_->AuthorizeAllDevices();
132
133 // Verify lockdown = 0
134 std::string data = "1";
135 ASSERT_TRUE(ReadFileToString(utils_->pci_lockdown_path_, &data));
136 EXPECT_EQ(data, "0");
137
138 // Verify rescan = 1
139 data = "0";
140 ASSERT_TRUE(ReadFileToString(utils_->pci_rescan_path_, &data));
141 EXPECT_EQ(data, "1");
142
143 // Verify file 1 is authorized
144 data = "0";
145 ASSERT_TRUE(ReadFileToString(file1, &data));
146 EXPECT_EQ(data, "1");
147
148 // Verify file 2 is authorized
149 data = "0";
150 ASSERT_TRUE(ReadFileToString(file2, &data));
151 EXPECT_EQ(data, "1");
152}
153
154TEST_F(SysfsUtilsTest, CheckDeauthorizeAllDevices) {
155 // Intialize lockdown with "0"
156 ASSERT_TRUE(base::WriteFile(utils_->pci_lockdown_path_, "0"));
157
158 auto remove = FilePath(root_ + kMockPciDevice + "/remove");
159 ASSERT_TRUE(base::WriteFile(remove, "0"));
160
161 // Set authorized to 1 for device 1
162 auto file1 = FilePath(root_ + kMockTestDevice1 + "/authorized");
163 ASSERT_TRUE(WriteFile(file1, "1"));
164
165 // Set authorized to 1 for device 2
166 auto file2 = FilePath(root_ + kMockTestDevice2 + "/authorized");
167 ASSERT_TRUE(WriteFile(file2, "1"));
168
169 utils_->DeauthorizeAllDevices();
170
171 // Verify
172 std::string data = "0";
173 ASSERT_TRUE(ReadFileToString(utils_->pci_lockdown_path_, &data));
174 EXPECT_EQ(data, "1");
175
176 data = "0";
177 ASSERT_TRUE(ReadFileToString(remove, &data));
178 EXPECT_EQ(data, "1");
179
180 // Verify file 1 is deauthorized
181 data = "1";
182 ASSERT_TRUE(ReadFileToString(file1, &data));
183 EXPECT_EQ(data, "0");
184
185 // Verify file 2 is deauthorized
186 data = "1";
187 ASSERT_TRUE(ReadFileToString(file2, &data));
188 EXPECT_EQ(data, "0");
189}
190
Rajat Jain5bf732b2021-01-22 14:57:59 -0800191} // namespace pciguard