devices.cpp revision 120add07ab2aa03cb7c073ef7629817b41643dc1
1/* 2 * Copyright (C) 2007-2014 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 <dirent.h> 18#include <errno.h> 19#include <fcntl.h> 20#include <fnmatch.h> 21#include <libgen.h> 22#include <linux/netlink.h> 23#include <stddef.h> 24#include <stdio.h> 25#include <stdlib.h> 26#include <string.h> 27#include <sys/sendfile.h> 28#include <sys/socket.h> 29#include <sys/time.h> 30#include <sys/types.h> 31#include <sys/un.h> 32#include <sys/wait.h> 33#include <unistd.h> 34 35#include <algorithm> 36#include <memory> 37#include <string> 38#include <thread> 39#include <vector> 40 41#include <android-base/file.h> 42#include <android-base/logging.h> 43#include <android-base/stringprintf.h> 44#include <android-base/strings.h> 45#include <android-base/unique_fd.h> 46#include <cutils/list.h> 47#include <cutils/uevent.h> 48#include <private/android_filesystem_config.h> 49#include <selinux/android.h> 50#include <selinux/avc.h> 51#include <selinux/label.h> 52#include <selinux/selinux.h> 53 54#include "devices.h" 55#include "ueventd_parser.h" 56#include "util.h" 57 58#define SYSFS_PREFIX "/sys" 59static const char *firmware_dirs[] = { "/etc/firmware", 60 "/vendor/firmware", 61 "/firmware/image" }; 62 63extern struct selabel_handle *sehandle; 64 65static android::base::unique_fd device_fd; 66 67struct perms_ { 68 char *name; 69 char *attr; 70 mode_t perm; 71 unsigned int uid; 72 unsigned int gid; 73 unsigned short prefix; 74 unsigned short wildcard; 75}; 76 77struct perm_node { 78 struct perms_ dp; 79 struct listnode plist; 80}; 81 82struct platform_node { 83 char *name; 84 char *path; 85 int path_len; 86 struct listnode list; 87}; 88 89static list_declare(sys_perms); 90static list_declare(dev_perms); 91static list_declare(platform_names); 92 93int add_dev_perms(const char *name, const char *attr, 94 mode_t perm, unsigned int uid, unsigned int gid, 95 unsigned short prefix, 96 unsigned short wildcard) { 97 struct perm_node *node = (perm_node*) calloc(1, sizeof(*node)); 98 if (!node) 99 return -ENOMEM; 100 101 node->dp.name = strdup(name); 102 if (!node->dp.name) { 103 free(node); 104 return -ENOMEM; 105 } 106 107 if (attr) { 108 node->dp.attr = strdup(attr); 109 if (!node->dp.attr) { 110 free(node->dp.name); 111 free(node); 112 return -ENOMEM; 113 } 114 } 115 116 node->dp.perm = perm; 117 node->dp.uid = uid; 118 node->dp.gid = gid; 119 node->dp.prefix = prefix; 120 node->dp.wildcard = wildcard; 121 122 if (attr) 123 list_add_tail(&sys_perms, &node->plist); 124 else 125 list_add_tail(&dev_perms, &node->plist); 126 127 return 0; 128} 129 130static bool perm_path_matches(const char *path, struct perms_ *dp) 131{ 132 if (dp->prefix) { 133 if (strncmp(path, dp->name, strlen(dp->name)) == 0) 134 return true; 135 } else if (dp->wildcard) { 136 if (fnmatch(dp->name, path, FNM_PATHNAME) == 0) 137 return true; 138 } else { 139 if (strcmp(path, dp->name) == 0) 140 return true; 141 } 142 143 return false; 144} 145 146static bool match_subsystem(perms_* dp, const char* pattern, 147 const char* path, const char* subsystem) { 148 if (!pattern || !subsystem || strstr(dp->name, subsystem) == NULL) { 149 return false; 150 } 151 152 std::string subsys_path = android::base::StringPrintf(pattern, subsystem, basename(path)); 153 return perm_path_matches(subsys_path.c_str(), dp); 154} 155 156static void fixup_sys_perms(const char* upath, const char* subsystem) { 157 // upaths omit the "/sys" that paths in this list 158 // contain, so we prepend it... 159 std::string path = std::string(SYSFS_PREFIX) + upath; 160 161 listnode* node; 162 list_for_each(node, &sys_perms) { 163 perms_* dp = &(node_to_item(node, perm_node, plist))->dp; 164 if (match_subsystem(dp, SYSFS_PREFIX "/class/%s/%s", path.c_str(), subsystem)) { 165 ; // matched 166 } else if (match_subsystem(dp, SYSFS_PREFIX "/bus/%s/devices/%s", path.c_str(), subsystem)) { 167 ; // matched 168 } else if (!perm_path_matches(path.c_str(), dp)) { 169 continue; 170 } 171 172 std::string attr_file = path + "/" + dp->attr; 173 LOG(INFO) << "fixup " << attr_file 174 << " " << dp->uid << " " << dp->gid << " " << std::oct << dp->perm; 175 chown(attr_file.c_str(), dp->uid, dp->gid); 176 chmod(attr_file.c_str(), dp->perm); 177 } 178 179 if (access(path.c_str(), F_OK) == 0) { 180 LOG(VERBOSE) << "restorecon_recursive: " << path; 181 restorecon(path.c_str(), SELINUX_ANDROID_RESTORECON_RECURSE); 182 } 183} 184 185static mode_t get_device_perm(const char* path, const std::vector<std::string>& links, 186 unsigned* uid, unsigned* gid) { 187 struct listnode *node; 188 struct perm_node *perm_node; 189 struct perms_ *dp; 190 191 /* search the perms list in reverse so that ueventd.$hardware can 192 * override ueventd.rc 193 */ 194 list_for_each_reverse(node, &dev_perms) { 195 perm_node = node_to_item(node, struct perm_node, plist); 196 dp = &perm_node->dp; 197 198 if (perm_path_matches(path, dp) || 199 std::any_of(links.begin(), links.end(), 200 [dp](const auto& link) { return perm_path_matches(link.c_str(), dp); })) { 201 *uid = dp->uid; 202 *gid = dp->gid; 203 return dp->perm; 204 } 205 } 206 /* Default if nothing found. */ 207 *uid = 0; 208 *gid = 0; 209 return 0600; 210} 211 212static void make_device(const char* path, const char* /*upath*/, int block, int major, int minor, 213 const std::vector<std::string>& links) { 214 unsigned uid; 215 unsigned gid; 216 mode_t mode; 217 dev_t dev; 218 char *secontext = NULL; 219 220 mode = get_device_perm(path, links, &uid, &gid) | (block ? S_IFBLK : S_IFCHR); 221 222 if (sehandle) { 223 std::vector<const char*> c_links; 224 for (const auto& link : links) { 225 c_links.emplace_back(link.c_str()); 226 } 227 c_links.emplace_back(nullptr); 228 if (selabel_lookup_best_match(sehandle, &secontext, path, &c_links[0], mode)) { 229 PLOG(ERROR) << "Device '" << path << "' not created; cannot find SELinux label"; 230 return; 231 } 232 setfscreatecon(secontext); 233 } 234 235 dev = makedev(major, minor); 236 /* Temporarily change egid to avoid race condition setting the gid of the 237 * device node. Unforunately changing the euid would prevent creation of 238 * some device nodes, so the uid has to be set with chown() and is still 239 * racy. Fixing the gid race at least fixed the issue with system_server 240 * opening dynamic input devices under the AID_INPUT gid. */ 241 if (setegid(gid)) { 242 PLOG(ERROR) << "setegid(" << gid << ") for " << path << " device failed"; 243 goto out; 244 } 245 /* If the node already exists update its SELinux label to handle cases when 246 * it was created with the wrong context during coldboot procedure. */ 247 if (mknod(path, mode, dev) && (errno == EEXIST) && secontext) { 248 249 char* fcon = nullptr; 250 int rc = lgetfilecon(path, &fcon); 251 if (rc < 0) { 252 PLOG(ERROR) << "Cannot get SELinux label on '" << path << "' device"; 253 goto out; 254 } 255 256 bool different = strcmp(fcon, secontext) != 0; 257 freecon(fcon); 258 259 if (different && lsetfilecon(path, secontext)) { 260 PLOG(ERROR) << "Cannot set '" << secontext << "' SELinux label on '" << path << "' device"; 261 } 262 } 263 264out: 265 chown(path, uid, -1); 266 if (setegid(AID_ROOT)) { 267 PLOG(FATAL) << "setegid(AID_ROOT) failed"; 268 } 269 270 if (secontext) { 271 freecon(secontext); 272 setfscreatecon(NULL); 273 } 274} 275 276void add_platform_device(const char* path) { 277 int path_len = strlen(path); 278 struct platform_node *bus; 279 const char *name = path; 280 281 if (!strncmp(path, "/devices/", 9)) { 282 name += 9; 283 if (!strncmp(name, "platform/", 9)) 284 name += 9; 285 } 286 287 LOG(VERBOSE) << "adding platform device " << name << " (" << path << ")"; 288 289 bus = (platform_node*) calloc(1, sizeof(struct platform_node)); 290 bus->path = strdup(path); 291 bus->path_len = path_len; 292 bus->name = bus->path + (name - path); 293 list_add_tail(&platform_names, &bus->list); 294} 295 296/* 297 * given a path that may start with a platform device, find the length of the 298 * platform device prefix. If it doesn't start with a platform device, return 299 * 0. 300 */ 301static struct platform_node *find_platform_device(const char *path) 302{ 303 int path_len = strlen(path); 304 struct listnode *node; 305 struct platform_node *bus; 306 307 list_for_each_reverse(node, &platform_names) { 308 bus = node_to_item(node, struct platform_node, list); 309 if ((bus->path_len < path_len) && 310 (path[bus->path_len] == '/') && 311 !strncmp(path, bus->path, bus->path_len)) 312 return bus; 313 } 314 315 return NULL; 316} 317 318void remove_platform_device(const char* path) { 319 struct listnode *node; 320 struct platform_node *bus; 321 322 list_for_each_reverse(node, &platform_names) { 323 bus = node_to_item(node, struct platform_node, list); 324 if (!strcmp(path, bus->path)) { 325 LOG(INFO) << "removing platform device " << bus->name; 326 free(bus->path); 327 list_remove(node); 328 free(bus); 329 return; 330 } 331 } 332} 333 334static void destroy_platform_devices() { 335 struct listnode* node; 336 struct listnode* n; 337 struct platform_node* bus; 338 339 list_for_each_safe(node, n, &platform_names) { 340 list_remove(node); 341 bus = node_to_item(node, struct platform_node, list); 342 free(bus->path); 343 free(bus); 344 } 345} 346 347/* Given a path that may start with a PCI device, populate the supplied buffer 348 * with the PCI domain/bus number and the peripheral ID and return 0. 349 * If it doesn't start with a PCI device, or there is some error, return -1 */ 350static bool find_pci_device_prefix(const std::string& path, std::string* result) { 351 result->clear(); 352 353 if (!android::base::StartsWith(path, "/devices/pci")) return false; 354 355 /* Beginning of the prefix is the initial "pci" after "/devices/" */ 356 std::string::size_type start = 9; 357 358 /* End of the prefix is two path '/' later, capturing the domain/bus number 359 * and the peripheral ID. Example: pci0000:00/0000:00:1f.2 */ 360 auto end = path.find('/', start); 361 if (end == std::string::npos) return false; 362 363 end = path.find('/', end + 1); 364 if (end == std::string::npos) return false; 365 366 auto length = end - start; 367 if (length <= 4) { 368 // The minimum string that will get to this check is 'pci/', which is malformed, 369 // so return false 370 return false; 371 } 372 373 *result = path.substr(start, length); 374 return true; 375} 376 377/* Given a path that may start with a virtual block device, populate 378 * the supplied buffer with the virtual block device ID and return 0. 379 * If it doesn't start with a virtual block device, or there is some 380 * error, return -1 */ 381static bool find_vbd_device_prefix(const std::string& path, std::string* result) { 382 result->clear(); 383 384 if (!android::base::StartsWith(path, "/devices/vbd-")) return false; 385 386 /* Beginning of the prefix is the initial "vbd-" after "/devices/" */ 387 std::string::size_type start = 13; 388 389 /* End of the prefix is one path '/' later, capturing the 390 virtual block device ID. Example: 768 */ 391 auto end = path.find('/', start); 392 if (end == std::string::npos) return false; 393 394 auto length = end - start; 395 if (length == 0) return false; 396 397 *result = path.substr(start, length); 398 return true; 399} 400 401static void parse_event(const char *msg, struct uevent *uevent) 402{ 403 uevent->action = ""; 404 uevent->path = ""; 405 uevent->subsystem = ""; 406 uevent->firmware = ""; 407 uevent->major = -1; 408 uevent->minor = -1; 409 uevent->partition_name = NULL; 410 uevent->partition_num = -1; 411 uevent->device_name = NULL; 412 413 /* currently ignoring SEQNUM */ 414 while(*msg) { 415 if(!strncmp(msg, "ACTION=", 7)) { 416 msg += 7; 417 uevent->action = msg; 418 } else if(!strncmp(msg, "DEVPATH=", 8)) { 419 msg += 8; 420 uevent->path = msg; 421 } else if(!strncmp(msg, "SUBSYSTEM=", 10)) { 422 msg += 10; 423 uevent->subsystem = msg; 424 } else if(!strncmp(msg, "FIRMWARE=", 9)) { 425 msg += 9; 426 uevent->firmware = msg; 427 } else if(!strncmp(msg, "MAJOR=", 6)) { 428 msg += 6; 429 uevent->major = atoi(msg); 430 } else if(!strncmp(msg, "MINOR=", 6)) { 431 msg += 6; 432 uevent->minor = atoi(msg); 433 } else if(!strncmp(msg, "PARTN=", 6)) { 434 msg += 6; 435 uevent->partition_num = atoi(msg); 436 } else if(!strncmp(msg, "PARTNAME=", 9)) { 437 msg += 9; 438 uevent->partition_name = msg; 439 } else if(!strncmp(msg, "DEVNAME=", 8)) { 440 msg += 8; 441 uevent->device_name = msg; 442 } 443 444 /* advance to after the next \0 */ 445 while(*msg++) 446 ; 447 } 448 449 if (LOG_UEVENTS) { 450 LOG(INFO) << android::base::StringPrintf("event { '%s', '%s', '%s', '%s', %d, %d }", 451 uevent->action, uevent->path, uevent->subsystem, 452 uevent->firmware, uevent->major, uevent->minor); 453 } 454} 455 456std::vector<std::string> get_character_device_symlinks(uevent* uevent) { 457 platform_node* pdev = find_platform_device(uevent->path); 458 if (!pdev) return {}; 459 460 /* skip "/devices/platform/<driver>" */ 461 std::string parent = std::string(uevent->path); 462 auto parent_start = parent.find('/', pdev->path_len); 463 if (parent_start == std::string::npos) return {}; 464 465 parent.erase(0, parent_start); 466 467 if (!android::base::StartsWith(parent, "/usb")) return {}; 468 469 // skip root hub name and device. use device interface 470 // skip 3 slashes, including the first / by starting the search at the 1st character, not 0th. 471 // then extract what comes between the 3rd and 4th slash 472 // e.g. "/usb/usb_device/name/tty2-1:1.0" -> "name" 473 474 std::string::size_type start = 0; 475 start = parent.find('/', start + 1); 476 if (start == std::string::npos) return {}; 477 478 start = parent.find('/', start + 1); 479 if (start == std::string::npos) return {}; 480 481 auto end = parent.find('/', start + 1); 482 if (end == std::string::npos) return {}; 483 484 start++; // Skip the first '/' 485 486 auto length = end - start; 487 if (length == 0) return {}; 488 489 auto name_string = parent.substr(start, length); 490 491 // TODO: remove std::string() when uevent->subsystem is an std::string 492 std::vector<std::string> links; 493 links.emplace_back("/dev/usb/" + std::string(uevent->subsystem) + name_string); 494 495 mkdir("/dev/usb", 0755); 496 497 return links; 498} 499 500// replaces any unacceptable characters with '_', the 501// length of the resulting string is equal to the input string 502void sanitize_partition_name(std::string* string) { 503 const char* accept = 504 "abcdefghijklmnopqrstuvwxyz" 505 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 506 "0123456789" 507 "_-."; 508 509 if (!string) return; 510 511 std::string::size_type pos = 0; 512 while ((pos = string->find_first_not_of(accept, pos)) != std::string::npos) { 513 (*string)[pos] = '_'; 514 } 515} 516 517std::vector<std::string> get_block_device_symlinks(uevent* uevent) { 518 std::string device; 519 struct platform_node* pdev; 520 std::string type; 521 522 pdev = find_platform_device(uevent->path); 523 if (pdev) { 524 device = pdev->name; 525 type = "platform"; 526 } else if (find_pci_device_prefix(uevent->path, &device)) { 527 type = "pci"; 528 } else if (find_vbd_device_prefix(uevent->path, &device)) { 529 type = "vbd"; 530 } else { 531 return {}; 532 } 533 534 std::vector<std::string> links; 535 536 LOG(VERBOSE) << "found " << type << " device " << device; 537 538 auto link_path = "/dev/block/" + type + "/" + device; 539 540 if (uevent->partition_name) { 541 std::string partition_name_sanitized(uevent->partition_name); 542 sanitize_partition_name(&partition_name_sanitized); 543 if (partition_name_sanitized != uevent->partition_name) { 544 LOG(VERBOSE) << "Linking partition '" << uevent->partition_name << "' as '" 545 << partition_name_sanitized << "'"; 546 } 547 links.emplace_back(link_path + "/by-name/" + partition_name_sanitized); 548 } 549 550 if (uevent->partition_num >= 0) { 551 links.emplace_back(link_path + "/by-num/p" + std::to_string(uevent->partition_num)); 552 } 553 554 // TODO: remove uevent_path when uevent->path is an std::string 555 std::string uevent_path = uevent->path; 556 auto last_slash = uevent_path.rfind('/'); 557 links.emplace_back(link_path + "/" + uevent_path.substr(last_slash + 1)); 558 559 return links; 560} 561 562static void make_link_init(const char* oldpath, const char* newpath) { 563 const char* slash = strrchr(newpath, '/'); 564 if (!slash) return; 565 566 if (mkdir_recursive(dirname(newpath), 0755)) { 567 PLOG(ERROR) << "Failed to create directory " << dirname(newpath); 568 } 569 570 if (symlink(oldpath, newpath) && errno != EEXIST) { 571 PLOG(ERROR) << "Failed to symlink " << oldpath << " to " << newpath; 572 } 573} 574 575static void remove_link(const char* oldpath, const char* newpath) { 576 std::string path; 577 if (android::base::Readlink(newpath, &path) && path == oldpath) unlink(newpath); 578} 579 580static void handle_device(const char* action, const char* devpath, const char* path, int block, 581 int major, int minor, const std::vector<std::string>& links) { 582 if(!strcmp(action, "add")) { 583 make_device(devpath, path, block, major, minor, links); 584 for (const auto& link : links) { 585 make_link_init(devpath, link.c_str()); 586 } 587 } 588 589 if(!strcmp(action, "remove")) { 590 for (const auto& link : links) { 591 remove_link(devpath, link.c_str()); 592 } 593 unlink(devpath); 594 } 595} 596 597static void handle_platform_device_event(struct uevent *uevent) 598{ 599 const char *path = uevent->path; 600 601 if (!strcmp(uevent->action, "add")) 602 add_platform_device(path); 603 else if (!strcmp(uevent->action, "remove")) 604 remove_platform_device(path); 605} 606 607static const char *parse_device_name(struct uevent *uevent, unsigned int len) 608{ 609 const char *name; 610 611 /* if it's not a /dev device, nothing else to do */ 612 if((uevent->major < 0) || (uevent->minor < 0)) 613 return NULL; 614 615 /* do we have a name? */ 616 name = strrchr(uevent->path, '/'); 617 if(!name) 618 return NULL; 619 name++; 620 621 /* too-long names would overrun our buffer */ 622 if(strlen(name) > len) { 623 LOG(ERROR) << "DEVPATH=" << name << " exceeds " << len << "-character limit on filename; ignoring event"; 624 return NULL; 625 } 626 627 return name; 628} 629 630#define DEVPATH_LEN 96 631#define MAX_DEV_NAME 64 632 633static void handle_block_device_event(struct uevent *uevent) 634{ 635 const char *base = "/dev/block/"; 636 const char *name; 637 char devpath[DEVPATH_LEN]; 638 639 name = parse_device_name(uevent, MAX_DEV_NAME); 640 if (!name) 641 return; 642 643 snprintf(devpath, sizeof(devpath), "%s%s", base, name); 644 make_dir(base, 0755); 645 646 std::vector<std::string> links; 647 if (!strncmp(uevent->path, "/devices/", 9)) 648 links = get_block_device_symlinks(uevent); 649 650 handle_device(uevent->action, devpath, uevent->path, 1, 651 uevent->major, uevent->minor, links); 652} 653 654static bool assemble_devpath(char *devpath, const char *dirname, 655 const char *devname) 656{ 657 int s = snprintf(devpath, DEVPATH_LEN, "%s/%s", dirname, devname); 658 if (s < 0) { 659 PLOG(ERROR) << "failed to assemble device path; ignoring event"; 660 return false; 661 } else if (s >= DEVPATH_LEN) { 662 LOG(ERROR) << dirname << "/" << devname 663 << " exceeds " << DEVPATH_LEN << "-character limit on path; ignoring event"; 664 return false; 665 } 666 return true; 667} 668 669static void mkdir_recursive_for_devpath(const char *devpath) 670{ 671 char dir[DEVPATH_LEN]; 672 char *slash; 673 674 strcpy(dir, devpath); 675 slash = strrchr(dir, '/'); 676 *slash = '\0'; 677 mkdir_recursive(dir, 0755); 678} 679 680static void handle_generic_device_event(struct uevent *uevent) 681{ 682 const char *base; 683 const char *name; 684 char devpath[DEVPATH_LEN] = {0}; 685 686 name = parse_device_name(uevent, MAX_DEV_NAME); 687 if (!name) 688 return; 689 690 struct ueventd_subsystem *subsystem = 691 ueventd_subsystem_find_by_name(uevent->subsystem); 692 693 if (subsystem) { 694 const char *devname; 695 696 switch (subsystem->devname_src) { 697 case DEVNAME_UEVENT_DEVNAME: 698 devname = uevent->device_name; 699 break; 700 701 case DEVNAME_UEVENT_DEVPATH: 702 devname = name; 703 break; 704 705 default: 706 LOG(ERROR) << uevent->subsystem << " subsystem's devpath option is not set; ignoring event"; 707 return; 708 } 709 710 if (!assemble_devpath(devpath, subsystem->dirname, devname)) 711 return; 712 mkdir_recursive_for_devpath(devpath); 713 } else if (!strncmp(uevent->subsystem, "usb", 3)) { 714 if (!strcmp(uevent->subsystem, "usb")) { 715 if (uevent->device_name) { 716 if (!assemble_devpath(devpath, "/dev", uevent->device_name)) 717 return; 718 mkdir_recursive_for_devpath(devpath); 719 } 720 else { 721 /* This imitates the file system that would be created 722 * if we were using devfs instead. 723 * Minors are broken up into groups of 128, starting at "001" 724 */ 725 int bus_id = uevent->minor / 128 + 1; 726 int device_id = uevent->minor % 128 + 1; 727 /* build directories */ 728 make_dir("/dev/bus", 0755); 729 make_dir("/dev/bus/usb", 0755); 730 snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d", bus_id); 731 make_dir(devpath, 0755); 732 snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d/%03d", bus_id, device_id); 733 } 734 } else { 735 /* ignore other USB events */ 736 return; 737 } 738 } else if (!strncmp(uevent->subsystem, "graphics", 8)) { 739 base = "/dev/graphics/"; 740 make_dir(base, 0755); 741 } else if (!strncmp(uevent->subsystem, "drm", 3)) { 742 base = "/dev/dri/"; 743 make_dir(base, 0755); 744 } else if (!strncmp(uevent->subsystem, "oncrpc", 6)) { 745 base = "/dev/oncrpc/"; 746 make_dir(base, 0755); 747 } else if (!strncmp(uevent->subsystem, "adsp", 4)) { 748 base = "/dev/adsp/"; 749 make_dir(base, 0755); 750 } else if (!strncmp(uevent->subsystem, "msm_camera", 10)) { 751 base = "/dev/msm_camera/"; 752 make_dir(base, 0755); 753 } else if(!strncmp(uevent->subsystem, "input", 5)) { 754 base = "/dev/input/"; 755 make_dir(base, 0755); 756 } else if(!strncmp(uevent->subsystem, "mtd", 3)) { 757 base = "/dev/mtd/"; 758 make_dir(base, 0755); 759 } else if(!strncmp(uevent->subsystem, "sound", 5)) { 760 base = "/dev/snd/"; 761 make_dir(base, 0755); 762 } else 763 base = "/dev/"; 764 auto links = get_character_device_symlinks(uevent); 765 766 if (!devpath[0]) 767 snprintf(devpath, sizeof(devpath), "%s%s", base, name); 768 769 handle_device(uevent->action, devpath, uevent->path, 0, 770 uevent->major, uevent->minor, links); 771} 772 773static void handle_device_event(struct uevent *uevent) 774{ 775 if (!strcmp(uevent->action,"add") || !strcmp(uevent->action, "change") || !strcmp(uevent->action, "online")) 776 fixup_sys_perms(uevent->path, uevent->subsystem); 777 778 if (!strncmp(uevent->subsystem, "block", 5)) { 779 handle_block_device_event(uevent); 780 } else if (!strncmp(uevent->subsystem, "platform", 8)) { 781 handle_platform_device_event(uevent); 782 } else { 783 handle_generic_device_event(uevent); 784 } 785} 786 787static void load_firmware(uevent* uevent, const std::string& root, 788 int fw_fd, size_t fw_size, 789 int loading_fd, int data_fd) { 790 // Start transfer. 791 android::base::WriteFully(loading_fd, "1", 1); 792 793 // Copy the firmware. 794 int rc = sendfile(data_fd, fw_fd, nullptr, fw_size); 795 if (rc == -1) { 796 PLOG(ERROR) << "firmware: sendfile failed { '" << root << "', '" << uevent->firmware << "' }"; 797 } 798 799 // Tell the firmware whether to abort or commit. 800 const char* response = (rc != -1) ? "0" : "-1"; 801 android::base::WriteFully(loading_fd, response, strlen(response)); 802} 803 804static int is_booting() { 805 return access("/dev/.booting", F_OK) == 0; 806} 807 808static void process_firmware_event(uevent* uevent) { 809 int booting = is_booting(); 810 811 LOG(INFO) << "firmware: loading '" << uevent->firmware << "' for '" << uevent->path << "'"; 812 813 std::string root = android::base::StringPrintf("/sys%s", uevent->path); 814 std::string loading = root + "/loading"; 815 std::string data = root + "/data"; 816 817 android::base::unique_fd loading_fd(open(loading.c_str(), O_WRONLY|O_CLOEXEC)); 818 if (loading_fd == -1) { 819 PLOG(ERROR) << "couldn't open firmware loading fd for " << uevent->firmware; 820 return; 821 } 822 823 android::base::unique_fd data_fd(open(data.c_str(), O_WRONLY|O_CLOEXEC)); 824 if (data_fd == -1) { 825 PLOG(ERROR) << "couldn't open firmware data fd for " << uevent->firmware; 826 return; 827 } 828 829try_loading_again: 830 for (size_t i = 0; i < arraysize(firmware_dirs); i++) { 831 std::string file = android::base::StringPrintf("%s/%s", firmware_dirs[i], uevent->firmware); 832 android::base::unique_fd fw_fd(open(file.c_str(), O_RDONLY|O_CLOEXEC)); 833 struct stat sb; 834 if (fw_fd != -1 && fstat(fw_fd, &sb) != -1) { 835 load_firmware(uevent, root, fw_fd, sb.st_size, loading_fd, data_fd); 836 return; 837 } 838 } 839 840 if (booting) { 841 // If we're not fully booted, we may be missing 842 // filesystems needed for firmware, wait and retry. 843 std::this_thread::sleep_for(100ms); 844 booting = is_booting(); 845 goto try_loading_again; 846 } 847 848 LOG(ERROR) << "firmware: could not find firmware for " << uevent->firmware; 849 850 // Write "-1" as our response to the kernel's firmware request, since we have nothing for it. 851 write(loading_fd, "-1", 2); 852} 853 854static void handle_firmware_event(uevent* uevent) { 855 if (strcmp(uevent->subsystem, "firmware")) return; 856 if (strcmp(uevent->action, "add")) return; 857 858 // Loading the firmware in a child means we can do that in parallel... 859 // (We ignore SIGCHLD rather than wait for our children.) 860 pid_t pid = fork(); 861 if (pid == 0) { 862 Timer t; 863 process_firmware_event(uevent); 864 LOG(INFO) << "loading " << uevent->path << " took " << t; 865 _exit(EXIT_SUCCESS); 866 } else if (pid == -1) { 867 PLOG(ERROR) << "could not fork to process firmware event for " << uevent->firmware; 868 } 869} 870 871static bool inline should_stop_coldboot(coldboot_action_t act) 872{ 873 return (act == COLDBOOT_STOP || act == COLDBOOT_FINISH); 874} 875 876#define UEVENT_MSG_LEN 2048 877 878static inline coldboot_action_t handle_device_fd_with( 879 std::function<coldboot_action_t(uevent* uevent)> handle_uevent) 880{ 881 char msg[UEVENT_MSG_LEN+2]; 882 int n; 883 while ((n = uevent_kernel_multicast_recv(device_fd, msg, UEVENT_MSG_LEN)) > 0) { 884 if(n >= UEVENT_MSG_LEN) /* overflow -- discard */ 885 continue; 886 887 msg[n] = '\0'; 888 msg[n+1] = '\0'; 889 890 struct uevent uevent; 891 parse_event(msg, &uevent); 892 coldboot_action_t act = handle_uevent(&uevent); 893 if (should_stop_coldboot(act)) 894 return act; 895 } 896 897 return COLDBOOT_CONTINUE; 898} 899 900coldboot_action_t handle_device_fd(coldboot_callback fn) 901{ 902 coldboot_action_t ret = handle_device_fd_with( 903 [&](uevent* uevent) -> coldboot_action_t { 904 if (selinux_status_updated() > 0) { 905 struct selabel_handle *sehandle2; 906 sehandle2 = selinux_android_file_context_handle(); 907 if (sehandle2) { 908 selabel_close(sehandle); 909 sehandle = sehandle2; 910 } 911 } 912 913 // default is to always create the devices 914 coldboot_action_t act = COLDBOOT_CREATE; 915 if (fn) { 916 act = fn(uevent); 917 } 918 919 if (act == COLDBOOT_CREATE || act == COLDBOOT_STOP) { 920 handle_device_event(uevent); 921 handle_firmware_event(uevent); 922 } 923 924 return act; 925 }); 926 927 return ret; 928} 929 930/* Coldboot walks parts of the /sys tree and pokes the uevent files 931** to cause the kernel to regenerate device add events that happened 932** before init's device manager was started 933** 934** We drain any pending events from the netlink socket every time 935** we poke another uevent file to make sure we don't overrun the 936** socket's buffer. 937*/ 938 939static coldboot_action_t do_coldboot(DIR *d, coldboot_callback fn) 940{ 941 struct dirent *de; 942 int dfd, fd; 943 coldboot_action_t act = COLDBOOT_CONTINUE; 944 945 dfd = dirfd(d); 946 947 fd = openat(dfd, "uevent", O_WRONLY); 948 if (fd >= 0) { 949 write(fd, "add\n", 4); 950 close(fd); 951 act = handle_device_fd(fn); 952 if (should_stop_coldboot(act)) 953 return act; 954 } 955 956 while (!should_stop_coldboot(act) && (de = readdir(d))) { 957 DIR *d2; 958 959 if(de->d_type != DT_DIR || de->d_name[0] == '.') 960 continue; 961 962 fd = openat(dfd, de->d_name, O_RDONLY | O_DIRECTORY); 963 if(fd < 0) 964 continue; 965 966 d2 = fdopendir(fd); 967 if(d2 == 0) 968 close(fd); 969 else { 970 act = do_coldboot(d2, fn); 971 closedir(d2); 972 } 973 } 974 975 // default is always to continue looking for uevents 976 return act; 977} 978 979static coldboot_action_t coldboot(const char *path, coldboot_callback fn) 980{ 981 std::unique_ptr<DIR, decltype(&closedir)> d(opendir(path), closedir); 982 if (d) { 983 return do_coldboot(d.get(), fn); 984 } 985 986 return COLDBOOT_CONTINUE; 987} 988 989void device_init(const char* path, coldboot_callback fn) { 990 if (!sehandle) { 991 sehandle = selinux_android_file_context_handle(); 992 } 993 // open uevent socket and selinux status only if it hasn't been 994 // done before 995 if (device_fd == -1) { 996 /* is 256K enough? udev uses 16MB! */ 997 device_fd.reset(uevent_open_socket(256 * 1024, true)); 998 if (device_fd == -1) { 999 return; 1000 } 1001 fcntl(device_fd, F_SETFL, O_NONBLOCK); 1002 selinux_status_open(true); 1003 } 1004 1005 if (access(COLDBOOT_DONE, F_OK) == 0) { 1006 LOG(VERBOSE) << "Skipping coldboot, already done!"; 1007 return; 1008 } 1009 1010 Timer t; 1011 coldboot_action_t act; 1012 if (!path) { 1013 act = coldboot("/sys/class", fn); 1014 if (!should_stop_coldboot(act)) { 1015 act = coldboot("/sys/block", fn); 1016 if (!should_stop_coldboot(act)) { 1017 act = coldboot("/sys/devices", fn); 1018 } 1019 } 1020 } else { 1021 act = coldboot(path, fn); 1022 } 1023 1024 // If we have a callback, then do as it says. If no, then the default is 1025 // to always create COLDBOOT_DONE file. 1026 if (!fn || (act == COLDBOOT_FINISH)) { 1027 close(open(COLDBOOT_DONE, O_WRONLY|O_CREAT|O_CLOEXEC, 0000)); 1028 } 1029 1030 LOG(INFO) << "Coldboot took " << t; 1031} 1032 1033void device_close() { 1034 destroy_platform_devices(); 1035 device_fd.reset(); 1036 selinux_status_close(); 1037} 1038 1039int get_device_fd() { 1040 return device_fd; 1041} 1042