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