1 /* 2 * Copyright (C) 2008 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 <sys/types.h> 18 #include <sys/stat.h> 19 #include <fcntl.h> 20 #include <unistd.h> 21 #include <string.h> 22 #include <stdio.h> 23 #include <linux/kd.h> 24 #include <errno.h> 25 #include <sys/socket.h> 26 #include <netinet/in.h> 27 #include <linux/if.h> 28 #include <arpa/inet.h> 29 #include <stdlib.h> 30 #include <sys/mount.h> 31 #include <sys/resource.h> 32 #include <sys/wait.h> 33 #include <linux/loop.h> 34 #include <cutils/partition_utils.h> 35 #include <sys/system_properties.h> 36 #include <fs_mgr.h> 37 38 #ifdef HAVE_SELINUX 39 #include <selinux/selinux.h> 40 #include <selinux/label.h> 41 #endif 42 43 #include "init.h" 44 #include "keywords.h" 45 #include "property_service.h" 46 #include "devices.h" 47 #include "init_parser.h" 48 #include "util.h" 49 #include "log.h" 50 51 #include <private/android_filesystem_config.h> 52 53 void add_environment(const char *name, const char *value); 54 55 extern int init_module(void *, unsigned long, const char *); 56 57 static int write_file(const char *path, const char *value) 58 { 59 int fd, ret, len; 60 61 fd = open(path, O_WRONLY|O_CREAT, 0622); 62 63 if (fd < 0) 64 return -errno; 65 66 len = strlen(value); 67 68 do { 69 ret = write(fd, value, len); 70 } while (ret < 0 && errno == EINTR); 71 72 close(fd); 73 if (ret < 0) { 74 return -errno; 75 } else { 76 return 0; 77 } 78 } 79 80 static int _open(const char *path) 81 { 82 int fd; 83 84 fd = open(path, O_RDONLY | O_NOFOLLOW); 85 if (fd < 0) 86 fd = open(path, O_WRONLY | O_NOFOLLOW); 87 88 return fd; 89 } 90 91 static int _chown(const char *path, unsigned int uid, unsigned int gid) 92 { 93 int fd; 94 int ret; 95 96 fd = _open(path); 97 if (fd < 0) { 98 return -1; 99 } 100 101 ret = fchown(fd, uid, gid); 102 if (ret < 0) { 103 int errno_copy = errno; 104 close(fd); 105 errno = errno_copy; 106 return -1; 107 } 108 109 close(fd); 110 111 return 0; 112 } 113 114 static int _chmod(const char *path, mode_t mode) 115 { 116 int fd; 117 int ret; 118 119 fd = _open(path); 120 if (fd < 0) { 121 return -1; 122 } 123 124 ret = fchmod(fd, mode); 125 if (ret < 0) { 126 int errno_copy = errno; 127 close(fd); 128 errno = errno_copy; 129 return -1; 130 } 131 132 close(fd); 133 134 return 0; 135 } 136 137 static int insmod(const char *filename, char *options) 138 { 139 void *module; 140 unsigned size; 141 int ret; 142 143 module = read_file(filename, &size); 144 if (!module) 145 return -1; 146 147 ret = init_module(module, size, options); 148 149 free(module); 150 151 return ret; 152 } 153 154 static int setkey(struct kbentry *kbe) 155 { 156 int fd, ret; 157 158 fd = open("/dev/tty0", O_RDWR | O_SYNC); 159 if (fd < 0) 160 return -1; 161 162 ret = ioctl(fd, KDSKBENT, kbe); 163 164 close(fd); 165 return ret; 166 } 167 168 static int __ifupdown(const char *interface, int up) 169 { 170 struct ifreq ifr; 171 int s, ret; 172 173 strlcpy(ifr.ifr_name, interface, IFNAMSIZ); 174 175 s = socket(AF_INET, SOCK_DGRAM, 0); 176 if (s < 0) 177 return -1; 178 179 ret = ioctl(s, SIOCGIFFLAGS, &ifr); 180 if (ret < 0) { 181 goto done; 182 } 183 184 if (up) 185 ifr.ifr_flags |= IFF_UP; 186 else 187 ifr.ifr_flags &= ~IFF_UP; 188 189 ret = ioctl(s, SIOCSIFFLAGS, &ifr); 190 191 done: 192 close(s); 193 return ret; 194 } 195 196 static void service_start_if_not_disabled(struct service *svc) 197 { 198 if (!(svc->flags & SVC_DISABLED)) { 199 service_start(svc, NULL); 200 } 201 } 202 203 int do_chdir(int nargs, char **args) 204 { 205 chdir(args[1]); 206 return 0; 207 } 208 209 int do_chroot(int nargs, char **args) 210 { 211 chroot(args[1]); 212 return 0; 213 } 214 215 int do_class_start(int nargs, char **args) 216 { 217 /* Starting a class does not start services 218 * which are explicitly disabled. They must 219 * be started individually. 220 */ 221 service_for_each_class(args[1], service_start_if_not_disabled); 222 return 0; 223 } 224 225 int do_class_stop(int nargs, char **args) 226 { 227 service_for_each_class(args[1], service_stop); 228 return 0; 229 } 230 231 int do_class_reset(int nargs, char **args) 232 { 233 service_for_each_class(args[1], service_reset); 234 return 0; 235 } 236 237 int do_domainname(int nargs, char **args) 238 { 239 return write_file("/proc/sys/kernel/domainname", args[1]); 240 } 241 242 int do_exec(int nargs, char **args) 243 { 244 return -1; 245 } 246 247 int do_export(int nargs, char **args) 248 { 249 add_environment(args[1], args[2]); 250 return 0; 251 } 252 253 int do_hostname(int nargs, char **args) 254 { 255 return write_file("/proc/sys/kernel/hostname", args[1]); 256 } 257 258 int do_ifup(int nargs, char **args) 259 { 260 return __ifupdown(args[1], 1); 261 } 262 263 264 static int do_insmod_inner(int nargs, char **args, int opt_len) 265 { 266 char options[opt_len + 1]; 267 int i; 268 269 options[0] = '\0'; 270 if (nargs > 2) { 271 strcpy(options, args[2]); 272 for (i = 3; i < nargs; ++i) { 273 strcat(options, " "); 274 strcat(options, args[i]); 275 } 276 } 277 278 return insmod(args[1], options); 279 } 280 281 int do_insmod(int nargs, char **args) 282 { 283 int i; 284 int size = 0; 285 286 if (nargs > 2) { 287 for (i = 2; i < nargs; ++i) 288 size += strlen(args[i]) + 1; 289 } 290 291 return do_insmod_inner(nargs, args, size); 292 } 293 294 int do_mkdir(int nargs, char **args) 295 { 296 mode_t mode = 0755; 297 int ret; 298 299 /* mkdir <path> [mode] [owner] [group] */ 300 301 if (nargs >= 3) { 302 mode = strtoul(args[2], 0, 8); 303 } 304 305 ret = mkdir(args[1], mode); 306 /* chmod in case the directory already exists */ 307 if (ret == -1 && errno == EEXIST) { 308 ret = _chmod(args[1], mode); 309 } 310 if (ret == -1) { 311 return -errno; 312 } 313 314 if (nargs >= 4) { 315 uid_t uid = decode_uid(args[3]); 316 gid_t gid = -1; 317 318 if (nargs == 5) { 319 gid = decode_uid(args[4]); 320 } 321 322 if (_chown(args[1], uid, gid) < 0) { 323 return -errno; 324 } 325 } 326 327 return 0; 328 } 329 330 static struct { 331 const char *name; 332 unsigned flag; 333 } mount_flags[] = { 334 { "noatime", MS_NOATIME }, 335 { "nosuid", MS_NOSUID }, 336 { "nodev", MS_NODEV }, 337 { "nodiratime", MS_NODIRATIME }, 338 { "ro", MS_RDONLY }, 339 { "rw", 0 }, 340 { "remount", MS_REMOUNT }, 341 { "defaults", 0 }, 342 { 0, 0 }, 343 }; 344 345 #define DATA_MNT_POINT "/data" 346 347 /* mount <type> <device> <path> <flags ...> <options> */ 348 int do_mount(int nargs, char **args) 349 { 350 char tmp[64]; 351 char *source, *target, *system; 352 char *options = NULL; 353 unsigned flags = 0; 354 int n, i; 355 int wait = 0; 356 357 for (n = 4; n < nargs; n++) { 358 for (i = 0; mount_flags[i].name; i++) { 359 if (!strcmp(args[n], mount_flags[i].name)) { 360 flags |= mount_flags[i].flag; 361 break; 362 } 363 } 364 365 if (!mount_flags[i].name) { 366 if (!strcmp(args[n], "wait")) 367 wait = 1; 368 /* if our last argument isn't a flag, wolf it up as an option string */ 369 else if (n + 1 == nargs) 370 options = args[n]; 371 } 372 } 373 374 system = args[1]; 375 source = args[2]; 376 target = args[3]; 377 378 if (!strncmp(source, "mtd@", 4)) { 379 n = mtd_name_to_number(source + 4); 380 if (n < 0) { 381 return -1; 382 } 383 384 sprintf(tmp, "/dev/block/mtdblock%d", n); 385 386 if (wait) 387 wait_for_file(tmp, COMMAND_RETRY_TIMEOUT); 388 if (mount(tmp, target, system, flags, options) < 0) { 389 return -1; 390 } 391 392 goto exit_success; 393 } else if (!strncmp(source, "loop@", 5)) { 394 int mode, loop, fd; 395 struct loop_info info; 396 397 mode = (flags & MS_RDONLY) ? O_RDONLY : O_RDWR; 398 fd = open(source + 5, mode); 399 if (fd < 0) { 400 return -1; 401 } 402 403 for (n = 0; ; n++) { 404 sprintf(tmp, "/dev/block/loop%d", n); 405 loop = open(tmp, mode); 406 if (loop < 0) { 407 return -1; 408 } 409 410 /* if it is a blank loop device */ 411 if (ioctl(loop, LOOP_GET_STATUS, &info) < 0 && errno == ENXIO) { 412 /* if it becomes our loop device */ 413 if (ioctl(loop, LOOP_SET_FD, fd) >= 0) { 414 close(fd); 415 416 if (mount(tmp, target, system, flags, options) < 0) { 417 ioctl(loop, LOOP_CLR_FD, 0); 418 close(loop); 419 return -1; 420 } 421 422 close(loop); 423 goto exit_success; 424 } 425 } 426 427 close(loop); 428 } 429 430 close(fd); 431 ERROR("out of loopback devices"); 432 return -1; 433 } else { 434 if (wait) 435 wait_for_file(source, COMMAND_RETRY_TIMEOUT); 436 if (mount(source, target, system, flags, options) < 0) { 437 return -1; 438 } 439 440 } 441 442 exit_success: 443 return 0; 444 445 } 446 447 int do_mount_all(int nargs, char **args) 448 { 449 pid_t pid; 450 int ret = -1; 451 int child_ret = -1; 452 int status; 453 const char *prop; 454 455 if (nargs != 2) { 456 return -1; 457 } 458 459 /* 460 * Call fs_mgr_mount_all() to mount all filesystems. We fork(2) and 461 * do the call in the child to provide protection to the main init 462 * process if anything goes wrong (crash or memory leak), and wait for 463 * the child to finish in the parent. 464 */ 465 pid = fork(); 466 if (pid > 0) { 467 /* Parent. Wait for the child to return */ 468 waitpid(pid, &status, 0); 469 if (WIFEXITED(status)) { 470 ret = WEXITSTATUS(status); 471 } else { 472 ret = -1; 473 } 474 } else if (pid == 0) { 475 /* child, call fs_mgr_mount_all() */ 476 klog_set_level(6); /* So we can see what fs_mgr_mount_all() does */ 477 child_ret = fs_mgr_mount_all(args[1]); 478 if (child_ret == -1) { 479 ERROR("fs_mgr_mount_all returned an error\n"); 480 } 481 exit(child_ret); 482 } else { 483 /* fork failed, return an error */ 484 return -1; 485 } 486 487 /* ret is 1 if the device is encrypted, 0 if not, and -1 on error */ 488 if (ret == 1) { 489 property_set("ro.crypto.state", "encrypted"); 490 property_set("vold.decrypt", "1"); 491 } else if (ret == 0) { 492 property_set("ro.crypto.state", "unencrypted"); 493 /* If fs_mgr determined this is an unencrypted device, then trigger 494 * that action. 495 */ 496 action_for_each_trigger("nonencrypted", action_add_queue_tail); 497 } 498 499 return ret; 500 } 501 502 int do_setcon(int nargs, char **args) { 503 #ifdef HAVE_SELINUX 504 if (is_selinux_enabled() <= 0) 505 return 0; 506 if (setcon(args[1]) < 0) { 507 return -errno; 508 } 509 #endif 510 return 0; 511 } 512 513 int do_setenforce(int nargs, char **args) { 514 #ifdef HAVE_SELINUX 515 if (is_selinux_enabled() <= 0) 516 return 0; 517 if (security_setenforce(atoi(args[1])) < 0) { 518 return -errno; 519 } 520 #endif 521 return 0; 522 } 523 524 int do_setkey(int nargs, char **args) 525 { 526 struct kbentry kbe; 527 kbe.kb_table = strtoul(args[1], 0, 0); 528 kbe.kb_index = strtoul(args[2], 0, 0); 529 kbe.kb_value = strtoul(args[3], 0, 0); 530 return setkey(&kbe); 531 } 532 533 int do_setprop(int nargs, char **args) 534 { 535 const char *name = args[1]; 536 const char *value = args[2]; 537 char prop_val[PROP_VALUE_MAX]; 538 int ret; 539 540 ret = expand_props(prop_val, value, sizeof(prop_val)); 541 if (ret) { 542 ERROR("cannot expand '%s' while assigning to '%s'\n", value, name); 543 return -EINVAL; 544 } 545 property_set(name, prop_val); 546 return 0; 547 } 548 549 int do_setrlimit(int nargs, char **args) 550 { 551 struct rlimit limit; 552 int resource; 553 resource = atoi(args[1]); 554 limit.rlim_cur = atoi(args[2]); 555 limit.rlim_max = atoi(args[3]); 556 return setrlimit(resource, &limit); 557 } 558 559 int do_start(int nargs, char **args) 560 { 561 struct service *svc; 562 svc = service_find_by_name(args[1]); 563 if (svc) { 564 service_start(svc, NULL); 565 } 566 return 0; 567 } 568 569 int do_stop(int nargs, char **args) 570 { 571 struct service *svc; 572 svc = service_find_by_name(args[1]); 573 if (svc) { 574 service_stop(svc); 575 } 576 return 0; 577 } 578 579 int do_restart(int nargs, char **args) 580 { 581 struct service *svc; 582 svc = service_find_by_name(args[1]); 583 if (svc) { 584 service_stop(svc); 585 service_start(svc, NULL); 586 } 587 return 0; 588 } 589 590 int do_trigger(int nargs, char **args) 591 { 592 action_for_each_trigger(args[1], action_add_queue_tail); 593 return 0; 594 } 595 596 int do_symlink(int nargs, char **args) 597 { 598 return symlink(args[1], args[2]); 599 } 600 601 int do_rm(int nargs, char **args) 602 { 603 return unlink(args[1]); 604 } 605 606 int do_rmdir(int nargs, char **args) 607 { 608 return rmdir(args[1]); 609 } 610 611 int do_sysclktz(int nargs, char **args) 612 { 613 struct timezone tz; 614 615 if (nargs != 2) 616 return -1; 617 618 memset(&tz, 0, sizeof(tz)); 619 tz.tz_minuteswest = atoi(args[1]); 620 if (settimeofday(NULL, &tz)) 621 return -1; 622 return 0; 623 } 624 625 int do_write(int nargs, char **args) 626 { 627 const char *path = args[1]; 628 const char *value = args[2]; 629 char prop_val[PROP_VALUE_MAX]; 630 int ret; 631 632 ret = expand_props(prop_val, value, sizeof(prop_val)); 633 if (ret) { 634 ERROR("cannot expand '%s' while writing to '%s'\n", value, path); 635 return -EINVAL; 636 } 637 return write_file(path, prop_val); 638 } 639 640 int do_copy(int nargs, char **args) 641 { 642 char *buffer = NULL; 643 int rc = 0; 644 int fd1 = -1, fd2 = -1; 645 struct stat info; 646 int brtw, brtr; 647 char *p; 648 649 if (nargs != 3) 650 return -1; 651 652 if (stat(args[1], &info) < 0) 653 return -1; 654 655 if ((fd1 = open(args[1], O_RDONLY)) < 0) 656 goto out_err; 657 658 if ((fd2 = open(args[2], O_WRONLY|O_CREAT|O_TRUNC, 0660)) < 0) 659 goto out_err; 660 661 if (!(buffer = malloc(info.st_size))) 662 goto out_err; 663 664 p = buffer; 665 brtr = info.st_size; 666 while(brtr) { 667 rc = read(fd1, p, brtr); 668 if (rc < 0) 669 goto out_err; 670 if (rc == 0) 671 break; 672 p += rc; 673 brtr -= rc; 674 } 675 676 p = buffer; 677 brtw = info.st_size; 678 while(brtw) { 679 rc = write(fd2, p, brtw); 680 if (rc < 0) 681 goto out_err; 682 if (rc == 0) 683 break; 684 p += rc; 685 brtw -= rc; 686 } 687 688 rc = 0; 689 goto out; 690 out_err: 691 rc = -1; 692 out: 693 if (buffer) 694 free(buffer); 695 if (fd1 >= 0) 696 close(fd1); 697 if (fd2 >= 0) 698 close(fd2); 699 return rc; 700 } 701 702 int do_chown(int nargs, char **args) { 703 /* GID is optional. */ 704 if (nargs == 3) { 705 if (_chown(args[2], decode_uid(args[1]), -1) < 0) 706 return -errno; 707 } else if (nargs == 4) { 708 if (_chown(args[3], decode_uid(args[1]), decode_uid(args[2])) < 0) 709 return -errno; 710 } else { 711 return -1; 712 } 713 return 0; 714 } 715 716 static mode_t get_mode(const char *s) { 717 mode_t mode = 0; 718 while (*s) { 719 if (*s >= '0' && *s <= '7') { 720 mode = (mode<<3) | (*s-'0'); 721 } else { 722 return -1; 723 } 724 s++; 725 } 726 return mode; 727 } 728 729 int do_chmod(int nargs, char **args) { 730 mode_t mode = get_mode(args[1]); 731 if (_chmod(args[2], mode) < 0) { 732 return -errno; 733 } 734 return 0; 735 } 736 737 int do_restorecon(int nargs, char **args) { 738 #ifdef HAVE_SELINUX 739 char *secontext = NULL; 740 struct stat sb; 741 int i; 742 743 if (is_selinux_enabled() <= 0 || !sehandle) 744 return 0; 745 746 for (i = 1; i < nargs; i++) { 747 if (lstat(args[i], &sb) < 0) 748 return -errno; 749 if (selabel_lookup(sehandle, &secontext, args[i], sb.st_mode) < 0) 750 return -errno; 751 if (lsetfilecon(args[i], secontext) < 0) { 752 freecon(secontext); 753 return -errno; 754 } 755 freecon(secontext); 756 } 757 #endif 758 return 0; 759 } 760 761 int do_setsebool(int nargs, char **args) { 762 #ifdef HAVE_SELINUX 763 SELboolean *b = alloca(nargs * sizeof(SELboolean)); 764 char *v; 765 int i; 766 767 if (is_selinux_enabled() <= 0) 768 return 0; 769 770 for (i = 1; i < nargs; i++) { 771 char *name = args[i]; 772 v = strchr(name, '='); 773 if (!v) { 774 ERROR("setsebool: argument %s had no =\n", name); 775 return -EINVAL; 776 } 777 *v++ = 0; 778 b[i-1].name = name; 779 if (!strcmp(v, "1") || !strcasecmp(v, "true") || !strcasecmp(v, "on")) 780 b[i-1].value = 1; 781 else if (!strcmp(v, "0") || !strcasecmp(v, "false") || !strcasecmp(v, "off")) 782 b[i-1].value = 0; 783 else { 784 ERROR("setsebool: invalid value %s\n", v); 785 return -EINVAL; 786 } 787 } 788 789 if (security_set_boolean_list(nargs - 1, b, 0) < 0) 790 return -errno; 791 #endif 792 return 0; 793 } 794 795 int do_loglevel(int nargs, char **args) { 796 if (nargs == 2) { 797 klog_set_level(atoi(args[1])); 798 return 0; 799 } 800 return -1; 801 } 802 803 int do_load_persist_props(int nargs, char **args) { 804 if (nargs == 1) { 805 load_persist_props(); 806 return 0; 807 } 808 return -1; 809 } 810 811 int do_wait(int nargs, char **args) 812 { 813 if (nargs == 2) { 814 return wait_for_file(args[1], COMMAND_RETRY_TIMEOUT); 815 } 816 return -1; 817 } 818