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