blob: eba00cb78f403f8c824bcd4249b9a63cf2fbce45 [file] [log] [blame]
Tom Cherryc44f6a42017-04-05 15:58:31 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "devices.h"
18
Tom Cherryc44f6a42017-04-05 15:58:31 -070019#include <android-base/scopeguard.h>
Sandeep Patilcd2ba0d2017-06-21 12:46:41 -070020#include <android-base/test_utils.h>
Tom Cherryc44f6a42017-04-05 15:58:31 -070021#include <gtest/gtest.h>
22
Sandeep Patilcd2ba0d2017-06-21 12:46:41 -070023#include "util.h"
24
25using namespace std::string_literals;
26
Tom Cherry81f5d3e2017-06-22 12:53:17 -070027namespace android {
28namespace init {
29
Tom Cherryed506f72017-05-25 15:58:59 -070030class DeviceHandlerTester {
31 public:
Sandeep Patilcd2ba0d2017-06-21 12:46:41 -070032 void TestGetSymlinks(const std::string& platform_device, const Uevent& uevent,
Tom Cherryb4dd8812017-06-23 12:43:48 -070033 const std::vector<std::string> expected_links) {
Sandeep Patilcd2ba0d2017-06-21 12:46:41 -070034 TemporaryDir fake_sys_root;
35 device_handler_.sysfs_mount_point_ = fake_sys_root.path;
36
37 std::string platform_device_dir = fake_sys_root.path + platform_device;
Tom Cherry16380362017-08-10 12:22:44 -070038 mkdir_recursive(platform_device_dir, 0777);
Sandeep Patilcd2ba0d2017-06-21 12:46:41 -070039
40 std::string platform_bus = fake_sys_root.path + "/bus/platform"s;
Tom Cherry16380362017-08-10 12:22:44 -070041 mkdir_recursive(platform_bus, 0777);
Sandeep Patilcd2ba0d2017-06-21 12:46:41 -070042 symlink(platform_bus.c_str(), (platform_device_dir + "/subsystem").c_str());
43
Tom Cherry16380362017-08-10 12:22:44 -070044 mkdir_recursive(android::base::Dirname(fake_sys_root.path + uevent.path), 0777);
Tom Cherryed506f72017-05-25 15:58:59 -070045
46 std::vector<std::string> result;
Tom Cherryb4dd8812017-06-23 12:43:48 -070047 result = device_handler_.GetBlockDeviceSymlinks(uevent);
Tom Cherryed506f72017-05-25 15:58:59 -070048
49 auto expected_size = expected_links.size();
50 ASSERT_EQ(expected_size, result.size());
51 if (expected_size == 0) return;
52
53 // Explicitly iterate so the results are visible if a failure occurs
54 for (unsigned int i = 0; i < expected_size; ++i) {
55 EXPECT_EQ(expected_links[i], result[i]);
56 }
57 }
58
59 private:
60 DeviceHandler device_handler_;
61};
62
Tom Cherryed506f72017-05-25 15:58:59 -070063TEST(device_handler, get_block_device_symlinks_success_platform) {
Tom Cherryc44f6a42017-04-05 15:58:31 -070064 // These are actual paths from bullhead
65 const char* platform_device = "/devices/soc.0/f9824900.sdhci";
Tom Cherryed506f72017-05-25 15:58:59 -070066 Uevent uevent = {
Tom Cherryc44f6a42017-04-05 15:58:31 -070067 .path = "/devices/soc.0/f9824900.sdhci/mmc_host/mmc0/mmc0:0001/block/mmcblk0",
Tom Cherrye3e48212017-04-11 13:53:37 -070068 .partition_name = "",
Tom Cherryc44f6a42017-04-05 15:58:31 -070069 .partition_num = -1,
70 };
71 std::vector<std::string> expected_result{"/dev/block/platform/soc.0/f9824900.sdhci/mmcblk0"};
72
Tom Cherryed506f72017-05-25 15:58:59 -070073 DeviceHandlerTester device_handler_tester_;
Tom Cherryb4dd8812017-06-23 12:43:48 -070074 device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
Tom Cherryc44f6a42017-04-05 15:58:31 -070075}
76
Tom Cherryed506f72017-05-25 15:58:59 -070077TEST(device_handler, get_block_device_symlinks_success_platform_with_partition) {
Tom Cherryc44f6a42017-04-05 15:58:31 -070078 // These are actual paths from bullhead
79 const char* platform_device = "/devices/soc.0/f9824900.sdhci";
Tom Cherryed506f72017-05-25 15:58:59 -070080 Uevent uevent = {
Tom Cherryc44f6a42017-04-05 15:58:31 -070081 .path = "/devices/soc.0/f9824900.sdhci/mmc_host/mmc0/mmc0:0001/block/mmcblk0p1",
82 .partition_name = "modem",
83 .partition_num = 1,
84 };
85 std::vector<std::string> expected_result{
86 "/dev/block/platform/soc.0/f9824900.sdhci/by-name/modem",
87 "/dev/block/platform/soc.0/f9824900.sdhci/by-num/p1",
88 "/dev/block/platform/soc.0/f9824900.sdhci/mmcblk0p1",
89 };
90
Tom Cherryed506f72017-05-25 15:58:59 -070091 DeviceHandlerTester device_handler_tester_;
Tom Cherryb4dd8812017-06-23 12:43:48 -070092 device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
Tom Cherryc44f6a42017-04-05 15:58:31 -070093}
94
Tom Cherryed506f72017-05-25 15:58:59 -070095TEST(device_handler, get_block_device_symlinks_success_platform_with_partition_only_num) {
Tom Cherryc44f6a42017-04-05 15:58:31 -070096 const char* platform_device = "/devices/soc.0/f9824900.sdhci";
Tom Cherryed506f72017-05-25 15:58:59 -070097 Uevent uevent = {
Tom Cherryc44f6a42017-04-05 15:58:31 -070098 .path = "/devices/soc.0/f9824900.sdhci/mmc_host/mmc0/mmc0:0001/block/mmcblk0p1",
Tom Cherrye3e48212017-04-11 13:53:37 -070099 .partition_name = "",
Tom Cherryc44f6a42017-04-05 15:58:31 -0700100 .partition_num = 1,
101 };
102 std::vector<std::string> expected_result{
103 "/dev/block/platform/soc.0/f9824900.sdhci/by-num/p1",
104 "/dev/block/platform/soc.0/f9824900.sdhci/mmcblk0p1",
105 };
106
Tom Cherryed506f72017-05-25 15:58:59 -0700107 DeviceHandlerTester device_handler_tester_;
Tom Cherryb4dd8812017-06-23 12:43:48 -0700108 device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
Tom Cherryc44f6a42017-04-05 15:58:31 -0700109}
110
Tom Cherryed506f72017-05-25 15:58:59 -0700111TEST(device_handler, get_block_device_symlinks_success_platform_with_partition_only_name) {
Tom Cherryc44f6a42017-04-05 15:58:31 -0700112 const char* platform_device = "/devices/soc.0/f9824900.sdhci";
Tom Cherryed506f72017-05-25 15:58:59 -0700113 Uevent uevent = {
Tom Cherryc44f6a42017-04-05 15:58:31 -0700114 .path = "/devices/soc.0/f9824900.sdhci/mmc_host/mmc0/mmc0:0001/block/mmcblk0p1",
115 .partition_name = "modem",
116 .partition_num = -1,
117 };
118 std::vector<std::string> expected_result{
119 "/dev/block/platform/soc.0/f9824900.sdhci/by-name/modem",
120 "/dev/block/platform/soc.0/f9824900.sdhci/mmcblk0p1",
121 };
122
Tom Cherryed506f72017-05-25 15:58:59 -0700123 DeviceHandlerTester device_handler_tester_;
Tom Cherryb4dd8812017-06-23 12:43:48 -0700124 device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
Tom Cherryc44f6a42017-04-05 15:58:31 -0700125}
126
Tom Cherryed506f72017-05-25 15:58:59 -0700127TEST(device_handler, get_block_device_symlinks_success_pci) {
Tom Cherryc44f6a42017-04-05 15:58:31 -0700128 const char* platform_device = "/devices/do/not/match";
Tom Cherryed506f72017-05-25 15:58:59 -0700129 Uevent uevent = {
Tom Cherrye3e48212017-04-11 13:53:37 -0700130 .path = "/devices/pci0000:00/0000:00:1f.2/mmcblk0", .partition_name = "", .partition_num = -1,
Tom Cherryc44f6a42017-04-05 15:58:31 -0700131 };
132 std::vector<std::string> expected_result{"/dev/block/pci/pci0000:00/0000:00:1f.2/mmcblk0"};
133
Tom Cherryed506f72017-05-25 15:58:59 -0700134 DeviceHandlerTester device_handler_tester_;
Tom Cherryb4dd8812017-06-23 12:43:48 -0700135 device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
Tom Cherryc44f6a42017-04-05 15:58:31 -0700136}
137
Tom Cherryed506f72017-05-25 15:58:59 -0700138TEST(device_handler, get_block_device_symlinks_pci_bad_format) {
Tom Cherry2e344f92017-04-04 17:53:45 -0700139 const char* platform_device = "/devices/do/not/match";
Tom Cherryed506f72017-05-25 15:58:59 -0700140 Uevent uevent = {
Tom Cherrye3e48212017-04-11 13:53:37 -0700141 .path = "/devices/pci//mmcblk0", .partition_name = "", .partition_num = -1,
Tom Cherry2e344f92017-04-04 17:53:45 -0700142 };
143 std::vector<std::string> expected_result{};
144
Tom Cherryed506f72017-05-25 15:58:59 -0700145 DeviceHandlerTester device_handler_tester_;
Tom Cherryb4dd8812017-06-23 12:43:48 -0700146 device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
Tom Cherry2e344f92017-04-04 17:53:45 -0700147}
148
Tom Cherryed506f72017-05-25 15:58:59 -0700149TEST(device_handler, get_block_device_symlinks_success_vbd) {
Tom Cherryc44f6a42017-04-05 15:58:31 -0700150 const char* platform_device = "/devices/do/not/match";
Tom Cherryed506f72017-05-25 15:58:59 -0700151 Uevent uevent = {
Tom Cherrye3e48212017-04-11 13:53:37 -0700152 .path = "/devices/vbd-1234/mmcblk0", .partition_name = "", .partition_num = -1,
Tom Cherryc44f6a42017-04-05 15:58:31 -0700153 };
154 std::vector<std::string> expected_result{"/dev/block/vbd/1234/mmcblk0"};
155
Tom Cherryed506f72017-05-25 15:58:59 -0700156 DeviceHandlerTester device_handler_tester_;
Tom Cherryb4dd8812017-06-23 12:43:48 -0700157 device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
Tom Cherryc44f6a42017-04-05 15:58:31 -0700158}
159
Tom Cherryed506f72017-05-25 15:58:59 -0700160TEST(device_handler, get_block_device_symlinks_vbd_bad_format) {
Tom Cherry2e344f92017-04-04 17:53:45 -0700161 const char* platform_device = "/devices/do/not/match";
Tom Cherryed506f72017-05-25 15:58:59 -0700162 Uevent uevent = {
Tom Cherrye3e48212017-04-11 13:53:37 -0700163 .path = "/devices/vbd-/mmcblk0", .partition_name = "", .partition_num = -1,
Tom Cherry2e344f92017-04-04 17:53:45 -0700164 };
165 std::vector<std::string> expected_result{};
166
Tom Cherryed506f72017-05-25 15:58:59 -0700167 DeviceHandlerTester device_handler_tester_;
Tom Cherryb4dd8812017-06-23 12:43:48 -0700168 device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
Tom Cherry2e344f92017-04-04 17:53:45 -0700169}
170
Tom Cherryed506f72017-05-25 15:58:59 -0700171TEST(device_handler, get_block_device_symlinks_no_matches) {
Tom Cherryc44f6a42017-04-05 15:58:31 -0700172 const char* platform_device = "/devices/soc.0/f9824900.sdhci";
Tom Cherryed506f72017-05-25 15:58:59 -0700173 Uevent uevent = {
Tom Cherryc44f6a42017-04-05 15:58:31 -0700174 .path = "/devices/soc.0/not_the_device/mmc_host/mmc0/mmc0:0001/block/mmcblk0p1",
Tom Cherrye3e48212017-04-11 13:53:37 -0700175 .partition_name = "",
Tom Cherryc44f6a42017-04-05 15:58:31 -0700176 .partition_num = -1,
177 };
178 std::vector<std::string> expected_result;
179
Tom Cherryed506f72017-05-25 15:58:59 -0700180 DeviceHandlerTester device_handler_tester_;
Tom Cherryb4dd8812017-06-23 12:43:48 -0700181 device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
Tom Cherryc44f6a42017-04-05 15:58:31 -0700182}
183
Tom Cherryed506f72017-05-25 15:58:59 -0700184TEST(device_handler, sanitize_null) {
185 SanitizePartitionName(nullptr);
Tom Cherryc44f6a42017-04-05 15:58:31 -0700186}
187
Tom Cherryed506f72017-05-25 15:58:59 -0700188TEST(device_handler, sanitize_empty) {
Tom Cherryc44f6a42017-04-05 15:58:31 -0700189 std::string empty;
Tom Cherryed506f72017-05-25 15:58:59 -0700190 SanitizePartitionName(&empty);
Tom Cherryc44f6a42017-04-05 15:58:31 -0700191 EXPECT_EQ(0u, empty.size());
192}
193
Tom Cherryed506f72017-05-25 15:58:59 -0700194TEST(device_handler, sanitize_allgood) {
Tom Cherryc44f6a42017-04-05 15:58:31 -0700195 std::string good =
196 "abcdefghijklmnopqrstuvwxyz"
197 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
198 "0123456789"
199 "_-.";
200 std::string good_copy = good;
Tom Cherryed506f72017-05-25 15:58:59 -0700201 SanitizePartitionName(&good);
Tom Cherryc44f6a42017-04-05 15:58:31 -0700202 EXPECT_EQ(good_copy, good);
203}
204
Tom Cherryed506f72017-05-25 15:58:59 -0700205TEST(device_handler, sanitize_somebad) {
Tom Cherryc44f6a42017-04-05 15:58:31 -0700206 std::string string = "abc!@#$%^&*()";
Tom Cherryed506f72017-05-25 15:58:59 -0700207 SanitizePartitionName(&string);
Tom Cherryc44f6a42017-04-05 15:58:31 -0700208 EXPECT_EQ("abc__________", string);
209}
210
Tom Cherryed506f72017-05-25 15:58:59 -0700211TEST(device_handler, sanitize_allbad) {
Tom Cherryc44f6a42017-04-05 15:58:31 -0700212 std::string string = "!@#$%^&*()";
Tom Cherryed506f72017-05-25 15:58:59 -0700213 SanitizePartitionName(&string);
Tom Cherryc44f6a42017-04-05 15:58:31 -0700214 EXPECT_EQ("__________", string);
215}
216
Tom Cherryed506f72017-05-25 15:58:59 -0700217TEST(device_handler, sanitize_onebad) {
Tom Cherryc44f6a42017-04-05 15:58:31 -0700218 std::string string = ")";
Tom Cherryed506f72017-05-25 15:58:59 -0700219 SanitizePartitionName(&string);
Tom Cherryc44f6a42017-04-05 15:58:31 -0700220 EXPECT_EQ("_", string);
221}
Tom Cherrycc054c92017-04-05 17:55:46 -0700222
Tom Cherryed506f72017-05-25 15:58:59 -0700223TEST(device_handler, DevPermissionsMatchNormal) {
Tom Cherrycc054c92017-04-05 17:55:46 -0700224 // Basic from ueventd.rc
225 // /dev/null 0666 root root
226 Permissions permissions("/dev/null", 0666, 0, 0);
227 EXPECT_TRUE(permissions.Match("/dev/null"));
228 EXPECT_FALSE(permissions.Match("/dev/nullsuffix"));
229 EXPECT_FALSE(permissions.Match("/dev/nul"));
230 EXPECT_EQ(0666U, permissions.perm());
231 EXPECT_EQ(0U, permissions.uid());
232 EXPECT_EQ(0U, permissions.gid());
233}
234
Tom Cherryed506f72017-05-25 15:58:59 -0700235TEST(device_handler, DevPermissionsMatchPrefix) {
Tom Cherrycc054c92017-04-05 17:55:46 -0700236 // Prefix from ueventd.rc
237 // /dev/dri/* 0666 root graphics
238 Permissions permissions("/dev/dri/*", 0666, 0, 1000);
239 EXPECT_TRUE(permissions.Match("/dev/dri/some_dri_device"));
240 EXPECT_TRUE(permissions.Match("/dev/dri/some_other_dri_device"));
241 EXPECT_TRUE(permissions.Match("/dev/dri/"));
242 EXPECT_FALSE(permissions.Match("/dev/dr/non_match"));
243 EXPECT_EQ(0666U, permissions.perm());
244 EXPECT_EQ(0U, permissions.uid());
245 EXPECT_EQ(1000U, permissions.gid());
246}
247
Tom Cherryed506f72017-05-25 15:58:59 -0700248TEST(device_handler, DevPermissionsMatchWildcard) {
Tom Cherrycc054c92017-04-05 17:55:46 -0700249 // Wildcard example
250 // /dev/device*name 0666 root graphics
251 Permissions permissions("/dev/device*name", 0666, 0, 1000);
252 EXPECT_TRUE(permissions.Match("/dev/devicename"));
253 EXPECT_TRUE(permissions.Match("/dev/device123name"));
254 EXPECT_TRUE(permissions.Match("/dev/deviceabcname"));
255 EXPECT_FALSE(permissions.Match("/dev/device123name/subdevice"));
256 EXPECT_FALSE(permissions.Match("/dev/deviceame"));
257 EXPECT_EQ(0666U, permissions.perm());
258 EXPECT_EQ(0U, permissions.uid());
259 EXPECT_EQ(1000U, permissions.gid());
260}
261
Tom Cherryed506f72017-05-25 15:58:59 -0700262TEST(device_handler, DevPermissionsMatchWildcardPrefix) {
Tom Cherrycc054c92017-04-05 17:55:46 -0700263 // Wildcard+Prefix example
264 // /dev/device*name* 0666 root graphics
265 Permissions permissions("/dev/device*name*", 0666, 0, 1000);
266 EXPECT_TRUE(permissions.Match("/dev/devicename"));
267 EXPECT_TRUE(permissions.Match("/dev/device123name"));
268 EXPECT_TRUE(permissions.Match("/dev/deviceabcname"));
269 EXPECT_TRUE(permissions.Match("/dev/device123namesomething"));
270 // FNM_PATHNAME doesn't match '/' with *
271 EXPECT_FALSE(permissions.Match("/dev/device123name/something"));
272 EXPECT_FALSE(permissions.Match("/dev/deviceame"));
273 EXPECT_EQ(0666U, permissions.perm());
274 EXPECT_EQ(0U, permissions.uid());
275 EXPECT_EQ(1000U, permissions.gid());
276}
277
Tom Cherryed506f72017-05-25 15:58:59 -0700278TEST(device_handler, SysfsPermissionsMatchWithSubsystemNormal) {
Tom Cherrycc054c92017-04-05 17:55:46 -0700279 // /sys/devices/virtual/input/input* enable 0660 root input
280 SysfsPermissions permissions("/sys/devices/virtual/input/input*", "enable", 0660, 0, 1001);
281 EXPECT_TRUE(permissions.MatchWithSubsystem("/sys/devices/virtual/input/input0", "input"));
282 EXPECT_FALSE(permissions.MatchWithSubsystem("/sys/devices/virtual/input/not_input0", "input"));
283 EXPECT_EQ(0660U, permissions.perm());
284 EXPECT_EQ(0U, permissions.uid());
285 EXPECT_EQ(1001U, permissions.gid());
286}
287
Tom Cherryed506f72017-05-25 15:58:59 -0700288TEST(device_handler, SysfsPermissionsMatchWithSubsystemClass) {
Tom Cherrycc054c92017-04-05 17:55:46 -0700289 // /sys/class/input/event* enable 0660 root input
290 SysfsPermissions permissions("/sys/class/input/event*", "enable", 0660, 0, 1001);
291 EXPECT_TRUE(permissions.MatchWithSubsystem(
292 "/sys/devices/soc.0/f9924000.i2c/i2c-2/2-0020/input/input0/event0", "input"));
293 EXPECT_FALSE(permissions.MatchWithSubsystem(
294 "/sys/devices/soc.0/f9924000.i2c/i2c-2/2-0020/input/input0/not_event0", "input"));
295 EXPECT_FALSE(permissions.MatchWithSubsystem(
296 "/sys/devices/soc.0/f9924000.i2c/i2c-2/2-0020/input/input0/event0", "not_input"));
297 EXPECT_EQ(0660U, permissions.perm());
298 EXPECT_EQ(0U, permissions.uid());
299 EXPECT_EQ(1001U, permissions.gid());
300}
301
Tom Cherryed506f72017-05-25 15:58:59 -0700302TEST(device_handler, SysfsPermissionsMatchWithSubsystemBus) {
Tom Cherrycc054c92017-04-05 17:55:46 -0700303 // /sys/bus/i2c/devices/i2c-* enable 0660 root input
304 SysfsPermissions permissions("/sys/bus/i2c/devices/i2c-*", "enable", 0660, 0, 1001);
305 EXPECT_TRUE(permissions.MatchWithSubsystem("/sys/devices/soc.0/f9967000.i2c/i2c-5", "i2c"));
306 EXPECT_FALSE(permissions.MatchWithSubsystem("/sys/devices/soc.0/f9967000.i2c/not-i2c", "i2c"));
307 EXPECT_FALSE(
308 permissions.MatchWithSubsystem("/sys/devices/soc.0/f9967000.i2c/i2c-5", "not_i2c"));
309 EXPECT_EQ(0660U, permissions.perm());
310 EXPECT_EQ(0U, permissions.uid());
311 EXPECT_EQ(1001U, permissions.gid());
312}
Tom Cherry81f5d3e2017-06-22 12:53:17 -0700313
314} // namespace init
315} // namespace android