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