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 #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