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 = make_dir(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         /* chown may have cleared S_ISUID and S_ISGID, chmod again */
    327         if (mode & (S_ISUID | S_ISGID)) {
    328             ret = _chmod(args[1], mode);
    329             if (ret == -1) {
    330                 return -errno;
    331             }
    332         }
    333     }
    334 
    335     return 0;
    336 }
    337 
    338 static struct {
    339     const char *name;
    340     unsigned flag;
    341 } mount_flags[] = {
    342     { "noatime",    MS_NOATIME },
    343     { "noexec",     MS_NOEXEC },
    344     { "nosuid",     MS_NOSUID },
    345     { "nodev",      MS_NODEV },
    346     { "nodiratime", MS_NODIRATIME },
    347     { "ro",         MS_RDONLY },
    348     { "rw",         0 },
    349     { "remount",    MS_REMOUNT },
    350     { "bind",       MS_BIND },
    351     { "rec",        MS_REC },
    352     { "unbindable", MS_UNBINDABLE },
    353     { "private",    MS_PRIVATE },
    354     { "slave",      MS_SLAVE },
    355     { "shared",     MS_SHARED },
    356     { "defaults",   0 },
    357     { 0,            0 },
    358 };
    359 
    360 #define DATA_MNT_POINT "/data"
    361 
    362 /* mount <type> <device> <path> <flags ...> <options> */
    363 int do_mount(int nargs, char **args)
    364 {
    365     char tmp[64];
    366     char *source, *target, *system;
    367     char *options = NULL;
    368     unsigned flags = 0;
    369     int n, i;
    370     int wait = 0;
    371 
    372     for (n = 4; n < nargs; n++) {
    373         for (i = 0; mount_flags[i].name; i++) {
    374             if (!strcmp(args[n], mount_flags[i].name)) {
    375                 flags |= mount_flags[i].flag;
    376                 break;
    377             }
    378         }
    379 
    380         if (!mount_flags[i].name) {
    381             if (!strcmp(args[n], "wait"))
    382                 wait = 1;
    383             /* if our last argument isn't a flag, wolf it up as an option string */
    384             else if (n + 1 == nargs)
    385                 options = args[n];
    386         }
    387     }
    388 
    389     system = args[1];
    390     source = args[2];
    391     target = args[3];
    392 
    393     if (!strncmp(source, "mtd@", 4)) {
    394         n = mtd_name_to_number(source + 4);
    395         if (n < 0) {
    396             return -1;
    397         }
    398 
    399         sprintf(tmp, "/dev/block/mtdblock%d", n);
    400 
    401         if (wait)
    402             wait_for_file(tmp, COMMAND_RETRY_TIMEOUT);
    403         if (mount(tmp, target, system, flags, options) < 0) {
    404             return -1;
    405         }
    406 
    407         goto exit_success;
    408     } else if (!strncmp(source, "loop@", 5)) {
    409         int mode, loop, fd;
    410         struct loop_info info;
    411 
    412         mode = (flags & MS_RDONLY) ? O_RDONLY : O_RDWR;
    413         fd = open(source + 5, mode);
    414         if (fd < 0) {
    415             return -1;
    416         }
    417 
    418         for (n = 0; ; n++) {
    419             sprintf(tmp, "/dev/block/loop%d", n);
    420             loop = open(tmp, mode);
    421             if (loop < 0) {
    422                 return -1;
    423             }
    424 
    425             /* if it is a blank loop device */
    426             if (ioctl(loop, LOOP_GET_STATUS, &info) < 0 && errno == ENXIO) {
    427                 /* if it becomes our loop device */
    428                 if (ioctl(loop, LOOP_SET_FD, fd) >= 0) {
    429                     close(fd);
    430 
    431                     if (mount(tmp, target, system, flags, options) < 0) {
    432                         ioctl(loop, LOOP_CLR_FD, 0);
    433                         close(loop);
    434                         return -1;
    435                     }
    436 
    437                     close(loop);
    438                     goto exit_success;
    439                 }
    440             }
    441 
    442             close(loop);
    443         }
    444 
    445         close(fd);
    446         ERROR("out of loopback devices");
    447         return -1;
    448     } else {
    449         if (wait)
    450             wait_for_file(source, COMMAND_RETRY_TIMEOUT);
    451         if (mount(source, target, system, flags, options) < 0) {
    452             return -1;
    453         }
    454 
    455     }
    456 
    457 exit_success:
    458     return 0;
    459 
    460 }
    461 
    462 int do_mount_all(int nargs, char **args)
    463 {
    464     pid_t pid;
    465     int ret = -1;
    466     int child_ret = -1;
    467     int status;
    468     const char *prop;
    469 
    470     if (nargs != 2) {
    471         return -1;
    472     }
    473 
    474     /*
    475      * Call fs_mgr_mount_all() to mount all filesystems.  We fork(2) and
    476      * do the call in the child to provide protection to the main init
    477      * process if anything goes wrong (crash or memory leak), and wait for
    478      * the child to finish in the parent.
    479      */
    480     pid = fork();
    481     if (pid > 0) {
    482         /* Parent.  Wait for the child to return */
    483         waitpid(pid, &status, 0);
    484         if (WIFEXITED(status)) {
    485             ret = WEXITSTATUS(status);
    486         } else {
    487             ret = -1;
    488         }
    489     } else if (pid == 0) {
    490         /* child, call fs_mgr_mount_all() */
    491         klog_set_level(6);  /* So we can see what fs_mgr_mount_all() does */
    492         child_ret = fs_mgr_mount_all(args[1]);
    493         if (child_ret == -1) {
    494             ERROR("fs_mgr_mount_all returned an error\n");
    495         }
    496         exit(child_ret);
    497     } else {
    498         /* fork failed, return an error */
    499         return -1;
    500     }
    501 
    502     /* ret is 1 if the device is encrypted, 0 if not, and -1 on error */
    503     if (ret == 1) {
    504         property_set("ro.crypto.state", "encrypted");
    505         property_set("vold.decrypt", "1");
    506     } else if (ret == 0) {
    507         property_set("ro.crypto.state", "unencrypted");
    508         /* If fs_mgr determined this is an unencrypted device, then trigger
    509          * that action.
    510          */
    511         action_for_each_trigger("nonencrypted", action_add_queue_tail);
    512     }
    513 
    514     return ret;
    515 }
    516 
    517 int do_setcon(int nargs, char **args) {
    518 #ifdef HAVE_SELINUX
    519     if (is_selinux_enabled() <= 0)
    520         return 0;
    521     if (setcon(args[1]) < 0) {
    522         return -errno;
    523     }
    524 #endif
    525     return 0;
    526 }
    527 
    528 int do_setenforce(int nargs, char **args) {
    529 #ifdef HAVE_SELINUX
    530     if (is_selinux_enabled() <= 0)
    531         return 0;
    532     if (security_setenforce(atoi(args[1])) < 0) {
    533         return -errno;
    534     }
    535 #endif
    536     return 0;
    537 }
    538 
    539 int do_setkey(int nargs, char **args)
    540 {
    541     struct kbentry kbe;
    542     kbe.kb_table = strtoul(args[1], 0, 0);
    543     kbe.kb_index = strtoul(args[2], 0, 0);
    544     kbe.kb_value = strtoul(args[3], 0, 0);
    545     return setkey(&kbe);
    546 }
    547 
    548 int do_setprop(int nargs, char **args)
    549 {
    550     const char *name = args[1];
    551     const char *value = args[2];
    552     char prop_val[PROP_VALUE_MAX];
    553     int ret;
    554 
    555     ret = expand_props(prop_val, value, sizeof(prop_val));
    556     if (ret) {
    557         ERROR("cannot expand '%s' while assigning to '%s'\n", value, name);
    558         return -EINVAL;
    559     }
    560     property_set(name, prop_val);
    561     return 0;
    562 }
    563 
    564 int do_setrlimit(int nargs, char **args)
    565 {
    566     struct rlimit limit;
    567     int resource;
    568     resource = atoi(args[1]);
    569     limit.rlim_cur = atoi(args[2]);
    570     limit.rlim_max = atoi(args[3]);
    571     return setrlimit(resource, &limit);
    572 }
    573 
    574 int do_start(int nargs, char **args)
    575 {
    576     struct service *svc;
    577     svc = service_find_by_name(args[1]);
    578     if (svc) {
    579         service_start(svc, NULL);
    580     }
    581     return 0;
    582 }
    583 
    584 int do_stop(int nargs, char **args)
    585 {
    586     struct service *svc;
    587     svc = service_find_by_name(args[1]);
    588     if (svc) {
    589         service_stop(svc);
    590     }
    591     return 0;
    592 }
    593 
    594 int do_restart(int nargs, char **args)
    595 {
    596     struct service *svc;
    597     svc = service_find_by_name(args[1]);
    598     if (svc) {
    599         service_stop(svc);
    600         service_start(svc, NULL);
    601     }
    602     return 0;
    603 }
    604 
    605 int do_trigger(int nargs, char **args)
    606 {
    607     action_for_each_trigger(args[1], action_add_queue_tail);
    608     return 0;
    609 }
    610 
    611 int do_symlink(int nargs, char **args)
    612 {
    613     return symlink(args[1], args[2]);
    614 }
    615 
    616 int do_rm(int nargs, char **args)
    617 {
    618     return unlink(args[1]);
    619 }
    620 
    621 int do_rmdir(int nargs, char **args)
    622 {
    623     return rmdir(args[1]);
    624 }
    625 
    626 int do_sysclktz(int nargs, char **args)
    627 {
    628     struct timezone tz;
    629 
    630     if (nargs != 2)
    631         return -1;
    632 
    633     memset(&tz, 0, sizeof(tz));
    634     tz.tz_minuteswest = atoi(args[1]);
    635     if (settimeofday(NULL, &tz))
    636         return -1;
    637     return 0;
    638 }
    639 
    640 int do_write(int nargs, char **args)
    641 {
    642     const char *path = args[1];
    643     const char *value = args[2];
    644     char prop_val[PROP_VALUE_MAX];
    645     int ret;
    646 
    647     ret = expand_props(prop_val, value, sizeof(prop_val));
    648     if (ret) {
    649         ERROR("cannot expand '%s' while writing to '%s'\n", value, path);
    650         return -EINVAL;
    651     }
    652     return write_file(path, prop_val);
    653 }
    654 
    655 int do_copy(int nargs, char **args)
    656 {
    657     char *buffer = NULL;
    658     int rc = 0;
    659     int fd1 = -1, fd2 = -1;
    660     struct stat info;
    661     int brtw, brtr;
    662     char *p;
    663 
    664     if (nargs != 3)
    665         return -1;
    666 
    667     if (stat(args[1], &info) < 0)
    668         return -1;
    669 
    670     if ((fd1 = open(args[1], O_RDONLY)) < 0)
    671         goto out_err;
    672 
    673     if ((fd2 = open(args[2], O_WRONLY|O_CREAT|O_TRUNC, 0660)) < 0)
    674         goto out_err;
    675 
    676     if (!(buffer = malloc(info.st_size)))
    677         goto out_err;
    678 
    679     p = buffer;
    680     brtr = info.st_size;
    681     while(brtr) {
    682         rc = read(fd1, p, brtr);
    683         if (rc < 0)
    684             goto out_err;
    685         if (rc == 0)
    686             break;
    687         p += rc;
    688         brtr -= rc;
    689     }
    690 
    691     p = buffer;
    692     brtw = info.st_size;
    693     while(brtw) {
    694         rc = write(fd2, p, brtw);
    695         if (rc < 0)
    696             goto out_err;
    697         if (rc == 0)
    698             break;
    699         p += rc;
    700         brtw -= rc;
    701     }
    702 
    703     rc = 0;
    704     goto out;
    705 out_err:
    706     rc = -1;
    707 out:
    708     if (buffer)
    709         free(buffer);
    710     if (fd1 >= 0)
    711         close(fd1);
    712     if (fd2 >= 0)
    713         close(fd2);
    714     return rc;
    715 }
    716 
    717 int do_chown(int nargs, char **args) {
    718     /* GID is optional. */
    719     if (nargs == 3) {
    720         if (_chown(args[2], decode_uid(args[1]), -1) < 0)
    721             return -errno;
    722     } else if (nargs == 4) {
    723         if (_chown(args[3], decode_uid(args[1]), decode_uid(args[2])) < 0)
    724             return -errno;
    725     } else {
    726         return -1;
    727     }
    728     return 0;
    729 }
    730 
    731 static mode_t get_mode(const char *s) {
    732     mode_t mode = 0;
    733     while (*s) {
    734         if (*s >= '0' && *s <= '7') {
    735             mode = (mode<<3) | (*s-'0');
    736         } else {
    737             return -1;
    738         }
    739         s++;
    740     }
    741     return mode;
    742 }
    743 
    744 int do_chmod(int nargs, char **args) {
    745     mode_t mode = get_mode(args[1]);
    746     if (_chmod(args[2], mode) < 0) {
    747         return -errno;
    748     }
    749     return 0;
    750 }
    751 
    752 int do_restorecon(int nargs, char **args) {
    753     int i;
    754 
    755     for (i = 1; i < nargs; i++) {
    756         if (restorecon(args[i]) < 0)
    757             return -errno;
    758     }
    759     return 0;
    760 }
    761 
    762 int do_setsebool(int nargs, char **args) {
    763 #ifdef HAVE_SELINUX
    764     SELboolean *b = alloca(nargs * sizeof(SELboolean));
    765     char *v;
    766     int i;
    767 
    768     if (is_selinux_enabled() <= 0)
    769         return 0;
    770 
    771     for (i = 1; i < nargs; i++) {
    772         char *name = args[i];
    773         v = strchr(name, '=');
    774         if (!v) {
    775             ERROR("setsebool: argument %s had no =\n", name);
    776             return -EINVAL;
    777         }
    778         *v++ = 0;
    779         b[i-1].name = name;
    780         if (!strcmp(v, "1") || !strcasecmp(v, "true") || !strcasecmp(v, "on"))
    781             b[i-1].value = 1;
    782         else if (!strcmp(v, "0") || !strcasecmp(v, "false") || !strcasecmp(v, "off"))
    783             b[i-1].value = 0;
    784         else {
    785             ERROR("setsebool: invalid value %s\n", v);
    786             return -EINVAL;
    787         }
    788     }
    789 
    790     if (security_set_boolean_list(nargs - 1, b, 0) < 0)
    791         return -errno;
    792 #endif
    793     return 0;
    794 }
    795 
    796 int do_loglevel(int nargs, char **args) {
    797     if (nargs == 2) {
    798         klog_set_level(atoi(args[1]));
    799         return 0;
    800     }
    801     return -1;
    802 }
    803 
    804 int do_load_persist_props(int nargs, char **args) {
    805     if (nargs == 1) {
    806         load_persist_props();
    807         return 0;
    808     }
    809     return -1;
    810 }
    811 
    812 int do_wait(int nargs, char **args)
    813 {
    814     if (nargs == 2) {
    815         return wait_for_file(args[1], COMMAND_RETRY_TIMEOUT);
    816     } else if (nargs == 3) {
    817         return wait_for_file(args[1], atoi(args[2]));
    818     } else
    819         return -1;
    820 }
    821