• 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 <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <unistd.h>
21 #include <fcntl.h>
22 #include <ctype.h>
23 #include <signal.h>
24 #include <sys/wait.h>
25 #include <sys/mount.h>
26 #include <sys/stat.h>
27 #include <sys/poll.h>
28 #include <errno.h>
29 #include <stdarg.h>
30 #include <mtd/mtd-user.h>
31 #include <sys/types.h>
32 #include <sys/socket.h>
33 #include <sys/un.h>
34 #include <sys/personality.h>
35 
36 #ifdef HAVE_SELINUX
37 #include <selinux/selinux.h>
38 #include <selinux/label.h>
39 #include <selinux/android.h>
40 #endif
41 
42 #include <libgen.h>
43 
44 #include <cutils/list.h>
45 #include <cutils/sockets.h>
46 #include <cutils/iosched_policy.h>
47 #include <private/android_filesystem_config.h>
48 #include <termios.h>
49 
50 #include <sys/system_properties.h>
51 
52 #include "devices.h"
53 #include "init.h"
54 #include "log.h"
55 #include "property_service.h"
56 #include "bootchart.h"
57 #include "signal_handler.h"
58 #include "keychords.h"
59 #include "init_parser.h"
60 #include "util.h"
61 #include "ueventd.h"
62 #include "watchdogd.h"
63 
64 #ifdef HAVE_SELINUX
65 struct selabel_handle *sehandle;
66 struct selabel_handle *sehandle_prop;
67 #endif
68 
69 static int property_triggers_enabled = 0;
70 
71 #if BOOTCHART
72 static int   bootchart_count;
73 #endif
74 
75 static char console[32];
76 static char bootmode[32];
77 static char hardware[32];
78 static unsigned revision = 0;
79 static char qemu[32];
80 
81 #ifdef HAVE_SELINUX
82 static int selinux_enabled = 1;
83 #endif
84 
85 static struct action *cur_action = NULL;
86 static struct command *cur_command = NULL;
87 static struct listnode *command_queue = NULL;
88 
notify_service_state(const char * name,const char * state)89 void notify_service_state(const char *name, const char *state)
90 {
91     char pname[PROP_NAME_MAX];
92     int len = strlen(name);
93     if ((len + 10) > PROP_NAME_MAX)
94         return;
95     snprintf(pname, sizeof(pname), "init.svc.%s", name);
96     property_set(pname, state);
97 }
98 
99 static int have_console;
100 static char *console_name = "/dev/console";
101 static time_t process_needs_restart;
102 
103 static const char *ENV[32];
104 
105 /* add_environment - add "key=value" to the current environment */
add_environment(const char * key,const char * val)106 int add_environment(const char *key, const char *val)
107 {
108     int n;
109 
110     for (n = 0; n < 31; n++) {
111         if (!ENV[n]) {
112             size_t len = strlen(key) + strlen(val) + 2;
113             char *entry = malloc(len);
114             snprintf(entry, len, "%s=%s", key, val);
115             ENV[n] = entry;
116             return 0;
117         }
118     }
119 
120     return 1;
121 }
122 
zap_stdio(void)123 static void zap_stdio(void)
124 {
125     int fd;
126     fd = open("/dev/null", O_RDWR);
127     dup2(fd, 0);
128     dup2(fd, 1);
129     dup2(fd, 2);
130     close(fd);
131 }
132 
open_console()133 static void open_console()
134 {
135     int fd;
136     if ((fd = open(console_name, O_RDWR)) < 0) {
137         fd = open("/dev/null", O_RDWR);
138     }
139     ioctl(fd, TIOCSCTTY, 0);
140     dup2(fd, 0);
141     dup2(fd, 1);
142     dup2(fd, 2);
143     close(fd);
144 }
145 
publish_socket(const char * name,int fd)146 static void publish_socket(const char *name, int fd)
147 {
148     char key[64] = ANDROID_SOCKET_ENV_PREFIX;
149     char val[64];
150 
151     strlcpy(key + sizeof(ANDROID_SOCKET_ENV_PREFIX) - 1,
152             name,
153             sizeof(key) - sizeof(ANDROID_SOCKET_ENV_PREFIX));
154     snprintf(val, sizeof(val), "%d", fd);
155     add_environment(key, val);
156 
157     /* make sure we don't close-on-exec */
158     fcntl(fd, F_SETFD, 0);
159 }
160 
service_start(struct service * svc,const char * dynamic_args)161 void service_start(struct service *svc, const char *dynamic_args)
162 {
163     struct stat s;
164     pid_t pid;
165     int needs_console;
166     int n;
167 #ifdef HAVE_SELINUX
168     char *scon = NULL;
169     int rc;
170 #endif
171         /* starting a service removes it from the disabled or reset
172          * state and immediately takes it out of the restarting
173          * state if it was in there
174          */
175     svc->flags &= (~(SVC_DISABLED|SVC_RESTARTING|SVC_RESET));
176     svc->time_started = 0;
177 
178         /* running processes require no additional work -- if
179          * they're in the process of exiting, we've ensured
180          * that they will immediately restart on exit, unless
181          * they are ONESHOT
182          */
183     if (svc->flags & SVC_RUNNING) {
184         return;
185     }
186 
187     needs_console = (svc->flags & SVC_CONSOLE) ? 1 : 0;
188     if (needs_console && (!have_console)) {
189         ERROR("service '%s' requires console\n", svc->name);
190         svc->flags |= SVC_DISABLED;
191         return;
192     }
193 
194     if (stat(svc->args[0], &s) != 0) {
195         ERROR("cannot find '%s', disabling '%s'\n", svc->args[0], svc->name);
196         svc->flags |= SVC_DISABLED;
197         return;
198     }
199 
200     if ((!(svc->flags & SVC_ONESHOT)) && dynamic_args) {
201         ERROR("service '%s' must be one-shot to use dynamic args, disabling\n",
202                svc->args[0]);
203         svc->flags |= SVC_DISABLED;
204         return;
205     }
206 
207 #ifdef HAVE_SELINUX
208     if (is_selinux_enabled() > 0) {
209         char *mycon = NULL, *fcon = NULL;
210 
211         INFO("computing context for service '%s'\n", svc->args[0]);
212         rc = getcon(&mycon);
213         if (rc < 0) {
214             ERROR("could not get context while starting '%s'\n", svc->name);
215             return;
216         }
217 
218         rc = getfilecon(svc->args[0], &fcon);
219         if (rc < 0) {
220             ERROR("could not get context while starting '%s'\n", svc->name);
221             freecon(mycon);
222             return;
223         }
224 
225         rc = security_compute_create(mycon, fcon, string_to_security_class("process"), &scon);
226         freecon(mycon);
227         freecon(fcon);
228         if (rc < 0) {
229             ERROR("could not get context while starting '%s'\n", svc->name);
230             return;
231         }
232     }
233 #endif
234 
235     NOTICE("starting '%s'\n", svc->name);
236 
237     pid = fork();
238 
239     if (pid == 0) {
240         struct socketinfo *si;
241         struct svcenvinfo *ei;
242         char tmp[32];
243         int fd, sz;
244 
245         umask(077);
246 #ifdef __arm__
247         /*
248          * b/7188322 - Temporarily revert to the compat memory layout
249          * to avoid breaking third party apps.
250          *
251          * THIS WILL GO AWAY IN A FUTURE ANDROID RELEASE.
252          *
253          * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=7dbaa466
254          * changes the kernel mapping from bottom up to top-down.
255          * This breaks some programs which improperly embed
256          * an out of date copy of Android's linker.
257          */
258         int current = personality(0xffffFFFF);
259         personality(current | ADDR_COMPAT_LAYOUT);
260 #endif
261         if (properties_inited()) {
262             get_property_workspace(&fd, &sz);
263             sprintf(tmp, "%d,%d", dup(fd), sz);
264             add_environment("ANDROID_PROPERTY_WORKSPACE", tmp);
265         }
266 
267         for (ei = svc->envvars; ei; ei = ei->next)
268             add_environment(ei->name, ei->value);
269 
270 #ifdef HAVE_SELINUX
271         setsockcreatecon(scon);
272 #endif
273 
274         for (si = svc->sockets; si; si = si->next) {
275             int socket_type = (
276                     !strcmp(si->type, "stream") ? SOCK_STREAM :
277                         (!strcmp(si->type, "dgram") ? SOCK_DGRAM : SOCK_SEQPACKET));
278             int s = create_socket(si->name, socket_type,
279                                   si->perm, si->uid, si->gid);
280             if (s >= 0) {
281                 publish_socket(si->name, s);
282             }
283         }
284 
285 #ifdef HAVE_SELINUX
286         freecon(scon);
287         scon = NULL;
288         setsockcreatecon(NULL);
289 #endif
290 
291         if (svc->ioprio_class != IoSchedClass_NONE) {
292             if (android_set_ioprio(getpid(), svc->ioprio_class, svc->ioprio_pri)) {
293                 ERROR("Failed to set pid %d ioprio = %d,%d: %s\n",
294                       getpid(), svc->ioprio_class, svc->ioprio_pri, strerror(errno));
295             }
296         }
297 
298         if (needs_console) {
299             setsid();
300             open_console();
301         } else {
302             zap_stdio();
303         }
304 
305 #if 0
306         for (n = 0; svc->args[n]; n++) {
307             INFO("args[%d] = '%s'\n", n, svc->args[n]);
308         }
309         for (n = 0; ENV[n]; n++) {
310             INFO("env[%d] = '%s'\n", n, ENV[n]);
311         }
312 #endif
313 
314         setpgid(0, getpid());
315 
316     /* as requested, set our gid, supplemental gids, and uid */
317         if (svc->gid) {
318             if (setgid(svc->gid) != 0) {
319                 ERROR("setgid failed: %s\n", strerror(errno));
320                 _exit(127);
321             }
322         }
323         if (svc->nr_supp_gids) {
324             if (setgroups(svc->nr_supp_gids, svc->supp_gids) != 0) {
325                 ERROR("setgroups failed: %s\n", strerror(errno));
326                 _exit(127);
327             }
328         }
329         if (svc->uid) {
330             if (setuid(svc->uid) != 0) {
331                 ERROR("setuid failed: %s\n", strerror(errno));
332                 _exit(127);
333             }
334         }
335 
336 #ifdef HAVE_SELINUX
337         if (svc->seclabel) {
338             if (is_selinux_enabled() > 0 && setexeccon(svc->seclabel) < 0) {
339                 ERROR("cannot setexeccon('%s'): %s\n", svc->seclabel, strerror(errno));
340                 _exit(127);
341             }
342         }
343 #endif
344 
345         if (!dynamic_args) {
346             if (execve(svc->args[0], (char**) svc->args, (char**) ENV) < 0) {
347                 ERROR("cannot execve('%s'): %s\n", svc->args[0], strerror(errno));
348             }
349         } else {
350             char *arg_ptrs[INIT_PARSER_MAXARGS+1];
351             int arg_idx = svc->nargs;
352             char *tmp = strdup(dynamic_args);
353             char *next = tmp;
354             char *bword;
355 
356             /* Copy the static arguments */
357             memcpy(arg_ptrs, svc->args, (svc->nargs * sizeof(char *)));
358 
359             while((bword = strsep(&next, " "))) {
360                 arg_ptrs[arg_idx++] = bword;
361                 if (arg_idx == INIT_PARSER_MAXARGS)
362                     break;
363             }
364             arg_ptrs[arg_idx] = '\0';
365             execve(svc->args[0], (char**) arg_ptrs, (char**) ENV);
366         }
367         _exit(127);
368     }
369 
370 #ifdef HAVE_SELINUX
371     freecon(scon);
372 #endif
373 
374     if (pid < 0) {
375         ERROR("failed to start '%s'\n", svc->name);
376         svc->pid = 0;
377         return;
378     }
379 
380     svc->time_started = gettime();
381     svc->pid = pid;
382     svc->flags |= SVC_RUNNING;
383 
384     if (properties_inited())
385         notify_service_state(svc->name, "running");
386 }
387 
388 /* The how field should be either SVC_DISABLED or SVC_RESET */
service_stop_or_reset(struct service * svc,int how)389 static void service_stop_or_reset(struct service *svc, int how)
390 {
391         /* we are no longer running, nor should we
392          * attempt to restart
393          */
394     svc->flags &= (~(SVC_RUNNING|SVC_RESTARTING));
395 
396     if ((how != SVC_DISABLED) && (how != SVC_RESET)) {
397         /* Hrm, an illegal flag.  Default to SVC_DISABLED */
398         how = SVC_DISABLED;
399     }
400         /* if the service has not yet started, prevent
401          * it from auto-starting with its class
402          */
403     if (how == SVC_RESET) {
404         svc->flags |= (svc->flags & SVC_RC_DISABLED) ? SVC_DISABLED : SVC_RESET;
405     } else {
406         svc->flags |= how;
407     }
408 
409     if (svc->pid) {
410         NOTICE("service '%s' is being killed\n", svc->name);
411         kill(-svc->pid, SIGKILL);
412         notify_service_state(svc->name, "stopping");
413     } else {
414         notify_service_state(svc->name, "stopped");
415     }
416 }
417 
service_reset(struct service * svc)418 void service_reset(struct service *svc)
419 {
420     service_stop_or_reset(svc, SVC_RESET);
421 }
422 
service_stop(struct service * svc)423 void service_stop(struct service *svc)
424 {
425     service_stop_or_reset(svc, SVC_DISABLED);
426 }
427 
property_changed(const char * name,const char * value)428 void property_changed(const char *name, const char *value)
429 {
430     if (property_triggers_enabled)
431         queue_property_triggers(name, value);
432 }
433 
restart_service_if_needed(struct service * svc)434 static void restart_service_if_needed(struct service *svc)
435 {
436     time_t next_start_time = svc->time_started + 5;
437 
438     if (next_start_time <= gettime()) {
439         svc->flags &= (~SVC_RESTARTING);
440         service_start(svc, NULL);
441         return;
442     }
443 
444     if ((next_start_time < process_needs_restart) ||
445         (process_needs_restart == 0)) {
446         process_needs_restart = next_start_time;
447     }
448 }
449 
restart_processes()450 static void restart_processes()
451 {
452     process_needs_restart = 0;
453     service_for_each_flags(SVC_RESTARTING,
454                            restart_service_if_needed);
455 }
456 
msg_start(const char * name)457 static void msg_start(const char *name)
458 {
459     struct service *svc;
460     char *tmp = NULL;
461     char *args = NULL;
462 
463     if (!strchr(name, ':'))
464         svc = service_find_by_name(name);
465     else {
466         tmp = strdup(name);
467         args = strchr(tmp, ':');
468         *args = '\0';
469         args++;
470 
471         svc = service_find_by_name(tmp);
472     }
473 
474     if (svc) {
475         service_start(svc, args);
476     } else {
477         ERROR("no such service '%s'\n", name);
478     }
479     if (tmp)
480         free(tmp);
481 }
482 
msg_stop(const char * name)483 static void msg_stop(const char *name)
484 {
485     struct service *svc = service_find_by_name(name);
486 
487     if (svc) {
488         service_stop(svc);
489     } else {
490         ERROR("no such service '%s'\n", name);
491     }
492 }
493 
handle_control_message(const char * msg,const char * arg)494 void handle_control_message(const char *msg, const char *arg)
495 {
496     if (!strcmp(msg,"start")) {
497         msg_start(arg);
498     } else if (!strcmp(msg,"stop")) {
499         msg_stop(arg);
500     } else if (!strcmp(msg,"restart")) {
501         msg_stop(arg);
502         msg_start(arg);
503     } else {
504         ERROR("unknown control msg '%s'\n", msg);
505     }
506 }
507 
get_first_command(struct action * act)508 static struct command *get_first_command(struct action *act)
509 {
510     struct listnode *node;
511     node = list_head(&act->commands);
512     if (!node || list_empty(&act->commands))
513         return NULL;
514 
515     return node_to_item(node, struct command, clist);
516 }
517 
get_next_command(struct action * act,struct command * cmd)518 static struct command *get_next_command(struct action *act, struct command *cmd)
519 {
520     struct listnode *node;
521     node = cmd->clist.next;
522     if (!node)
523         return NULL;
524     if (node == &act->commands)
525         return NULL;
526 
527     return node_to_item(node, struct command, clist);
528 }
529 
is_last_command(struct action * act,struct command * cmd)530 static int is_last_command(struct action *act, struct command *cmd)
531 {
532     return (list_tail(&act->commands) == &cmd->clist);
533 }
534 
execute_one_command(void)535 void execute_one_command(void)
536 {
537     int ret;
538 
539     if (!cur_action || !cur_command || is_last_command(cur_action, cur_command)) {
540         cur_action = action_remove_queue_head();
541         cur_command = NULL;
542         if (!cur_action)
543             return;
544         INFO("processing action %p (%s)\n", cur_action, cur_action->name);
545         cur_command = get_first_command(cur_action);
546     } else {
547         cur_command = get_next_command(cur_action, cur_command);
548     }
549 
550     if (!cur_command)
551         return;
552 
553     ret = cur_command->func(cur_command->nargs, cur_command->args);
554     INFO("command '%s' r=%d\n", cur_command->args[0], ret);
555 }
556 
wait_for_coldboot_done_action(int nargs,char ** args)557 static int wait_for_coldboot_done_action(int nargs, char **args)
558 {
559     int ret;
560     INFO("wait for %s\n", coldboot_done);
561     ret = wait_for_file(coldboot_done, COMMAND_RETRY_TIMEOUT);
562     if (ret)
563         ERROR("Timed out waiting for %s\n", coldboot_done);
564     return ret;
565 }
566 
keychord_init_action(int nargs,char ** args)567 static int keychord_init_action(int nargs, char **args)
568 {
569     keychord_init();
570     return 0;
571 }
572 
console_init_action(int nargs,char ** args)573 static int console_init_action(int nargs, char **args)
574 {
575     int fd;
576     char tmp[PROP_VALUE_MAX];
577 
578     if (console[0]) {
579         snprintf(tmp, sizeof(tmp), "/dev/%s", console);
580         console_name = strdup(tmp);
581     }
582 
583     fd = open(console_name, O_RDWR);
584     if (fd >= 0)
585         have_console = 1;
586     close(fd);
587 
588     if( load_565rle_image(INIT_IMAGE_FILE) ) {
589         fd = open("/dev/tty0", O_WRONLY);
590         if (fd >= 0) {
591             const char *msg;
592                 msg = "\n"
593             "\n"
594             "\n"
595             "\n"
596             "\n"
597             "\n"
598             "\n"  // console is 40 cols x 30 lines
599             "\n"
600             "\n"
601             "\n"
602             "\n"
603             "\n"
604             "\n"
605             "\n"
606             "             A N D R O I D ";
607             write(fd, msg, strlen(msg));
608             close(fd);
609         }
610     }
611     return 0;
612 }
613 
import_kernel_nv(char * name,int for_emulator)614 static void import_kernel_nv(char *name, int for_emulator)
615 {
616     char *value = strchr(name, '=');
617     int name_len = strlen(name);
618 
619     if (value == 0) return;
620     *value++ = 0;
621     if (name_len == 0) return;
622 
623 #ifdef HAVE_SELINUX
624     if (!strcmp(name,"selinux")) {
625         selinux_enabled = atoi(value);
626     }
627 #endif
628 
629     if (for_emulator) {
630         /* in the emulator, export any kernel option with the
631          * ro.kernel. prefix */
632         char buff[PROP_NAME_MAX];
633         int len = snprintf( buff, sizeof(buff), "ro.kernel.%s", name );
634 
635         if (len < (int)sizeof(buff))
636             property_set( buff, value );
637         return;
638     }
639 
640     if (!strcmp(name,"qemu")) {
641         strlcpy(qemu, value, sizeof(qemu));
642     } else if (!strncmp(name, "androidboot.", 12) && name_len > 12) {
643         const char *boot_prop_name = name + 12;
644         char prop[PROP_NAME_MAX];
645         int cnt;
646 
647         cnt = snprintf(prop, sizeof(prop), "ro.boot.%s", boot_prop_name);
648         if (cnt < PROP_NAME_MAX)
649             property_set(prop, value);
650     }
651 }
652 
export_kernel_boot_props(void)653 static void export_kernel_boot_props(void)
654 {
655     char tmp[PROP_VALUE_MAX];
656     const char *pval;
657     unsigned i;
658     struct {
659         const char *src_prop;
660         const char *dest_prop;
661         const char *def_val;
662     } prop_map[] = {
663         { "ro.boot.serialno", "ro.serialno", "", },
664         { "ro.boot.mode", "ro.bootmode", "unknown", },
665         { "ro.boot.baseband", "ro.baseband", "unknown", },
666         { "ro.boot.bootloader", "ro.bootloader", "unknown", },
667     };
668 
669     for (i = 0; i < ARRAY_SIZE(prop_map); i++) {
670         pval = property_get(prop_map[i].src_prop);
671         property_set(prop_map[i].dest_prop, pval ?: prop_map[i].def_val);
672     }
673 
674     pval = property_get("ro.boot.console");
675     if (pval)
676         strlcpy(console, pval, sizeof(console));
677 
678     /* save a copy for init's usage during boot */
679     strlcpy(bootmode, property_get("ro.bootmode"), sizeof(bootmode));
680 
681     /* if this was given on kernel command line, override what we read
682      * before (e.g. from /proc/cpuinfo), if anything */
683     pval = property_get("ro.boot.hardware");
684     if (pval)
685         strlcpy(hardware, pval, sizeof(hardware));
686     property_set("ro.hardware", hardware);
687 
688     snprintf(tmp, PROP_VALUE_MAX, "%d", revision);
689     property_set("ro.revision", tmp);
690 
691     /* TODO: these are obsolete. We should delete them */
692     if (!strcmp(bootmode,"factory"))
693         property_set("ro.factorytest", "1");
694     else if (!strcmp(bootmode,"factory2"))
695         property_set("ro.factorytest", "2");
696     else
697         property_set("ro.factorytest", "0");
698 }
699 
process_kernel_cmdline(void)700 static void process_kernel_cmdline(void)
701 {
702     /* don't expose the raw commandline to nonpriv processes */
703     chmod("/proc/cmdline", 0440);
704 
705     /* first pass does the common stuff, and finds if we are in qemu.
706      * second pass is only necessary for qemu to export all kernel params
707      * as props.
708      */
709     import_kernel_cmdline(0, import_kernel_nv);
710     if (qemu[0])
711         import_kernel_cmdline(1, import_kernel_nv);
712 
713     /* now propogate the info given on command line to internal variables
714      * used by init as well as the current required properties
715      */
716     export_kernel_boot_props();
717 }
718 
property_service_init_action(int nargs,char ** args)719 static int property_service_init_action(int nargs, char **args)
720 {
721     /* read any property files on system or data and
722      * fire up the property service.  This must happen
723      * after the ro.foo properties are set above so
724      * that /data/local.prop cannot interfere with them.
725      */
726     start_property_service();
727     return 0;
728 }
729 
signal_init_action(int nargs,char ** args)730 static int signal_init_action(int nargs, char **args)
731 {
732     signal_init();
733     return 0;
734 }
735 
check_startup_action(int nargs,char ** args)736 static int check_startup_action(int nargs, char **args)
737 {
738     /* make sure we actually have all the pieces we need */
739     if ((get_property_set_fd() < 0) ||
740         (get_signal_fd() < 0)) {
741         ERROR("init startup failure\n");
742         exit(1);
743     }
744 
745         /* signal that we hit this point */
746     unlink("/dev/.booting");
747 
748     return 0;
749 }
750 
queue_property_triggers_action(int nargs,char ** args)751 static int queue_property_triggers_action(int nargs, char **args)
752 {
753     queue_all_property_triggers();
754     /* enable property triggers */
755     property_triggers_enabled = 1;
756     return 0;
757 }
758 
759 #if BOOTCHART
bootchart_init_action(int nargs,char ** args)760 static int bootchart_init_action(int nargs, char **args)
761 {
762     bootchart_count = bootchart_init();
763     if (bootchart_count < 0) {
764         ERROR("bootcharting init failure\n");
765     } else if (bootchart_count > 0) {
766         NOTICE("bootcharting started (period=%d ms)\n", bootchart_count*BOOTCHART_POLLING_MS);
767     } else {
768         NOTICE("bootcharting ignored\n");
769     }
770 
771     return 0;
772 }
773 #endif
774 
775 #ifdef HAVE_SELINUX
776 static const struct selinux_opt seopts_prop[] = {
777         { SELABEL_OPT_PATH, "/data/system/property_contexts" },
778         { SELABEL_OPT_PATH, "/property_contexts" },
779         { 0, NULL }
780 };
781 
selinux_android_prop_context_handle(void)782 struct selabel_handle* selinux_android_prop_context_handle(void)
783 {
784     int i = 0;
785     struct selabel_handle* sehandle = NULL;
786     while ((sehandle == NULL) && seopts_prop[i].value) {
787         sehandle = selabel_open(SELABEL_CTX_ANDROID_PROP, &seopts_prop[i], 1);
788         i++;
789     }
790 
791     if (!sehandle) {
792         ERROR("SELinux:  Could not load property_contexts:  %s\n",
793               strerror(errno));
794         return NULL;
795     }
796     INFO("SELinux: Loaded property contexts from %s\n", seopts_prop[i - 1].value);
797     return sehandle;
798 }
799 
selinux_init_all_handles(void)800 void selinux_init_all_handles(void)
801 {
802     sehandle = selinux_android_file_context_handle();
803     sehandle_prop = selinux_android_prop_context_handle();
804 }
805 
selinux_reload_policy(void)806 int selinux_reload_policy(void)
807 {
808     if (!selinux_enabled) {
809         return -1;
810     }
811 
812     INFO("SELinux: Attempting to reload policy files\n");
813 
814     if (selinux_android_reload_policy() == -1) {
815         return -1;
816     }
817 
818     if (sehandle)
819         selabel_close(sehandle);
820 
821     if (sehandle_prop)
822         selabel_close(sehandle_prop);
823 
824     selinux_init_all_handles();
825     return 0;
826 }
827 
audit_callback(void * data,security_class_t cls,char * buf,size_t len)828 int audit_callback(void *data, security_class_t cls, char *buf, size_t len)
829 {
830     snprintf(buf, len, "property=%s", !data ? "NULL" : (char *)data);
831     return 0;
832 }
833 
834 #endif
835 
main(int argc,char ** argv)836 int main(int argc, char **argv)
837 {
838     int fd_count = 0;
839     struct pollfd ufds[4];
840     char *tmpdev;
841     char* debuggable;
842     char tmp[32];
843     int property_set_fd_init = 0;
844     int signal_fd_init = 0;
845     int keychord_fd_init = 0;
846     bool is_charger = false;
847 
848     if (!strcmp(basename(argv[0]), "ueventd"))
849         return ueventd_main(argc, argv);
850 
851     if (!strcmp(basename(argv[0]), "watchdogd"))
852         return watchdogd_main(argc, argv);
853 
854     /* clear the umask */
855     umask(0);
856 
857         /* Get the basic filesystem setup we need put
858          * together in the initramdisk on / and then we'll
859          * let the rc file figure out the rest.
860          */
861     mkdir("/dev", 0755);
862     mkdir("/proc", 0755);
863     mkdir("/sys", 0755);
864 
865     mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
866     mkdir("/dev/pts", 0755);
867     mkdir("/dev/socket", 0755);
868     mount("devpts", "/dev/pts", "devpts", 0, NULL);
869     mount("proc", "/proc", "proc", 0, NULL);
870     mount("sysfs", "/sys", "sysfs", 0, NULL);
871 
872         /* indicate that booting is in progress to background fw loaders, etc */
873     close(open("/dev/.booting", O_WRONLY | O_CREAT, 0000));
874 
875         /* We must have some place other than / to create the
876          * device nodes for kmsg and null, otherwise we won't
877          * be able to remount / read-only later on.
878          * Now that tmpfs is mounted on /dev, we can actually
879          * talk to the outside world.
880          */
881     open_devnull_stdio();
882     klog_init();
883     property_init();
884 
885     get_hardware_name(hardware, &revision);
886 
887     process_kernel_cmdline();
888 
889 #ifdef HAVE_SELINUX
890     union selinux_callback cb;
891     cb.func_log = klog_write;
892     selinux_set_callback(SELINUX_CB_LOG, cb);
893 
894     cb.func_audit = audit_callback;
895     selinux_set_callback(SELINUX_CB_AUDIT, cb);
896 
897     INFO("loading selinux policy\n");
898     if (selinux_enabled) {
899         if (selinux_android_load_policy() < 0) {
900             selinux_enabled = 0;
901             INFO("SELinux: Disabled due to failed policy load\n");
902         } else {
903             selinux_init_all_handles();
904         }
905     } else {
906         INFO("SELinux:  Disabled by command line option\n");
907     }
908     /* These directories were necessarily created before initial policy load
909      * and therefore need their security context restored to the proper value.
910      * This must happen before /dev is populated by ueventd.
911      */
912     restorecon("/dev");
913     restorecon("/dev/socket");
914 #endif
915 
916     is_charger = !strcmp(bootmode, "charger");
917 
918     INFO("property init\n");
919     if (!is_charger)
920         property_load_boot_defaults();
921 
922     INFO("reading config file\n");
923     init_parse_config_file("/init.rc");
924 
925     action_for_each_trigger("early-init", action_add_queue_tail);
926 
927     queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done");
928     queue_builtin_action(keychord_init_action, "keychord_init");
929     queue_builtin_action(console_init_action, "console_init");
930 
931     /* execute all the boot actions to get us started */
932     action_for_each_trigger("init", action_add_queue_tail);
933 
934     /* skip mounting filesystems in charger mode */
935     if (!is_charger) {
936         action_for_each_trigger("early-fs", action_add_queue_tail);
937         action_for_each_trigger("fs", action_add_queue_tail);
938         action_for_each_trigger("post-fs", action_add_queue_tail);
939         action_for_each_trigger("post-fs-data", action_add_queue_tail);
940     }
941 
942     queue_builtin_action(property_service_init_action, "property_service_init");
943     queue_builtin_action(signal_init_action, "signal_init");
944     queue_builtin_action(check_startup_action, "check_startup");
945 
946     if (is_charger) {
947         action_for_each_trigger("charger", action_add_queue_tail);
948     } else {
949         action_for_each_trigger("early-boot", action_add_queue_tail);
950         action_for_each_trigger("boot", action_add_queue_tail);
951     }
952 
953         /* run all property triggers based on current state of the properties */
954     queue_builtin_action(queue_property_triggers_action, "queue_property_triggers");
955 
956 
957 #if BOOTCHART
958     queue_builtin_action(bootchart_init_action, "bootchart_init");
959 #endif
960 
961     for(;;) {
962         int nr, i, timeout = -1;
963 
964         execute_one_command();
965         restart_processes();
966 
967         if (!property_set_fd_init && get_property_set_fd() > 0) {
968             ufds[fd_count].fd = get_property_set_fd();
969             ufds[fd_count].events = POLLIN;
970             ufds[fd_count].revents = 0;
971             fd_count++;
972             property_set_fd_init = 1;
973         }
974         if (!signal_fd_init && get_signal_fd() > 0) {
975             ufds[fd_count].fd = get_signal_fd();
976             ufds[fd_count].events = POLLIN;
977             ufds[fd_count].revents = 0;
978             fd_count++;
979             signal_fd_init = 1;
980         }
981         if (!keychord_fd_init && get_keychord_fd() > 0) {
982             ufds[fd_count].fd = get_keychord_fd();
983             ufds[fd_count].events = POLLIN;
984             ufds[fd_count].revents = 0;
985             fd_count++;
986             keychord_fd_init = 1;
987         }
988 
989         if (process_needs_restart) {
990             timeout = (process_needs_restart - gettime()) * 1000;
991             if (timeout < 0)
992                 timeout = 0;
993         }
994 
995         if (!action_queue_empty() || cur_action)
996             timeout = 0;
997 
998 #if BOOTCHART
999         if (bootchart_count > 0) {
1000             if (timeout < 0 || timeout > BOOTCHART_POLLING_MS)
1001                 timeout = BOOTCHART_POLLING_MS;
1002             if (bootchart_step() < 0 || --bootchart_count == 0) {
1003                 bootchart_finish();
1004                 bootchart_count = 0;
1005             }
1006         }
1007 #endif
1008 
1009         nr = poll(ufds, fd_count, timeout);
1010         if (nr <= 0)
1011             continue;
1012 
1013         for (i = 0; i < fd_count; i++) {
1014             if (ufds[i].revents == POLLIN) {
1015                 if (ufds[i].fd == get_property_set_fd())
1016                     handle_property_set_fd();
1017                 else if (ufds[i].fd == get_keychord_fd())
1018                     handle_keychord();
1019                 else if (ufds[i].fd == get_signal_fd())
1020                     handle_signal();
1021             }
1022         }
1023     }
1024 
1025     return 0;
1026 }
1027