1 /* 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 19 #include <android-base/scopeguard.h> 20 #include <android-base/test_utils.h> 21 #include <gtest/gtest.h> 22 23 #include "util.h" 24 25 using namespace std::string_literals; 26 27 namespace android { 28 namespace init { 29 30 class DeviceHandlerTester { 31 public: 32 void TestGetSymlinks(const std::string& platform_device, const Uevent& uevent, 33 const std::vector<std::string> expected_links) { 34 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; 38 mkdir_recursive(platform_device_dir, 0777); 39 40 std::string platform_bus = fake_sys_root.path + "/bus/platform"s; 41 mkdir_recursive(platform_bus, 0777); 42 symlink(platform_bus.c_str(), (platform_device_dir + "/subsystem").c_str()); 43 44 mkdir_recursive(android::base::Dirname(fake_sys_root.path + uevent.path), 0777); 45 46 std::vector<std::string> result; 47 result = device_handler_.GetBlockDeviceSymlinks(uevent); 48 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 63 TEST(device_handler, get_block_device_symlinks_success_platform) { 64 // These are actual paths from bullhead 65 const char* platform_device = "/devices/soc.0/f9824900.sdhci"; 66 Uevent uevent = { 67 .path = "/devices/soc.0/f9824900.sdhci/mmc_host/mmc0/mmc0:0001/block/mmcblk0", 68 .partition_name = "", 69 .partition_num = -1, 70 }; 71 std::vector<std::string> expected_result{"/dev/block/platform/soc.0/f9824900.sdhci/mmcblk0"}; 72 73 DeviceHandlerTester device_handler_tester_; 74 device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result); 75 } 76 77 TEST(device_handler, get_block_device_symlinks_success_platform_with_partition) { 78 // These are actual paths from bullhead 79 const char* platform_device = "/devices/soc.0/f9824900.sdhci"; 80 Uevent uevent = { 81 .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/mmcblk0p1", 88 }; 89 90 DeviceHandlerTester device_handler_tester_; 91 device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result); 92 } 93 94 TEST(device_handler, get_block_device_symlinks_success_platform_with_partition_only_num) { 95 const char* platform_device = "/devices/soc.0/f9824900.sdhci"; 96 Uevent uevent = { 97 .path = "/devices/soc.0/f9824900.sdhci/mmc_host/mmc0/mmc0:0001/block/mmcblk0p1", 98 .partition_name = "", 99 .partition_num = 1, 100 }; 101 std::vector<std::string> expected_result{ 102 "/dev/block/platform/soc.0/f9824900.sdhci/mmcblk0p1", 103 }; 104 105 DeviceHandlerTester device_handler_tester_; 106 device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result); 107 } 108 109 TEST(device_handler, get_block_device_symlinks_success_platform_with_partition_only_name) { 110 const char* platform_device = "/devices/soc.0/f9824900.sdhci"; 111 Uevent uevent = { 112 .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 121 DeviceHandlerTester device_handler_tester_; 122 device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result); 123 } 124 125 TEST(device_handler, get_block_device_symlinks_success_pci) { 126 const char* platform_device = "/devices/do/not/match"; 127 Uevent uevent = { 128 .path = "/devices/pci0000:00/0000:00:1f.2/mmcblk0", .partition_name = "", .partition_num = -1, 129 }; 130 std::vector<std::string> expected_result{"/dev/block/pci/pci0000:00/0000:00:1f.2/mmcblk0"}; 131 132 DeviceHandlerTester device_handler_tester_; 133 device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result); 134 } 135 136 TEST(device_handler, get_block_device_symlinks_pci_bad_format) { 137 const char* platform_device = "/devices/do/not/match"; 138 Uevent uevent = { 139 .path = "/devices/pci//mmcblk0", .partition_name = "", .partition_num = -1, 140 }; 141 std::vector<std::string> expected_result{}; 142 143 DeviceHandlerTester device_handler_tester_; 144 device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result); 145 } 146 147 TEST(device_handler, get_block_device_symlinks_success_vbd) { 148 const char* platform_device = "/devices/do/not/match"; 149 Uevent uevent = { 150 .path = "/devices/vbd-1234/mmcblk0", .partition_name = "", .partition_num = -1, 151 }; 152 std::vector<std::string> expected_result{"/dev/block/vbd/1234/mmcblk0"}; 153 154 DeviceHandlerTester device_handler_tester_; 155 device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result); 156 } 157 158 TEST(device_handler, get_block_device_symlinks_vbd_bad_format) { 159 const char* platform_device = "/devices/do/not/match"; 160 Uevent uevent = { 161 .path = "/devices/vbd-/mmcblk0", .partition_name = "", .partition_num = -1, 162 }; 163 std::vector<std::string> expected_result{}; 164 165 DeviceHandlerTester device_handler_tester_; 166 device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result); 167 } 168 169 TEST(device_handler, get_block_device_symlinks_no_matches) { 170 const char* platform_device = "/devices/soc.0/f9824900.sdhci"; 171 Uevent uevent = { 172 .path = "/devices/soc.0/not_the_device/mmc_host/mmc0/mmc0:0001/block/mmcblk0p1", 173 .partition_name = "", 174 .partition_num = -1, 175 }; 176 std::vector<std::string> expected_result; 177 178 DeviceHandlerTester device_handler_tester_; 179 device_handler_tester_.TestGetSymlinks(platform_device, uevent, expected_result); 180 } 181 182 TEST(device_handler, sanitize_null) { 183 SanitizePartitionName(nullptr); 184 } 185 186 TEST(device_handler, sanitize_empty) { 187 std::string empty; 188 SanitizePartitionName(&empty); 189 EXPECT_EQ(0u, empty.size()); 190 } 191 192 TEST(device_handler, sanitize_allgood) { 193 std::string good = 194 "abcdefghijklmnopqrstuvwxyz" 195 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 196 "0123456789" 197 "_-."; 198 std::string good_copy = good; 199 SanitizePartitionName(&good); 200 EXPECT_EQ(good_copy, good); 201 } 202 203 TEST(device_handler, sanitize_somebad) { 204 std::string string = "abc!@#$%^&*()"; 205 SanitizePartitionName(&string); 206 EXPECT_EQ("abc__________", string); 207 } 208 209 TEST(device_handler, sanitize_allbad) { 210 std::string string = "!@#$%^&*()"; 211 SanitizePartitionName(&string); 212 EXPECT_EQ("__________", string); 213 } 214 215 TEST(device_handler, sanitize_onebad) { 216 std::string string = ")"; 217 SanitizePartitionName(&string); 218 EXPECT_EQ("_", string); 219 } 220 221 TEST(device_handler, DevPermissionsMatchNormal) { 222 // 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 233 TEST(device_handler, DevPermissionsMatchPrefix) { 234 // 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 246 TEST(device_handler, DevPermissionsMatchWildcard) { 247 // 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 260 TEST(device_handler, DevPermissionsMatchWildcardPrefix) { 261 // 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 276 TEST(device_handler, SysfsPermissionsMatchWithSubsystemNormal) { 277 // /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 286 TEST(device_handler, SysfsPermissionsMatchWithSubsystemClass) { 287 // /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 300 TEST(device_handler, SysfsPermissionsMatchWithSubsystemBus) { 301 // /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 } 311 312 } // namespace init 313 } // namespace android 314