blob: d658f4d9a119d649bf3505ce8274fe74f1427464 [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",
Tom Cherryc44f6a42017-04-05 15:58:31 -070087 "/dev/block/platform/soc.0/f9824900.sdhci/mmcblk0p1",
88 };
89
Tom Cherryed506f72017-05-25 15:58:59 -070090 DeviceHandlerTester device_handler_tester_;
Tom Cherryb4dd8812017-06-23 12:43:48 -070091 device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
Tom Cherryc44f6a42017-04-05 15:58:31 -070092}
93
Tom Cherryed506f72017-05-25 15:58:59 -070094TEST(device_handler, get_block_device_symlinks_success_platform_with_partition_only_num) {
Tom Cherryc44f6a42017-04-05 15:58:31 -070095 const char* platform_device = "/devices/soc.0/f9824900.sdhci";
Tom Cherryed506f72017-05-25 15:58:59 -070096 Uevent uevent = {
Tom Cherryc44f6a42017-04-05 15:58:31 -070097 .path = "/devices/soc.0/f9824900.sdhci/mmc_host/mmc0/mmc0:0001/block/mmcblk0p1",
Tom Cherrye3e48212017-04-11 13:53:37 -070098 .partition_name = "",
Tom Cherryc44f6a42017-04-05 15:58:31 -070099 .partition_num = 1,
100 };
101 std::vector<std::string> expected_result{
Tom Cherryc44f6a42017-04-05 15:58:31 -0700102 "/dev/block/platform/soc.0/f9824900.sdhci/mmcblk0p1",
103 };
104
Tom Cherryed506f72017-05-25 15:58:59 -0700105 DeviceHandlerTester device_handler_tester_;
Tom Cherryb4dd8812017-06-23 12:43:48 -0700106 device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
Tom Cherryc44f6a42017-04-05 15:58:31 -0700107}
108
Tom Cherryed506f72017-05-25 15:58:59 -0700109TEST(device_handler, get_block_device_symlinks_success_platform_with_partition_only_name) {
Tom Cherryc44f6a42017-04-05 15:58:31 -0700110 const char* platform_device = "/devices/soc.0/f9824900.sdhci";
Tom Cherryed506f72017-05-25 15:58:59 -0700111 Uevent uevent = {
Tom Cherryc44f6a42017-04-05 15:58:31 -0700112 .path = "/devices/soc.0/f9824900.sdhci/mmc_host/mmc0/mmc0:0001/block/mmcblk0p1",
113 .partition_name = "modem",
114 .partition_num = -1,
115 };
116 std::vector<std::string> expected_result{
117 "/dev/block/platform/soc.0/f9824900.sdhci/by-name/modem",
118 "/dev/block/platform/soc.0/f9824900.sdhci/mmcblk0p1",
119 };
120
Tom Cherryed506f72017-05-25 15:58:59 -0700121 DeviceHandlerTester device_handler_tester_;
Tom Cherryb4dd8812017-06-23 12:43:48 -0700122 device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
Tom Cherryc44f6a42017-04-05 15:58:31 -0700123}
124
Tom Cherryed506f72017-05-25 15:58:59 -0700125TEST(device_handler, get_block_device_symlinks_success_pci) {
Tom Cherryc44f6a42017-04-05 15:58:31 -0700126 const char* platform_device = "/devices/do/not/match";
Tom Cherryed506f72017-05-25 15:58:59 -0700127 Uevent uevent = {
Tom Cherrye3e48212017-04-11 13:53:37 -0700128 .path = "/devices/pci0000:00/0000:00:1f.2/mmcblk0", .partition_name = "", .partition_num = -1,
Tom Cherryc44f6a42017-04-05 15:58:31 -0700129 };
130 std::vector<std::string> expected_result{"/dev/block/pci/pci0000:00/0000:00:1f.2/mmcblk0"};
131
Tom Cherryed506f72017-05-25 15:58:59 -0700132 DeviceHandlerTester device_handler_tester_;
Tom Cherryb4dd8812017-06-23 12:43:48 -0700133 device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
Tom Cherryc44f6a42017-04-05 15:58:31 -0700134}
135
Tom Cherryed506f72017-05-25 15:58:59 -0700136TEST(device_handler, get_block_device_symlinks_pci_bad_format) {
Tom Cherry2e344f92017-04-04 17:53:45 -0700137 const char* platform_device = "/devices/do/not/match";
Tom Cherryed506f72017-05-25 15:58:59 -0700138 Uevent uevent = {
Tom Cherrye3e48212017-04-11 13:53:37 -0700139 .path = "/devices/pci//mmcblk0", .partition_name = "", .partition_num = -1,
Tom Cherry2e344f92017-04-04 17:53:45 -0700140 };
141 std::vector<std::string> expected_result{};
142
Tom Cherryed506f72017-05-25 15:58:59 -0700143 DeviceHandlerTester device_handler_tester_;
Tom Cherryb4dd8812017-06-23 12:43:48 -0700144 device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
Tom Cherry2e344f92017-04-04 17:53:45 -0700145}
146
Tom Cherryed506f72017-05-25 15:58:59 -0700147TEST(device_handler, get_block_device_symlinks_success_vbd) {
Tom Cherryc44f6a42017-04-05 15:58:31 -0700148 const char* platform_device = "/devices/do/not/match";
Tom Cherryed506f72017-05-25 15:58:59 -0700149 Uevent uevent = {
Tom Cherrye3e48212017-04-11 13:53:37 -0700150 .path = "/devices/vbd-1234/mmcblk0", .partition_name = "", .partition_num = -1,
Tom Cherryc44f6a42017-04-05 15:58:31 -0700151 };
152 std::vector<std::string> expected_result{"/dev/block/vbd/1234/mmcblk0"};
153
Tom Cherryed506f72017-05-25 15:58:59 -0700154 DeviceHandlerTester device_handler_tester_;
Tom Cherryb4dd8812017-06-23 12:43:48 -0700155 device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
Tom Cherryc44f6a42017-04-05 15:58:31 -0700156}
157
Tom Cherryed506f72017-05-25 15:58:59 -0700158TEST(device_handler, get_block_device_symlinks_vbd_bad_format) {
Tom Cherry2e344f92017-04-04 17:53:45 -0700159 const char* platform_device = "/devices/do/not/match";
Tom Cherryed506f72017-05-25 15:58:59 -0700160 Uevent uevent = {
Tom Cherrye3e48212017-04-11 13:53:37 -0700161 .path = "/devices/vbd-/mmcblk0", .partition_name = "", .partition_num = -1,
Tom Cherry2e344f92017-04-04 17:53:45 -0700162 };
163 std::vector<std::string> expected_result{};
164
Tom Cherryed506f72017-05-25 15:58:59 -0700165 DeviceHandlerTester device_handler_tester_;
Tom Cherryb4dd8812017-06-23 12:43:48 -0700166 device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
Tom Cherry2e344f92017-04-04 17:53:45 -0700167}
168
Tom Cherryed506f72017-05-25 15:58:59 -0700169TEST(device_handler, get_block_device_symlinks_no_matches) {
Tom Cherryc44f6a42017-04-05 15:58:31 -0700170 const char* platform_device = "/devices/soc.0/f9824900.sdhci";
Tom Cherryed506f72017-05-25 15:58:59 -0700171 Uevent uevent = {
Tom Cherryc44f6a42017-04-05 15:58:31 -0700172 .path = "/devices/soc.0/not_the_device/mmc_host/mmc0/mmc0:0001/block/mmcblk0p1",
Tom Cherrye3e48212017-04-11 13:53:37 -0700173 .partition_name = "",
Tom Cherryc44f6a42017-04-05 15:58:31 -0700174 .partition_num = -1,
175 };
176 std::vector<std::string> expected_result;
177
Tom Cherryed506f72017-05-25 15:58:59 -0700178 DeviceHandlerTester device_handler_tester_;
Tom Cherryb4dd8812017-06-23 12:43:48 -0700179 device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result);
Tom Cherryc44f6a42017-04-05 15:58:31 -0700180}
181
Tom Cherryed506f72017-05-25 15:58:59 -0700182TEST(device_handler, sanitize_null) {
183 SanitizePartitionName(nullptr);
Tom Cherryc44f6a42017-04-05 15:58:31 -0700184}
185
Tom Cherryed506f72017-05-25 15:58:59 -0700186TEST(device_handler, sanitize_empty) {
Tom Cherryc44f6a42017-04-05 15:58:31 -0700187 std::string empty;
Tom Cherryed506f72017-05-25 15:58:59 -0700188 SanitizePartitionName(&empty);
Tom Cherryc44f6a42017-04-05 15:58:31 -0700189 EXPECT_EQ(0u, empty.size());
190}
191
Tom Cherryed506f72017-05-25 15:58:59 -0700192TEST(device_handler, sanitize_allgood) {
Tom Cherryc44f6a42017-04-05 15:58:31 -0700193 std::string good =
194 "abcdefghijklmnopqrstuvwxyz"
195 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
196 "0123456789"
197 "_-.";
198 std::string good_copy = good;
Tom Cherryed506f72017-05-25 15:58:59 -0700199 SanitizePartitionName(&good);
Tom Cherryc44f6a42017-04-05 15:58:31 -0700200 EXPECT_EQ(good_copy, good);
201}
202
Tom Cherryed506f72017-05-25 15:58:59 -0700203TEST(device_handler, sanitize_somebad) {
Tom Cherryc44f6a42017-04-05 15:58:31 -0700204 std::string string = "abc!@#$%^&*()";
Tom Cherryed506f72017-05-25 15:58:59 -0700205 SanitizePartitionName(&string);
Tom Cherryc44f6a42017-04-05 15:58:31 -0700206 EXPECT_EQ("abc__________", string);
207}
208
Tom Cherryed506f72017-05-25 15:58:59 -0700209TEST(device_handler, sanitize_allbad) {
Tom Cherryc44f6a42017-04-05 15:58:31 -0700210 std::string string = "!@#$%^&*()";
Tom Cherryed506f72017-05-25 15:58:59 -0700211 SanitizePartitionName(&string);
Tom Cherryc44f6a42017-04-05 15:58:31 -0700212 EXPECT_EQ("__________", string);
213}
214
Tom Cherryed506f72017-05-25 15:58:59 -0700215TEST(device_handler, sanitize_onebad) {
Tom Cherryc44f6a42017-04-05 15:58:31 -0700216 std::string string = ")";
Tom Cherryed506f72017-05-25 15:58:59 -0700217 SanitizePartitionName(&string);
Tom Cherryc44f6a42017-04-05 15:58:31 -0700218 EXPECT_EQ("_", string);
219}
Tom Cherrycc054c92017-04-05 17:55:46 -0700220
Tom Cherryed506f72017-05-25 15:58:59 -0700221TEST(device_handler, DevPermissionsMatchNormal) {
Tom Cherrycc054c92017-04-05 17:55:46 -0700222 // Basic from ueventd.rc
223 // /dev/null 0666 root root
224 Permissions permissions("/dev/null", 0666, 0, 0);
225 EXPECT_TRUE(permissions.Match("/dev/null"));
226 EXPECT_FALSE(permissions.Match("/dev/nullsuffix"));
227 EXPECT_FALSE(permissions.Match("/dev/nul"));
228 EXPECT_EQ(0666U, permissions.perm());
229 EXPECT_EQ(0U, permissions.uid());
230 EXPECT_EQ(0U, permissions.gid());
231}
232
Tom Cherryed506f72017-05-25 15:58:59 -0700233TEST(device_handler, DevPermissionsMatchPrefix) {
Tom Cherrycc054c92017-04-05 17:55:46 -0700234 // Prefix from ueventd.rc
235 // /dev/dri/* 0666 root graphics
236 Permissions permissions("/dev/dri/*", 0666, 0, 1000);
237 EXPECT_TRUE(permissions.Match("/dev/dri/some_dri_device"));
238 EXPECT_TRUE(permissions.Match("/dev/dri/some_other_dri_device"));
239 EXPECT_TRUE(permissions.Match("/dev/dri/"));
240 EXPECT_FALSE(permissions.Match("/dev/dr/non_match"));
241 EXPECT_EQ(0666U, permissions.perm());
242 EXPECT_EQ(0U, permissions.uid());
243 EXPECT_EQ(1000U, permissions.gid());
244}
245
Tom Cherryed506f72017-05-25 15:58:59 -0700246TEST(device_handler, DevPermissionsMatchWildcard) {
Tom Cherrycc054c92017-04-05 17:55:46 -0700247 // Wildcard example
248 // /dev/device*name 0666 root graphics
249 Permissions permissions("/dev/device*name", 0666, 0, 1000);
250 EXPECT_TRUE(permissions.Match("/dev/devicename"));
251 EXPECT_TRUE(permissions.Match("/dev/device123name"));
252 EXPECT_TRUE(permissions.Match("/dev/deviceabcname"));
253 EXPECT_FALSE(permissions.Match("/dev/device123name/subdevice"));
254 EXPECT_FALSE(permissions.Match("/dev/deviceame"));
255 EXPECT_EQ(0666U, permissions.perm());
256 EXPECT_EQ(0U, permissions.uid());
257 EXPECT_EQ(1000U, permissions.gid());
258}
259
Tom Cherryed506f72017-05-25 15:58:59 -0700260TEST(device_handler, DevPermissionsMatchWildcardPrefix) {
Tom Cherrycc054c92017-04-05 17:55:46 -0700261 // Wildcard+Prefix example
262 // /dev/device*name* 0666 root graphics
263 Permissions permissions("/dev/device*name*", 0666, 0, 1000);
264 EXPECT_TRUE(permissions.Match("/dev/devicename"));
265 EXPECT_TRUE(permissions.Match("/dev/device123name"));
266 EXPECT_TRUE(permissions.Match("/dev/deviceabcname"));
267 EXPECT_TRUE(permissions.Match("/dev/device123namesomething"));
268 // FNM_PATHNAME doesn't match '/' with *
269 EXPECT_FALSE(permissions.Match("/dev/device123name/something"));
270 EXPECT_FALSE(permissions.Match("/dev/deviceame"));
271 EXPECT_EQ(0666U, permissions.perm());
272 EXPECT_EQ(0U, permissions.uid());
273 EXPECT_EQ(1000U, permissions.gid());
274}
275
Tom Cherryed506f72017-05-25 15:58:59 -0700276TEST(device_handler, SysfsPermissionsMatchWithSubsystemNormal) {
Tom Cherrycc054c92017-04-05 17:55:46 -0700277 // /sys/devices/virtual/input/input* enable 0660 root input
278 SysfsPermissions permissions("/sys/devices/virtual/input/input*", "enable", 0660, 0, 1001);
279 EXPECT_TRUE(permissions.MatchWithSubsystem("/sys/devices/virtual/input/input0", "input"));
280 EXPECT_FALSE(permissions.MatchWithSubsystem("/sys/devices/virtual/input/not_input0", "input"));
281 EXPECT_EQ(0660U, permissions.perm());
282 EXPECT_EQ(0U, permissions.uid());
283 EXPECT_EQ(1001U, permissions.gid());
284}
285
Tom Cherryed506f72017-05-25 15:58:59 -0700286TEST(device_handler, SysfsPermissionsMatchWithSubsystemClass) {
Tom Cherrycc054c92017-04-05 17:55:46 -0700287 // /sys/class/input/event* enable 0660 root input
288 SysfsPermissions permissions("/sys/class/input/event*", "enable", 0660, 0, 1001);
289 EXPECT_TRUE(permissions.MatchWithSubsystem(
290 "/sys/devices/soc.0/f9924000.i2c/i2c-2/2-0020/input/input0/event0", "input"));
291 EXPECT_FALSE(permissions.MatchWithSubsystem(
292 "/sys/devices/soc.0/f9924000.i2c/i2c-2/2-0020/input/input0/not_event0", "input"));
293 EXPECT_FALSE(permissions.MatchWithSubsystem(
294 "/sys/devices/soc.0/f9924000.i2c/i2c-2/2-0020/input/input0/event0", "not_input"));
295 EXPECT_EQ(0660U, permissions.perm());
296 EXPECT_EQ(0U, permissions.uid());
297 EXPECT_EQ(1001U, permissions.gid());
298}
299
Tom Cherryed506f72017-05-25 15:58:59 -0700300TEST(device_handler, SysfsPermissionsMatchWithSubsystemBus) {
Tom Cherrycc054c92017-04-05 17:55:46 -0700301 // /sys/bus/i2c/devices/i2c-* enable 0660 root input
302 SysfsPermissions permissions("/sys/bus/i2c/devices/i2c-*", "enable", 0660, 0, 1001);
303 EXPECT_TRUE(permissions.MatchWithSubsystem("/sys/devices/soc.0/f9967000.i2c/i2c-5", "i2c"));
304 EXPECT_FALSE(permissions.MatchWithSubsystem("/sys/devices/soc.0/f9967000.i2c/not-i2c", "i2c"));
305 EXPECT_FALSE(
306 permissions.MatchWithSubsystem("/sys/devices/soc.0/f9967000.i2c/i2c-5", "not_i2c"));
307 EXPECT_EQ(0660U, permissions.perm());
308 EXPECT_EQ(0U, permissions.uid());
309 EXPECT_EQ(1001U, permissions.gid());
310}
Tom Cherry81f5d3e2017-06-22 12:53:17 -0700311
312} // namespace init
313} // namespace android