• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  
write_file(const char * path,const char * value)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  
_open(const char * path)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  
_chown(const char * path,unsigned int uid,unsigned int gid)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  
_chmod(const char * path,mode_t mode)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  
insmod(const char * filename,char * options)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  
setkey(struct kbentry * kbe)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  
__ifupdown(const char * interface,int up)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  
service_start_if_not_disabled(struct service * svc)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  
do_chdir(int nargs,char ** args)203  int do_chdir(int nargs, char **args)
204  {
205      chdir(args[1]);
206      return 0;
207  }
208  
do_chroot(int nargs,char ** args)209  int do_chroot(int nargs, char **args)
210  {
211      chroot(args[1]);
212      return 0;
213  }
214  
do_class_start(int nargs,char ** args)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  
do_class_stop(int nargs,char ** args)225  int do_class_stop(int nargs, char **args)
226  {
227      service_for_each_class(args[1], service_stop);
228      return 0;
229  }
230  
do_class_reset(int nargs,char ** args)231  int do_class_reset(int nargs, char **args)
232  {
233      service_for_each_class(args[1], service_reset);
234      return 0;
235  }
236  
do_domainname(int nargs,char ** args)237  int do_domainname(int nargs, char **args)
238  {
239      return write_file("/proc/sys/kernel/domainname", args[1]);
240  }
241  
do_exec(int nargs,char ** args)242  int do_exec(int nargs, char **args)
243  {
244      return -1;
245  }
246  
do_export(int nargs,char ** args)247  int do_export(int nargs, char **args)
248  {
249      add_environment(args[1], args[2]);
250      return 0;
251  }
252  
do_hostname(int nargs,char ** args)253  int do_hostname(int nargs, char **args)
254  {
255      return write_file("/proc/sys/kernel/hostname", args[1]);
256  }
257  
do_ifup(int nargs,char ** args)258  int do_ifup(int nargs, char **args)
259  {
260      return __ifupdown(args[1], 1);
261  }
262  
263  
do_insmod_inner(int nargs,char ** args,int opt_len)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  
do_insmod(int nargs,char ** args)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  
do_mkdir(int nargs,char ** args)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> */
do_mount(int nargs,char ** args)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  
do_mount_all(int nargs,char ** args)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  
do_setcon(int nargs,char ** args)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  
do_setenforce(int nargs,char ** args)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  
do_setkey(int nargs,char ** args)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  
do_setprop(int nargs,char ** args)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  
do_setrlimit(int nargs,char ** args)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  
do_start(int nargs,char ** args)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  
do_stop(int nargs,char ** args)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  
do_restart(int nargs,char ** args)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  
do_trigger(int nargs,char ** args)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  
do_symlink(int nargs,char ** args)611  int do_symlink(int nargs, char **args)
612  {
613      return symlink(args[1], args[2]);
614  }
615  
do_rm(int nargs,char ** args)616  int do_rm(int nargs, char **args)
617  {
618      return unlink(args[1]);
619  }
620  
do_rmdir(int nargs,char ** args)621  int do_rmdir(int nargs, char **args)
622  {
623      return rmdir(args[1]);
624  }
625  
do_sysclktz(int nargs,char ** args)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  
do_write(int nargs,char ** args)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  
do_copy(int nargs,char ** args)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  
do_chown(int nargs,char ** args)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  
get_mode(const char * s)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  
do_chmod(int nargs,char ** args)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  
do_restorecon(int nargs,char ** args)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  
do_setsebool(int nargs,char ** args)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  
do_loglevel(int nargs,char ** args)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  
do_load_persist_props(int nargs,char ** args)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  
do_wait(int nargs,char ** args)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