static int access_init(sd_bus_error *error) { if (!mac_selinux_use()) return 0; if (initialized) return 1; if (avc_open(NULL, 0) != 0) { int enforce, saved_errno = errno; enforce = security_getenforce(); log_full_errno(enforce != 0 ? LOG_ERR : LOG_WARNING, saved_errno, "Failed to open the SELinux AVC: %m"); /* If enforcement isn't on, then let's suppress this * error, and just don't do any AVC checks. The * warning we printed is hence all the admin will * see. */ if (enforce == 0) return 0; /* Return an access denied error, if we couldn't load * the AVC but enforcing mode was on, or we couldn't * determine whether it is one. */ return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Failed to open the SELinux AVC: %s", strerror(saved_errno)); } selinux_set_callback(SELINUX_CB_AUDIT, (union selinux_callback) audit_callback); selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback) log_callback); initialized = true; return 1; }
int main(int argc, char** argv) { union selinux_callback cb; if (argc == 1) { cb.func_audit = audit_callback; selinux_set_callback(SELINUX_CB_AUDIT, cb); cb.func_log = selinux_log_callback; selinux_set_callback(SELINUX_CB_LOG, cb); return do_server(); } bool dump_backtrace = false; bool have_tid = false; pid_t tid = 0; for (int i = 1; i < argc; i++) { if (!strcmp(argv[i], "-b")) { dump_backtrace = true; } else if (!have_tid) { tid = atoi(argv[i]); have_tid = true; } else { usage(); return 1; } } if (!have_tid) { usage(); return 1; } return do_explicit_dump(tid, dump_backtrace); }
/* Function must be called once to initialize the SELinux AVC environment. Sets up callbacks. If you want to cleanup memory you should need to call selinux_access_finish. */ static int access_init(void) { int r = 0; if (avc_open(NULL, 0)) return log_error_errno(errno, "avc_open() failed: %m"); selinux_set_callback(SELINUX_CB_AUDIT, (union selinux_callback) audit_callback); selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback) log_callback); if (security_getenforce() < 0){ r = -errno; avc_destroy(); } return r; }
int register_android_os_SELinux(JNIEnv *env) { union selinux_callback cb; cb.func_log = log_callback; selinux_set_callback(SELINUX_CB_LOG, cb); isSELinuxDisabled = (is_selinux_enabled() != 1) ? true : false; return RegisterMethodsOrDie(env, "android/os/SELinux", method_table, NELEM(method_table)); }
UINT32 aerofgt_state::screen_update_turbofrc(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { int i, scrolly; m_bg1_tilemap->set_scroll_rows(512); scrolly = m_bg1scrolly + 2; for (i = 0; i < 256; i++) // m_bg1_tilemap->set_scrollx((i + scrolly) & 0x1ff, m_rasterram[i] - 11); m_bg1_tilemap->set_scrollx((i + scrolly) & 0x1ff, m_rasterram[7] - 11);
/* Function must be called once to initialize the SELinux AVC environment. Sets up callbacks. If you want to cleanup memory you should need to call selinux_access_finish. */ static int access_init(void) { int r; if (avc_open(NULL, 0)) { log_error("avc_open() failed: %m"); return -errno; } selinux_set_callback(SELINUX_CB_AUDIT, (union selinux_callback) audit_callback); selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback) log_callback); if (security_getenforce() >= 0) return 0; r = -errno; avc_destroy(); return r; }
int main(int argc, char **argv) { struct binder_state *bs; bs = binder_open(128*1024); if (!bs) { ALOGE("failed to open binder driver\n"); return -1; } if (binder_become_context_manager(bs)) { ALOGE("cannot become context manager (%s)\n", strerror(errno)); return -1; } selinux_enabled = is_selinux_enabled(); sehandle = selinux_android_service_context_handle(); selinux_status_open(true); if (selinux_enabled > 0) { if (sehandle == NULL) { ALOGE("SELinux: Failed to acquire sehandle. Aborting.\n"); abort(); } if (getcon(&service_manager_context) != 0) { ALOGE("SELinux: Failed to acquire service_manager context. Aborting.\n"); abort(); } } union selinux_callback cb; cb.func_audit = audit_callback; selinux_set_callback(SELINUX_CB_AUDIT, cb); cb.func_log = selinux_log_callback; selinux_set_callback(SELINUX_CB_LOG, cb); binder_loop(bs, svcmgr_handler); return 0; }
int register_android_os_SELinux(JNIEnv *env) { #ifdef HAVE_SELINUX union selinux_callback cb; cb.func_log = log_callback; selinux_set_callback(SELINUX_CB_LOG, cb); isSELinuxDisabled = (is_selinux_enabled() != 1) ? true : false; #endif return AndroidRuntime::registerNativeMethods( env, "android/os/SELinux", method_table, NELEM(method_table)); }
bool mselinux_init(selinux_engine_t *se) { union selinux_callback selinux_cb; if (!se->config.selinux) return true; /* * Is the platform support SELinux? */ if (is_selinux_enabled() == 1) { se->info.features[se->info.num_features++].feature = ENGINE_FEATURE_ACCESS_CONTROL; } else { se->config.selinux = false; return true; } /* * Memcached callback */ se->server.callback->register_callback((ENGINE_HANDLE *)se, ON_CONNECT, mselinux_on_connect, se); /* * Set up userspace access vector */ if (avc_init(NULL, NULL, &avc_log_cb, NULL, &avc_lock_cb) < 0) return false; selinux_cb.func_policyload = mavc_cb_policyload; selinux_set_callback(SELINUX_CB_POLICYLOAD, selinux_cb); mavc_cb_policyload(0); if (pthread_create(&se->thread, NULL, mavc_netlink_worker, NULL) != 0) { avc_destroy(); return false; } return true; }
int ueventd_main(int argc, char **argv) { /* * init sets the umask to 077 for forked processes. We need to * create files with exact permissions, without modification by * the umask. */ umask(000); /* Prevent fire-and-forget children from becoming zombies. * If we should need to wait() for some children in the future * (as opposed to none right now), double-forking here instead * of ignoring SIGCHLD may be the better solution. */ signal(SIGCHLD, SIG_IGN); open_devnull_stdio(); klog_init(); klog_set_level(KLOG_NOTICE_LEVEL); NOTICE("ueventd started!\n"); selinux_callback cb; cb.func_log = selinux_klog_callback; selinux_set_callback(SELINUX_CB_LOG, cb); std::string hardware = property_get("ro.hardware"); ueventd_parse_config_file("/ueventd.rc"); ueventd_parse_config_file(android::base::StringPrintf("/ueventd.%s.rc", hardware.c_str()).c_str()); device_init(); pollfd ufd; ufd.events = POLLIN; ufd.fd = get_device_fd(); while (true) { ufd.revents = 0; int nr = poll(&ufd, 1, -1); if (nr <= 0) { continue; } if (ufd.revents & POLLIN) { handle_device_fd(); } } return 0; }
static void selinux_initialize(bool in_kernel_domain) { Timer t; selinux_callback cb; cb.func_log = selinux_klog_callback; selinux_set_callback(SELINUX_CB_LOG, cb); cb.func_audit = audit_callback; selinux_set_callback(SELINUX_CB_AUDIT, cb); if (in_kernel_domain) { INFO("Loading SELinux policy...\n"); if (selinux_android_load_policy() < 0) { ERROR("failed to load policy: %s\n", strerror(errno)); security_failure(); } bool kernel_enforcing = (security_getenforce() == 1); bool is_enforcing = selinux_is_enforcing(); if (kernel_enforcing != is_enforcing) { if (security_setenforce(is_enforcing)) { ERROR("security_setenforce(%s) failed: %s\n", is_enforcing ? "true" : "false", strerror(errno)); security_failure(); } } if (write_file("/sys/fs/selinux/checkreqprot", "0") == -1) { security_failure(); } NOTICE("(Initializing SELinux %s took %.2fs.)\n", is_enforcing ? "enforcing" : "non-enforcing", t.duration()); } else { selinux_init_all_handles(); } }
static int installd_main(const int argc ATTRIBUTE_UNUSED, char *argv[]) { int ret; int selinux_enabled = (is_selinux_enabled() > 0); setenv("ANDROID_LOG_TAGS", "*:v", 1); android::base::InitLogging(argv); SLOGI("installd firing up"); union selinux_callback cb; cb.func_log = log_callback; selinux_set_callback(SELINUX_CB_LOG, cb); if (!initialize_globals()) { SLOGE("Could not initialize globals; exiting.\n"); exit(1); } if (initialize_directories() < 0) { SLOGE("Could not create directories; exiting.\n"); exit(1); } if (selinux_enabled && selinux_status_open(true) < 0) { SLOGE("Could not open selinux status; exiting.\n"); exit(1); } if ((ret = InstalldNativeService::start()) != android::OK) { SLOGE("Unable to start InstalldNativeService: %d", ret); exit(1); } IPCThreadState::self()->joinThreadPool(); LOG(INFO) << "installd shutting down"; return 0; }
int mac_selinux_setup(bool *loaded_policy) { #ifdef HAVE_SELINUX int enforce = 0; usec_t before_load, after_load; security_context_t con; int r; union selinux_callback cb; bool initialized = false; assert(loaded_policy); /* Turn off all of SELinux' own logging, we want to do that */ cb.func_log = null_log; selinux_set_callback(SELINUX_CB_LOG, cb); /* Don't load policy in the initrd if we don't appear to have * it. For the real root, we check below if we've already * loaded policy, and return gracefully. */ if (in_initrd() && access(selinux_path(), F_OK) < 0) return 0; /* Already initialized by somebody else? */ r = getcon_raw(&con); if (r == 0) { initialized = !streq(con, "kernel"); freecon(con); } /* Make sure we have no fds open while loading the policy and * transitioning */ log_close(); /* Now load the policy */ before_load = now(CLOCK_MONOTONIC); r = selinux_init_load_policy(&enforce); if (r == 0) { _cleanup_(mac_selinux_freep) char *label = NULL; char timespan[FORMAT_TIMESPAN_MAX]; mac_selinux_retest(); /* Transition to the new context */ r = mac_selinux_get_create_label_from_exe(SYSTEMD_BINARY_PATH, &label); if (r < 0 || !label) { log_open(); log_error("Failed to compute init label, ignoring."); } else { r = setcon_raw(label); log_open(); if (r < 0) log_error("Failed to transition into init label '%s', ignoring.", label); } after_load = now(CLOCK_MONOTONIC); log_info("Successfully loaded SELinux policy in %s.", format_timespan(timespan, sizeof(timespan), after_load - before_load, 0)); *loaded_policy = true; } else {
int ueventd_main(int argc, char **argv) { struct pollfd ufd; int nr; char tmp[32]; /* * init sets the umask to 077 for forked processes. We need to * create files with exact permissions, without modification by * the umask. */ umask(000); /* Prevent fire-and-forget children from becoming zombies. * If we should need to wait() for some children in the future * (as opposed to none right now), double-forking here instead * of ignoring SIGCHLD may be the better solution. */ signal(SIGCHLD, SIG_IGN); open_devnull_stdio(); klog_init(); #if LOG_UEVENTS /* Ensure we're at a logging level that will show the events */ if (klog_get_level() < KLOG_INFO_LEVEL) { klog_set_level(KLOG_INFO_LEVEL); } #endif union selinux_callback cb; cb.func_log = log_callback; selinux_set_callback(SELINUX_CB_LOG, cb); INFO("starting ueventd\n"); /* Respect hardware passed in through the kernel cmd line. Here we will look * for androidboot.hardware param in kernel cmdline, and save its value in * hardware[]. */ import_kernel_cmdline(0, import_kernel_nv); get_hardware_name(hardware, &revision); ueventd_parse_config_file("/ueventd.rc"); snprintf(tmp, sizeof(tmp), "/ueventd.%s.rc", hardware); ueventd_parse_config_file(tmp); device_init(); ufd.events = POLLIN; ufd.fd = get_device_fd(); while(1) { ufd.revents = 0; nr = poll(&ufd, 1, -1); if (nr <= 0) continue; if (ufd.revents & POLLIN) handle_device_fd(); } }
int main(int argc, char **argv) { struct stat sb; int opt, i = 0; const char *input_filename = NULL; int use_input_file = 0; char *buf = NULL; size_t buf_len; int recurse; /* Recursive descent. */ const char *base; int mass_relabel = 0, errors = 0; const char *ropts = "e:f:hilno:pqrsvFRW0"; const char *sopts = "c:de:f:hilno:pqr:svFR:W0"; const char *opts; memset(&r_opts, 0, sizeof(r_opts)); /* Initialize variables */ r_opts.progress = 0; r_opts.count = 0; r_opts.nfile = 0; r_opts.debug = 0; r_opts.change = 1; r_opts.verbose = 0; r_opts.logging = 0; r_opts.rootpath = NULL; r_opts.rootpathlen = 0; r_opts.outfile = NULL; r_opts.force = 0; r_opts.hard_links = 1; altpath = NULL; r_opts.progname = strdup(argv[0]); if (!r_opts.progname) { fprintf(stderr, "%s: Out of memory!\n", argv[0]); exit(-1); } base = basename(r_opts.progname); if (!strcmp(base, SETFILES)) { /* * setfiles: * Recursive descent, * Does not expand paths via realpath, * Aborts on errors during the file tree walk, * Try to track inode associations for conflict detection, * Does not follow mounts, * Validates all file contexts at init time. */ iamrestorecon = 0; recurse = 1; r_opts.expand_realpath = 0; r_opts.abort_on_error = 1; r_opts.add_assoc = 1; r_opts.fts_flags = FTS_PHYSICAL | FTS_XDEV; ctx_validate = 1; opts = sopts; } else { /* * restorecon: * No recursive descent unless -r/-R, * Expands paths via realpath, * Do not abort on errors during the file tree walk, * Do not try to track inode associations for conflict detection, * Follows mounts, * Does lazy validation of contexts upon use. */ if (strcmp(base, RESTORECON) && !r_opts.quiet) printf("Executed with an unrecognized name (%s), defaulting to %s behavior.\n", base, RESTORECON); iamrestorecon = 1; recurse = 0; r_opts.expand_realpath = 1; r_opts.abort_on_error = 0; r_opts.add_assoc = 0; r_opts.fts_flags = FTS_PHYSICAL; ctx_validate = 0; opts = ropts; /* restorecon only: silent exit if no SELinux. Allows unconditional execution by scripts. */ if (is_selinux_enabled() <= 0) exit(0); } /* This must happen before getopt. */ r_opts.nfile = exclude_non_seclabel_mounts(); if (iamrestorecon) opts = ropts; else opts = sopts; /* Process any options. */ while ((opt = getopt(argc, argv, opts)) > 0) { switch (opt) { case 'c': { FILE *policystream; if (iamrestorecon) usage(argv[0]); policyfile = optarg; policystream = fopen(policyfile, "r"); if (!policystream) { fprintf(stderr, "Error opening %s: %s\n", policyfile, strerror(errno)); exit(-1); } __fsetlocking(policystream, FSETLOCKING_BYCALLER); if (sepol_set_policydb_from_file(policystream) < 0) { fprintf(stderr, "Error reading policy %s: %s\n", policyfile, strerror(errno)); exit(-1); } fclose(policystream); ctx_validate = 1; break; } case 'e': remove_exclude(optarg); if (lstat(optarg, &sb) < 0 && errno != EACCES) { fprintf(stderr, "Can't stat exclude path \"%s\", %s - ignoring.\n", optarg, strerror(errno)); break; } if (add_exclude(optarg)) exit(-1); break; case 'f': use_input_file = 1; input_filename = optarg; break; case 'd': if (iamrestorecon) usage(argv[0]); r_opts.debug = 1; break; case 'i': r_opts.ignore_enoent = 1; break; case 'l': r_opts.logging = 1; break; case 'F': r_opts.force = 1; break; case 'n': r_opts.change = 0; break; case 'o': if (strcmp(optarg, "-") == 0) { r_opts.outfile = stdout; break; } r_opts.outfile = fopen(optarg, "w"); if (!r_opts.outfile) { fprintf(stderr, "Error opening %s: %s\n", optarg, strerror(errno)); usage(argv[0]); } __fsetlocking(r_opts.outfile, FSETLOCKING_BYCALLER); break; case 'q': r_opts.quiet = 1; break; case 'R': case 'r': if (iamrestorecon) { recurse = 1; break; } if (NULL != r_opts.rootpath) { fprintf(stderr, "%s: only one -r can be specified\n", argv[0]); exit(-1); } set_rootpath(optarg); break; case 's': use_input_file = 1; input_filename = "-"; r_opts.add_assoc = 0; break; case 'v': if (r_opts.progress) { fprintf(stderr, "Progress and Verbose mutually exclusive\n"); usage(argv[0]); } r_opts.verbose++; break; case 'p': if (r_opts.verbose) { fprintf(stderr, "Progress and Verbose mutually exclusive\n"); usage(argv[0]); } r_opts.progress++; break; case 'W': warn_no_match = 1; break; case '0': null_terminated = 1; break; case 'h': case '?': usage(argv[0]); } } for (i = optind; i < argc; i++) { if (!strcmp(argv[i], "/")) { mass_relabel = 1; if (r_opts.progress) r_opts.progress++; } } if (!iamrestorecon) { if (policyfile) { if (optind != (argc - 1)) usage(argv[0]); } else if (use_input_file) { if (optind != (argc - 1)) { /* Cannot mix with pathname arguments. */ usage(argv[0]); } } else { if (optind > (argc - 2)) usage(argv[0]); } /* Use our own invalid context checking function so that we can support either checking against the active policy or checking against a binary policy file. */ selinux_set_callback(SELINUX_CB_VALIDATE, (union selinux_callback)&canoncon); if (stat(argv[optind], &sb) < 0) { perror(argv[optind]); exit(-1); } if (!S_ISREG(sb.st_mode)) { fprintf(stderr, "%s: spec file %s is not a regular file.\n", argv[0], argv[optind]); exit(-1); } altpath = argv[optind]; optind++; } else if (argc == 1) usage(argv[0]); /* Load the file contexts configuration and check it. */ r_opts.selabel_opt_validate = (ctx_validate ? (char *)1 : NULL); r_opts.selabel_opt_path = altpath; if (nerr) exit(-1); restore_init(&r_opts); if (use_input_file) { FILE *f = stdin; ssize_t len; int delim; if (strcmp(input_filename, "-") != 0) f = fopen(input_filename, "r"); if (f == NULL) { fprintf(stderr, "Unable to open %s: %s\n", input_filename, strerror(errno)); usage(argv[0]); } __fsetlocking(f, FSETLOCKING_BYCALLER); delim = (null_terminated != 0) ? '\0' : '\n'; while ((len = getdelim(&buf, &buf_len, delim, f)) > 0) { buf[len - 1] = 0; if (!strcmp(buf, "/")) mass_relabel = 1; errors |= process_glob(buf, recurse) < 0; } if (strcmp(input_filename, "-") != 0) fclose(f); } else { for (i = optind; i < argc; i++) errors |= process_glob(argv[i], recurse) < 0; } maybe_audit_mass_relabel(mass_relabel, errors); if (warn_no_match) selabel_stats(r_opts.hnd); selabel_close(r_opts.hnd); restore_finish(); if (r_opts.outfile) fclose(r_opts.outfile); if (r_opts.progress && r_opts.count >= STAR_COUNT) printf("\n"); exit(errors ? -1: 0); }
int main(int argc, char *argv[]) { const char *path = NULL; const char *out_file = NULL; char stack_path[PATH_MAX + 1]; char *tmp = NULL; int fd, rc, opt; FILE *policy_fp = NULL; struct stat buf; struct selabel_handle *rec = NULL; struct saved_data *data = NULL; if (argc < 2) usage(argv[0]); while ((opt = getopt(argc, argv, "o:p:")) > 0) { switch (opt) { case 'o': out_file = optarg; break; case 'p': policy_file = optarg; break; default: usage(argv[0]); } } if (optind >= argc) usage(argv[0]); path = argv[optind]; if (stat(path, &buf) < 0) { fprintf(stderr, "Can not stat: %s: %m\n", path); exit(EXIT_FAILURE); } /* Open binary policy if supplied. */ if (policy_file) { policy_fp = fopen(policy_file, "r"); if (!policy_fp) { fprintf(stderr, "Failed to open policy: %s\n", policy_file); exit(EXIT_FAILURE); } if (sepol_set_policydb_from_file(policy_fp) < 0) { fprintf(stderr, "Failed to load policy: %s\n", policy_file); fclose(policy_fp); exit(EXIT_FAILURE); } } /* Generate dummy handle for process_line() function */ rec = (struct selabel_handle *)calloc(1, sizeof(*rec)); if (!rec) { fprintf(stderr, "Failed to calloc handle\n"); if (policy_fp) fclose(policy_fp); exit(EXIT_FAILURE); } rec->backend = SELABEL_CTX_FILE; /* Need to set validation on to get the bin file generated by the * process_line function, however as the bin file being generated * may not be related to the currently loaded policy (that it * would be validated against), then set callback to ignore any * validation - unless the -p option is used in which case if an * error is detected, the process will be aborted. */ rec->validating = 1; selinux_set_callback(SELINUX_CB_VALIDATE, (union selinux_callback)&validate_context); data = (struct saved_data *)calloc(1, sizeof(*data)); if (!data) { fprintf(stderr, "Failed to calloc saved_data\n"); free(rec); if (policy_fp) fclose(policy_fp); exit(EXIT_FAILURE); } rec->data = data; rc = process_file(rec, path); if (rc < 0) goto err; rc = sort_specs(data); if (rc) goto err; if (out_file) rc = snprintf(stack_path, sizeof(stack_path), "%s", out_file); else rc = snprintf(stack_path, sizeof(stack_path), "%s.bin", path); if (rc < 0 || rc >= (int)sizeof(stack_path)) goto err; tmp = malloc(strlen(stack_path) + 7); if (!tmp) goto err; rc = sprintf(tmp, "%sXXXXXX", stack_path); if (rc < 0) goto err; fd = mkstemp(tmp); if (fd < 0) goto err; rc = fchmod(fd, buf.st_mode); if (rc < 0) { perror("fchmod failed to set permission on compiled regexs"); goto err_unlink; } rc = write_binary_file(data, fd); if (rc < 0) goto err_unlink; rc = rename(tmp, stack_path); if (rc < 0) goto err_unlink; rc = 0; out: if (policy_fp) fclose(policy_fp); free_specs(data); free(rec); free(data); free(tmp); return rc; err_unlink: unlink(tmp); err: rc = -1; goto out; }
int main(int argc, char **argv) { int fd_count = 0; struct pollfd ufds[4]; char *tmpdev; char* debuggable; char tmp[32]; int property_set_fd_init = 0; int signal_fd_init = 0; int keychord_fd_init = 0; bool is_charger = false; klog_set_level(LOG_DEFAULT_LEVEL); if (!strcmp(basename(argv[0]), "ueventd")) return ueventd_main(argc, argv); if (!strcmp(basename(argv[0]), "watchdogd")) return watchdogd_main(argc, argv); /* clear the umask */ umask(0); /* Get the basic filesystem setup we need put * together in the initramdisk on / and then we'll * let the rc file figure out the rest. */ mkdir("/dev", 0755); mkdir("/proc", 0755); mkdir("/sys", 0755); mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"); mkdir("/dev/pts", 0755); mkdir("/dev/socket", 0755); mount("devpts", "/dev/pts", "devpts", 0, NULL); mount("proc", "/proc", "proc", 0, NULL); mount("sysfs", "/sys", "sysfs", 0, NULL); #ifdef INIT_ENG_BUILD mount("debugfs", "/sys/kernel/debug", "debugfs", 0, NULL); #endif /* indicate that booting is in progress to background fw loaders, etc */ close(open("/dev/.booting", O_WRONLY | O_CREAT, 0000)); /* We must have some place other than / to create the * device nodes for kmsg and null, otherwise we won't * be able to remount / read-only later on. * Now that tmpfs is mounted on /dev, we can actually * talk to the outside world. */ //open_devnull_stdio(); klog_init(); property_init(); get_hardware_name(hardware, &revision); process_kernel_cmdline(); #ifdef HAVE_SELINUX union selinux_callback cb; cb.func_log = klog_write; selinux_set_callback(SELINUX_CB_LOG, cb); cb.func_audit = audit_callback; selinux_set_callback(SELINUX_CB_AUDIT, cb); INFO("loading selinux policy\n"); if (selinux_enabled) { if (selinux_android_load_policy() < 0) { selinux_enabled = 0; INFO("SELinux: Disabled due to failed policy load\n"); } else { selinux_init_all_handles(); } } else { INFO("SELinux: Disabled by command line option\n"); } /* These directories were necessarily created before initial policy load * and therefore need their security context restored to the proper value. * This must happen before /dev is populated by ueventd. */ restorecon("/dev"); restorecon("/dev/socket"); #endif is_charger = !strcmp(bootmode, "charger"); INFO("property init\n"); if (!is_charger) property_load_boot_defaults(); #ifdef HAVE_AEE_FEATURE INFO("reading AEE config file\n"); #ifndef PARTIAL_BUILD init_parse_config_file("/init.aee.mtk.rc"); #else init_parse_config_file("/init.aee.customer.rc"); #endif // PARTIAL_BUILD #endif // HAVE_AEE_FEATURE INFO("reading config file\n"); #ifdef USE_BUILT_IN_FACTORY ERROR("USE_BUILT_IN_FACTORY"); if (is_factory_boot()) { ERROR("This is factory boot"); property_set("sys.mtk.no.factoryimage","1"); init_parse_config_file("/factory_init.rc"); INFO("reading project config file\n"); init_parse_config_file("/factory_init.project.rc"); } else { if(is_meta_boot()) { ERROR("Parsing meta_init.rc ...\n"); init_parse_config_file("/meta_init.rc"); INFO("reading project config file\n"); init_parse_config_file("/meta_init.project.rc"); init_parse_config_file("/meta_init.modem.rc"); } else if(is_advanced_meta_boot()) { ERROR("Parsing advanced_meta_init.rc ...\n"); init_parse_config_file("/advanced_meta_init.rc"); INFO("reading project config file\n"); init_parse_config_file("/advanced_meta_init.project.rc"); #ifdef MTK_FAT_ON_NAND printf("reading init.fon.rc file\n"); init_parse_config_file("/init.fon.rc"); #endif } #if defined (MTK_KERNEL_POWER_OFF_CHARGING_SUPPORT) else if (is_kernel_power_off_charging_boot()) { ERROR("Parsing init.charging.rc ...\n"); if (init_parse_config_file("/init.charging.rc") < 0) { init_parse_config_file("/init.rc"); INFO("reading project config file\n"); init_parse_config_file("/init.project.rc"); init_parse_config_file("/init.modem.rc"); } } #endif else { printf("Parsing init.rc ...\n"); init_parse_config_file("/init.rc"); INFO("reading project config file\n"); init_parse_config_file("/init.project.rc"); init_parse_config_file("/init.modem.rc"); #ifdef MTK_FAT_ON_NAND printf("reading init.fon.rc file\n"); init_parse_config_file("/init.fon.rc"); #endif } } #else if(is_meta_boot()) { ERROR("Parsing meta_init.rc ...\n"); init_parse_config_file("/meta_init.rc"); INFO("reading project config file\n"); init_parse_config_file("/meta_init.project.rc"); init_parse_config_file("/meta_init.modem.rc"); } else if(is_advanced_meta_boot()) { ERROR("Parsing advanced_meta_init.rc ...\n"); init_parse_config_file("/advanced_meta_init.rc"); INFO("reading project config file\n"); init_parse_config_file("/advanced_meta_init.project.rc"); } else { printf("Parsing init.rc ...\n"); init_parse_config_file("/init.rc"); INFO("reading project config file\n"); init_parse_config_file("/init.project.rc"); init_parse_config_file("/init.modem.rc"); } #endif #ifdef MTK_SHARED_SDCARD if(is_support_sdcard_share_boot()) { #ifdef MTK_2SDCARD_SWAP printf("Parsing init.ssd_sdswap.rc ...\n"); init_parse_config_file("/init.ssd_nomuser.rc"); #else printf("Parsing init.ssd.rc ...\n"); init_parse_config_file("/init.ssd.rc"); #endif } else { printf("Parsing init.no_ssd.rc ...\n"); init_parse_config_file("/init.no_ssd.rc"); } #else printf("Parsing init.no_ssd.rc ...\n"); init_parse_config_file("/init.no_ssd.rc"); #endif #ifndef INIT_ENG_BUILD property_set("ro.mtprof.disable", "1"); #endif if(is_support_protected_data_boot()) { printf("Parsing init.protect.rc ...\n"); init_parse_config_file("/init.protect.rc"); } snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware); init_parse_config_file(tmp); action_for_each_trigger("early-init", action_add_queue_tail); queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done"); queue_builtin_action(keychord_init_action, "keychord_init"); queue_builtin_action(console_init_action, "console_init"); /* execute all the boot actions to get us started */ action_for_each_trigger("init", action_add_queue_tail); /* skip mounting filesystems in charger mode */ if (!is_charger) { queue_builtin_action(queue_fs_property_triggers_action, "queue_fs_propety_triggers"); action_for_each_trigger("early-fs", action_add_queue_tail); action_for_each_trigger("fs", action_add_queue_tail); action_for_each_trigger("post-fs", action_add_queue_tail); action_for_each_trigger("post-fs-data", action_add_queue_tail); } queue_builtin_action(property_service_init_action, "property_service_init"); queue_builtin_action(signal_init_action, "signal_init"); queue_builtin_action(check_startup_action, "check_startup"); queue_builtin_action(queue_early_property_triggers_action, "queue_early_propety_triggers"); if (is_charger) { action_for_each_trigger("charger", action_add_queue_tail); } #if defined (MTK_KERNEL_POWER_OFF_CHARGING_SUPPORT) else if (is_kernel_power_off_charging_boot()){ action_for_each_trigger("ipo", action_add_queue_tail); } #endif else { action_for_each_trigger("early-boot", action_add_queue_tail); action_for_each_trigger("boot", action_add_queue_tail); } /* run all property triggers based on current state of the properties */ queue_builtin_action(queue_property_triggers_action, "queue_property_triggers"); /* change USB function by meta_com_id */ #ifdef USE_BUILT_IN_FACTORY if (is_meta_boot() || is_factory_boot()) { queue_builtin_action(queue_com_triggers_action, "queue_com_triggers"); } #else if (is_meta_boot()) { queue_builtin_action(queue_com_triggers_action, "queue_com_triggers"); } #endif #if BOOTCHART queue_builtin_action(bootchart_init_action, "bootchart_init"); #endif for(;;) { int nr, i, timeout = -1; execute_one_command(); restart_processes(); if (!property_set_fd_init && get_property_set_fd() > 0) { ufds[fd_count].fd = get_property_set_fd(); ufds[fd_count].events = POLLIN; ufds[fd_count].revents = 0; fd_count++; property_set_fd_init = 1; } if (!signal_fd_init && get_signal_fd() > 0) { ufds[fd_count].fd = get_signal_fd(); ufds[fd_count].events = POLLIN; ufds[fd_count].revents = 0; fd_count++; signal_fd_init = 1; } if (!keychord_fd_init && get_keychord_fd() > 0) { ufds[fd_count].fd = get_keychord_fd(); ufds[fd_count].events = POLLIN; ufds[fd_count].revents = 0; fd_count++; keychord_fd_init = 1; } if (process_needs_restart) { timeout = (process_needs_restart - gettime()) * 1000; if (timeout < 0) timeout = 0; } if (!action_queue_empty() || cur_action) timeout = 0; #if BOOTCHART if (bootchart_count > 0) { if (timeout < 0 || timeout > BOOTCHART_POLLING_MS) timeout = BOOTCHART_POLLING_MS; if (bootchart_step() < 0 || --bootchart_count == 0) { bootchart_finish(); bootchart_count = 0; } } #endif nr = poll(ufds, fd_count, timeout); if (nr <= 0) continue; for (i = 0; i < fd_count; i++) { if (ufds[i].revents == POLLIN) { if (ufds[i].fd == get_property_set_fd()) handle_property_set_fd(); else if (ufds[i].fd == get_keychord_fd()) handle_keychord(); else if (ufds[i].fd == get_signal_fd()) handle_signal(); } } } return 0; }
int main(int argc, char **argv) { int fd_count = 0; struct pollfd ufds[4]; int property_set_fd_init = 0; int signal_fd_init = 0; int keychord_fd_init = 0; bool is_charger = false; if (!strcmp(basename(argv[0]), "ueventd")) return ueventd_main(argc, argv); if (!strcmp(basename(argv[0]), "watchdogd")) return watchdogd_main(argc, argv); /* clear the umask */ umask(0); /* Get the basic filesystem setup we need put * together in the initramdisk on / and then we'll * let the rc file figure out the rest. */ mkdir("/dev", 0755); mkdir("/proc", 0755); mkdir("/sys", 0755); mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"); mkdir("/dev/pts", 0755); mkdir("/dev/socket", 0755); mount("devpts", "/dev/pts", "devpts", 0, NULL); mount("proc", "/proc", "proc", 0, NULL); mount("sysfs", "/sys", "sysfs", 0, NULL); /* indicate that booting is in progress to background fw loaders, etc */ close(open("/dev/.booting", O_WRONLY | O_CREAT, 0000)); /* We must have some place other than / to create the * device nodes for kmsg and null, otherwise we won't * be able to remount / read-only later on. * Now that tmpfs is mounted on /dev, we can actually * talk to the outside world. */ open_devnull_stdio(); klog_init(); property_init(); get_hardware_name(hardware, &revision); process_kernel_cmdline(); union selinux_callback cb; cb.func_log = log_callback; selinux_set_callback(SELINUX_CB_LOG, cb); cb.func_audit = audit_callback; selinux_set_callback(SELINUX_CB_AUDIT, cb); selinux_initialize(); /* These directories were necessarily created before initial policy load * and therefore need their security context restored to the proper value. * This must happen before /dev is populated by ueventd. */ restorecon("/dev"); restorecon("/dev/socket"); restorecon("/dev/__properties__"); restorecon_recursive("/sys"); is_charger = !strcmp(bootmode, "charger"); INFO("property init\n"); property_load_boot_defaults(); INFO("reading config file\n"); init_parse_config_file("/init.rc"); action_for_each_trigger("early-init", action_add_queue_tail); queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done"); queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng"); queue_builtin_action(keychord_init_action, "keychord_init"); queue_builtin_action(console_init_action, "console_init"); /* execute all the boot actions to get us started */ action_for_each_trigger("init", action_add_queue_tail); /* Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random * wasn't ready immediately after wait_for_coldboot_done */ queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng"); queue_builtin_action(property_service_init_action, "property_service_init"); queue_builtin_action(signal_init_action, "signal_init"); /* Don't mount filesystems or start core system services if in charger mode. */ if (is_charger) { action_for_each_trigger("charger", action_add_queue_tail); } else { action_for_each_trigger("late-init", action_add_queue_tail); } /* run all property triggers based on current state of the properties */ queue_builtin_action(queue_property_triggers_action, "queue_property_triggers"); #if BOOTCHART queue_builtin_action(bootchart_init_action, "bootchart_init"); #endif for(;;) { int nr, i, timeout = -1; execute_one_command(); restart_processes(); if (!property_set_fd_init && get_property_set_fd() > 0) { ufds[fd_count].fd = get_property_set_fd(); ufds[fd_count].events = POLLIN; ufds[fd_count].revents = 0; fd_count++; property_set_fd_init = 1; } if (!signal_fd_init && get_signal_fd() > 0) { ufds[fd_count].fd = get_signal_fd(); ufds[fd_count].events = POLLIN; ufds[fd_count].revents = 0; fd_count++; signal_fd_init = 1; } if (!keychord_fd_init && get_keychord_fd() > 0) { ufds[fd_count].fd = get_keychord_fd(); ufds[fd_count].events = POLLIN; ufds[fd_count].revents = 0; fd_count++; keychord_fd_init = 1; } if (process_needs_restart) { timeout = (process_needs_restart - gettime()) * 1000; if (timeout < 0) timeout = 0; } if (!action_queue_empty() || cur_action) timeout = 0; #if BOOTCHART if (bootchart_count > 0) { long long current_time; int elapsed_time, remaining_time; current_time = bootchart_gettime(); elapsed_time = current_time - bootchart_time; if (elapsed_time >= BOOTCHART_POLLING_MS) { /* count missed samples */ while (elapsed_time >= BOOTCHART_POLLING_MS) { elapsed_time -= BOOTCHART_POLLING_MS; bootchart_count--; } /* count may be negative, take a sample anyway */ bootchart_time = current_time; if (bootchart_step() < 0 || bootchart_count <= 0) { bootchart_finish(); bootchart_count = 0; } } if (bootchart_count > 0) { remaining_time = BOOTCHART_POLLING_MS - elapsed_time; if (timeout < 0 || timeout > remaining_time) timeout = remaining_time; } } #endif nr = poll(ufds, fd_count, timeout); if (nr <= 0) continue; for (i = 0; i < fd_count; i++) { if (ufds[i].revents & POLLIN) { if (ufds[i].fd == get_property_set_fd()) handle_property_set_fd(); else if (ufds[i].fd == get_keychord_fd()) handle_keychord(); else if (ufds[i].fd == get_signal_fd()) handle_signal(); } } } return 0; }
/* * selinux_status_open * * It tries to open and mmap kernel status page (/selinux/status). * Since Linux 2.6.37 or later supports this feature, we may run * fallback routine using a netlink socket on older kernels, if * the supplied `fallback' is not zero. * It returns 0 on success, or -1 on error. */ int selinux_status_open(int fallback) { int fd; char path[PATH_MAX]; long pagesize; if (!selinux_mnt) { errno = ENOENT; return -1; } pagesize = sysconf(_SC_PAGESIZE); if (pagesize < 0) return -1; snprintf(path, sizeof(path), "%s/status", selinux_mnt); fd = open(path, O_RDONLY | O_CLOEXEC); if (fd < 0) goto error; selinux_status = mmap(NULL, pagesize, PROT_READ, MAP_SHARED, fd, 0); if (selinux_status == MAP_FAILED) { close(fd); goto error; } selinux_status_fd = fd; last_seqno = (uint32_t)(-1); return 0; error: /* * If caller wants fallback routine, we try to provide * an equivalent functionality using existing netlink * socket, although it needs system call invocation to * receive event notification. */ if (fallback && avc_netlink_open(0) == 0) { union selinux_callback cb; /* register my callbacks */ cb.func_setenforce = fallback_cb_setenforce; selinux_set_callback(SELINUX_CB_SETENFORCE, cb); cb.func_policyload = fallback_cb_policyload; selinux_set_callback(SELINUX_CB_POLICYLOAD, cb); /* mark as fallback mode */ selinux_status = MAP_FAILED; selinux_status_fd = avc_netlink_acquire_fd(); last_seqno = (uint32_t)(-1); fallback_sequence = 0; fallback_enforcing = security_getenforce(); fallback_policyload = 0; return 1; } selinux_status = NULL; return -1; }
int main(int argc, char **argv) { struct selinux_opt opts[] = { { SELABEL_OPT_VALIDATE, (void*)1 }, { SELABEL_OPT_PATH, NULL } }; // Default backend unless changed by input argument. unsigned int backend = SELABEL_CTX_FILE; FILE *fp; struct selabel_handle *sehnd; char c; while ((c = getopt(argc, argv, "ph")) != -1) { switch (c) { case 'p': backend = SELABEL_CTX_ANDROID_PROP; break; case 'h': default: usage(argv[0]); break; } } int index = optind; if (argc - optind != 2) { fprintf(stderr, "Expected sepolicy file and context file as arguments.\n"); usage(argv[0]); } // remaining args are sepolicy file and context file char *sepolicyFile = argv[index]; char *contextFile = argv[index + 1]; fp = fopen(sepolicyFile, "r"); if (!fp) { perror(sepolicyFile); exit(2); } if (sepol_set_policydb_from_file(fp) < 0) { fprintf(stderr, "Error loading policy from %s\n", sepolicyFile); exit(3); } selinux_set_callback(SELINUX_CB_VALIDATE, (union selinux_callback)&validate); opts[1].value = contextFile; sehnd = selabel_open(backend, opts, 2); if (!sehnd) { fprintf(stderr, "Error loading context file from %s\n", contextFile); exit(4); } if (nerr) { fprintf(stderr, "Invalid context file found in %s\n", contextFile); exit(5); } exit(0); }
static void do_fc_check_and_die_on_error(struct selinux_opt opts[], unsigned int backend, filemode mode, const char *sepolicy_file, const char *context_file, bool allow_empty) { struct stat sb; if (stat(context_file, &sb) < 0) { perror("Error: could not get stat on file contexts file"); exit(1); } if (sb.st_size == 0) { /* Nothing to check on empty file_contexts file if allowed*/ if (allow_empty) { return; } /* else: We could throw the error here, but libselinux backend will catch it */ } global_state.sepolicy.file = fopen(sepolicy_file, "r"); if (!global_state.sepolicy.file) { perror("Error: could not open policy file"); exit(1); } global_state.sepolicy.handle = sepol_handle_create(); if (!global_state.sepolicy.handle) { fprintf(stderr, "Error: could not create policy handle: %s\n", strerror(errno)); exit(1); } if (sepol_policy_file_create(&global_state.sepolicy.pf) < 0) { perror("Error: could not create policy handle"); exit(1); } sepol_policy_file_set_fp(global_state.sepolicy.pf, global_state.sepolicy.file); sepol_policy_file_set_handle(global_state.sepolicy.pf, global_state.sepolicy.handle); int rc = sepol_policydb_create(&global_state.sepolicy.sdb); if (rc < 0) { perror("Error: could not create policy db"); exit(1); } rc = sepol_policydb_read(global_state.sepolicy.sdb, global_state.sepolicy.pf); if (rc < 0) { perror("Error: could not read file into policy db"); exit(1); } global_state.assert.attrs = filemode_to_assert_attrs(mode); bool ret = ebitmap_attribute_assertion_init(&global_state.assert.set, global_state.assert.attrs); if (!ret) { /* error messages logged by ebitmap_attribute_assertion_init() */ exit(1); } selinux_set_callback(SELINUX_CB_VALIDATE, (union selinux_callback)&validate); opts[1].value = context_file; global_state.sepolicy.sehnd[0] = selabel_open(backend, opts, 2); if (!global_state.sepolicy.sehnd[0]) { fprintf(stderr, "Error: could not load context file from %s\n", context_file); exit(1); } }
int main(int argc, char **argv) { int fd_count = 0; struct pollfd ufds[4]; char *tmpdev; char* debuggable; char tmp[32]; int property_set_fd_init = 0; int signal_fd_init = 0; int keychord_fd_init = 0; bool is_charger = false; if (!strcmp(basename(argv[0]), "ueventd")) return ueventd_main(argc, argv); if (!strcmp(basename(argv[0]), "watchdogd")) return watchdogd_main(argc, argv); /* clear the umask */ umask(0); /* Get the basic filesystem setup we need put * together in the initramdisk on / and then we'll * let the rc file figure out the rest. */ mkdir("/dev", 0755); mkdir("/proc", 0755); mkdir("/sys", 0755); mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"); mkdir("/dev/pts", 0755); mkdir("/dev/socket", 0755); mount("devpts", "/dev/pts", "devpts", 0, NULL); mount("proc", "/proc", "proc", 0, NULL); mount("sysfs", "/sys", "sysfs", 0, NULL); /* indicate that booting is in progress to background fw loaders, etc */ close(open("/dev/.booting", O_WRONLY | O_CREAT, 0000)); /* We must have some place other than / to create the * device nodes for kmsg and null, otherwise we won't * be able to remount / read-only later on. * Now that tmpfs is mounted on /dev, we can actually * talk to the outside world. */ open_devnull_stdio(); klog_init(); property_init(); get_hardware_name(hardware, &revision); process_kernel_cmdline(); #ifdef HAVE_SELINUX union selinux_callback cb; cb.func_log = klog_write; selinux_set_callback(SELINUX_CB_LOG, cb); cb.func_audit = audit_callback; selinux_set_callback(SELINUX_CB_AUDIT, cb); INFO("loading selinux policy\n"); if (selinux_enabled) { if (selinux_android_load_policy() < 0) { selinux_enabled = 0; INFO("SELinux: Disabled due to failed policy load\n"); } else { selinux_init_all_handles(); } } else { INFO("SELinux: Disabled by command line option\n"); } /* These directories were necessarily created before initial policy load * and therefore need their security context restored to the proper value. * This must happen before /dev is populated by ueventd. */ restorecon("/dev"); restorecon("/dev/socket"); #endif is_charger = !strcmp(bootmode, "charger"); INFO("property init\n"); if (!is_charger) property_load_boot_defaults(); INFO("reading config file\n"); init_parse_config_file("/init.rc"); action_for_each_trigger("early-init", action_add_queue_tail); queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done"); queue_builtin_action(keychord_init_action, "keychord_init"); //queue_builtin_action(console_init_action, "console_init"); /* execute all the boot actions to get us started */ action_for_each_trigger("init", action_add_queue_tail); /* skip mounting filesystems in charger mode */ if (!is_charger) { action_for_each_trigger("early-fs", action_add_queue_tail); queue_builtin_action(console_init_action, "console_init"); action_for_each_trigger("fs", action_add_queue_tail); action_for_each_trigger("post-fs", action_add_queue_tail); action_for_each_trigger("post-fs-data", action_add_queue_tail); } queue_builtin_action(property_service_init_action, "property_service_init"); queue_builtin_action(signal_init_action, "signal_init"); queue_builtin_action(check_startup_action, "check_startup"); if (is_charger) { action_for_each_trigger("charger", action_add_queue_tail); } else { action_for_each_trigger("early-boot", action_add_queue_tail); action_for_each_trigger("boot", action_add_queue_tail); } /* run all property triggers based on current state of the properties */ queue_builtin_action(queue_property_triggers_action, "queue_property_triggers"); #if BOOTCHART queue_builtin_action(bootchart_init_action, "bootchart_init"); #endif for(;;) { int nr, i, timeout = -1; execute_one_command(); restart_processes(); if (!property_set_fd_init && get_property_set_fd() > 0) { ufds[fd_count].fd = get_property_set_fd(); ufds[fd_count].events = POLLIN; ufds[fd_count].revents = 0; fd_count++; property_set_fd_init = 1; } if (!signal_fd_init && get_signal_fd() > 0) { ufds[fd_count].fd = get_signal_fd(); ufds[fd_count].events = POLLIN; ufds[fd_count].revents = 0; fd_count++; signal_fd_init = 1; } if (!keychord_fd_init && get_keychord_fd() > 0) { ufds[fd_count].fd = get_keychord_fd(); ufds[fd_count].events = POLLIN; ufds[fd_count].revents = 0; fd_count++; keychord_fd_init = 1; } if (process_needs_restart) { timeout = (process_needs_restart - gettime()) * 1000; if (timeout < 0) timeout = 0; } if (!action_queue_empty() || cur_action) timeout = 0; #if BOOTCHART if (bootchart_count > 0) { if (timeout < 0 || timeout > BOOTCHART_POLLING_MS) timeout = BOOTCHART_POLLING_MS; if (bootchart_step() < 0 || --bootchart_count == 0) { bootchart_finish(); bootchart_count = 0; } } #endif nr = poll(ufds, fd_count, timeout); if (nr <= 0) continue; for (i = 0; i < fd_count; i++) { if (ufds[i].revents == POLLIN) { if (ufds[i].fd == get_property_set_fd()) handle_property_set_fd(); else if (ufds[i].fd == get_keychord_fd()) handle_keychord(); else if (ufds[i].fd == get_signal_fd()) handle_signal(); } } } return 0; }
int selinux_setup(bool *loaded_policy) { #ifdef HAVE_SELINUX int enforce = 0; usec_t before_load, after_load; security_context_t con; int r; union selinux_callback cb; assert(loaded_policy); /* Turn off all of SELinux' own logging, we want to do that */ cb.func_log = null_log; selinux_set_callback(SELINUX_CB_LOG, cb); /* Already initialized by somebody else? */ r = getcon_raw(&con); if (r == 0) { bool initialized; initialized = !streq(con, "kernel"); freecon(con); if (initialized) return 0; } /* Make sure we have no fds open while loading the policy and * transitioning */ log_close(); /* Now load the policy */ before_load = now(CLOCK_MONOTONIC); r = selinux_init_load_policy(&enforce); if (r == 0) { char timespan[FORMAT_TIMESPAN_MAX]; char *label; retest_selinux(); /* Transition to the new context */ r = label_get_create_label_from_exe(SYSTEMD_BINARY_PATH, &label); if (r < 0 || label == NULL) { log_open(); log_error("Failed to compute init label, ignoring."); } else { r = setcon(label); log_open(); if (r < 0) log_error("Failed to transition into init label '%s', ignoring.", label); label_free(label); } after_load = now(CLOCK_MONOTONIC); log_info("Successfully loaded SELinux policy in %s.", format_timespan(timespan, sizeof(timespan), after_load - before_load)); *loaded_policy = true; } else { log_open(); if (enforce > 0) { log_error("Failed to load SELinux policy. Freezing."); return -EIO; } else log_debug("Unable to load SELinux policy. Ignoring."); } #endif return 0; }
int main(int argc, char **argv) { int fd_count = 0; struct pollfd ufds[4]; char *tmpdev; char* debuggable; char tmp[32]; int property_set_fd_init = 0; int signal_fd_init = 0; int keychord_fd_init = 0; bool is_charger = false; if (!strcmp(basename(argv[0]), "ueventd")) return ueventd_main(argc, argv); if (!strcmp(basename(argv[0]), "watchdogd")) return watchdogd_main(argc, argv); /* clear the umask */ umask(0); /* Get the basic filesystem setup we need put * together in the initramdisk on / and then we'll * let the rc file figure out the rest. */ /* Don't repeat the setup of these filesystems, * it creates double mount points with an unknown effect * on the system. This init file is for 2nd-init anyway. */ #ifndef NO_DEVFS_SETUP mkdir("/dev", 0755); mkdir("/proc", 0755); mkdir("/sys", 0755); mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"); mkdir("/dev/pts", 0755); mkdir("/dev/socket", 0755); mount("devpts", "/dev/pts", "devpts", 0, NULL); mount("proc", "/proc", "proc", 0, NULL); mount("sysfs", "/sys", "sysfs", 0, NULL); /* indicate that booting is in progress to background fw loaders, etc */ close(open("/dev/.booting", O_WRONLY | O_CREAT, 0000)); /* We must have some place other than / to create the * device nodes for kmsg and null, otherwise we won't * be able to remount / read-only later on. * Now that tmpfs is mounted on /dev, we can actually * talk to the outside world. */ open_devnull_stdio(); klog_init(); #endif property_init(); get_hardware_name(hardware, &revision); process_kernel_cmdline(); union selinux_callback cb; cb.func_log = klog_write; selinux_set_callback(SELINUX_CB_LOG, cb); cb.func_audit = audit_callback; selinux_set_callback(SELINUX_CB_AUDIT, cb); selinux_initialize(); /* These directories were necessarily created before initial policy load * and therefore need their security context restored to the proper value. * This must happen before /dev is populated by ueventd. */ restorecon("/dev"); restorecon("/dev/socket"); restorecon("/dev/__properties__"); restorecon_recursive("/sys"); is_charger = !strcmp(bootmode, "charger"); INFO("property init\n"); if (!is_charger) property_load_boot_defaults(); INFO("reading config file\n"); if (!charging_mode_booting()) init_parse_config_file("/init.rc"); else init_parse_config_file("/lpm.rc"); /* Check for an emmc initialisation file and read if present */ if (emmc_boot && access("/init.emmc.rc", R_OK) == 0) { INFO("Reading emmc config file"); init_parse_config_file("/init.emmc.rc"); } /* Check for a target specific initialisation file and read if present */ if (access("/init.target.rc", R_OK) == 0) { INFO("Reading target specific config file"); init_parse_config_file("/init.target.rc"); } action_for_each_trigger("early-init", action_add_queue_tail); queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done"); queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng"); queue_builtin_action(keychord_init_action, "keychord_init"); queue_builtin_action(console_init_action, "console_init"); /* execute all the boot actions to get us started */ action_for_each_trigger("init", action_add_queue_tail); if (!is_charger) { action_for_each_trigger("early-fs", action_add_queue_tail); if(emmc_boot) { action_for_each_trigger("emmc-fs", action_add_queue_tail); } else { action_for_each_trigger("fs", action_add_queue_tail); } action_for_each_trigger("post-fs", action_add_queue_tail); action_for_each_trigger("post-fs-data", action_add_queue_tail); } else { action_for_each_trigger("charger-fs", action_add_queue_tail); } /* Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random * wasn't ready immediately after wait_for_coldboot_done */ queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng"); queue_builtin_action(property_service_init_action, "property_service_init"); queue_builtin_action(signal_init_action, "signal_init"); queue_builtin_action(check_startup_action, "check_startup"); /* Older bootloaders use non-standard charging modes. Check for * those now, after mounting the filesystems */ if (strcmp(battchg_pause, BOARD_CHARGING_CMDLINE_VALUE) == 0) is_charger = 1; if (is_charger) { action_for_each_trigger("charger", action_add_queue_tail); } else { action_for_each_trigger("early-boot", action_add_queue_tail); action_for_each_trigger("boot", action_add_queue_tail); } /* run all property triggers based on current state of the properties */ queue_builtin_action(queue_property_triggers_action, "queue_property_triggers"); #if BOOTCHART queue_builtin_action(bootchart_init_action, "bootchart_init"); #endif for(;;) { int nr, i, timeout = -1; execute_one_command(); restart_processes(); if (!property_set_fd_init && get_property_set_fd() > 0) { ufds[fd_count].fd = get_property_set_fd(); ufds[fd_count].events = POLLIN; ufds[fd_count].revents = 0; fd_count++; property_set_fd_init = 1; } if (!signal_fd_init && get_signal_fd() > 0) { ufds[fd_count].fd = get_signal_fd(); ufds[fd_count].events = POLLIN; ufds[fd_count].revents = 0; fd_count++; signal_fd_init = 1; } if (!keychord_fd_init && get_keychord_fd() > 0) { ufds[fd_count].fd = get_keychord_fd(); ufds[fd_count].events = POLLIN; ufds[fd_count].revents = 0; fd_count++; keychord_fd_init = 1; } if (process_needs_restart) { timeout = (process_needs_restart - gettime()) * 1000; if (timeout < 0) timeout = 0; } if (!action_queue_empty() || cur_action) timeout = 0; #if BOOTCHART if (bootchart_count > 0) { if (timeout < 0 || timeout > BOOTCHART_POLLING_MS) timeout = BOOTCHART_POLLING_MS; if (bootchart_step() < 0 || --bootchart_count == 0) { bootchart_finish(); bootchart_count = 0; } } #endif nr = poll(ufds, fd_count, timeout); if (nr <= 0) continue; for (i = 0; i < fd_count; i++) { if (ufds[i].revents & POLLIN) { if (ufds[i].fd == get_property_set_fd()) handle_property_set_fd(); else if (ufds[i].fd == get_keychord_fd()) handle_keychord(); else if (ufds[i].fd == get_signal_fd()) handle_signal(); } } } return 0; }
int main(int argc, char **argv) { int fd_count = 0; struct pollfd ufds[4]; char *tmpdev; char* debuggable; char tmp[32]; int property_set_fd_init = 0; int signal_fd_init = 0; int keychord_fd_init = 0; bool is_charger = false; #ifdef MTK_INIT int mt_boot_mode = 0; klog_set_level(6); #endif if (!strcmp(basename(argv[0]), "ueventd")) return ueventd_main(argc, argv); if (!strcmp(basename(argv[0]), "watchdogd")) return watchdogd_main(argc, argv); /* clear the umask */ umask(0); /* Get the basic filesystem setup we need put * together in the initramdisk on / and then we'll * let the rc file figure out the rest. */ mkdir("/dev", 0755); mkdir("/proc", 0755); mkdir("/sys", 0755); mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"); mkdir("/dev/pts", 0755); mkdir("/dev/socket", 0755); mount("devpts", "/dev/pts", "devpts", 0, NULL); mount("proc", "/proc", "proc", 0, NULL); mount("sysfs", "/sys", "sysfs", 0, NULL); #ifdef INIT_ENG_BUILD mount("debugfs", "/sys/kernel/debug", "debugfs", 0, NULL); #endif /* indicate that booting is in progress to background fw loaders, etc */ close(open("/dev/.booting", O_WRONLY | O_CREAT, 0000)); /* We must have some place other than / to create the * device nodes for kmsg and null, otherwise we won't * be able to remount / read-only later on. * Now that tmpfs is mounted on /dev, we can actually * talk to the outside world. */ open_devnull_stdio(); klog_init(); property_init(); get_hardware_name(hardware, &revision); process_kernel_cmdline(); union selinux_callback cb; cb.func_log = log_callback; selinux_set_callback(SELINUX_CB_LOG, cb); cb.func_audit = audit_callback; selinux_set_callback(SELINUX_CB_AUDIT, cb); selinux_initialize(); /* These directories were necessarily created before initial policy load * and therefore need their security context restored to the proper value. * This must happen before /dev is populated by ueventd. */ restorecon("/dev"); restorecon("/dev/socket"); restorecon("/dev/__properties__"); restorecon_recursive("/sys"); is_charger = !strcmp(bootmode, "charger"); INFO("property init\n"); property_load_boot_defaults(); #ifndef INIT_ENG_BUILD property_set("ro.mtprof.disable", "1"); #endif INFO("reading config file\n"); #ifdef MTK_INIT /* NEW FEATURE: multi-boot mode */ mt_boot_mode = get_boot_mode(); if ( (mt_boot_mode == MT_FACTORY_BOOT) || (mt_boot_mode == MT_ATE_FACTORY_BOOT) ) { printf("Factory Mode Booting.....\n"); property_set("sys.mtk.no.factoryimage","1"); init_parse_config_file("/factory_init.rc"); init_parse_config_file("/factory_init.project.rc"); } else if ( mt_boot_mode == MT_META_BOOT ) { printf("META Mode Booting.....\n"); init_parse_config_file("/meta_init.rc"); init_parse_config_file("/meta_init.project.rc"); } else { #endif // MTK_INIT init_parse_config_file("/init.rc"); #ifdef MTK_INIT } #endif #ifdef MTK_INIT if ( (mt_boot_mode == MT_FACTORY_BOOT) || (mt_boot_mode == MT_ATE_FACTORY_BOOT) ) { NOTICE("No need modem.rc for factory mode\n"); } else if ( mt_boot_mode == MT_META_BOOT ) { init_parse_config_file("/meta_init.modem.rc"); }else { init_parse_config_file("/init.modem.rc"); } #endif // MTK_INIT /**** End of Parsing .rc files ****/ action_for_each_trigger("early-init", action_add_queue_tail); queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done"); queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng"); queue_builtin_action(keychord_init_action, "keychord_init"); queue_builtin_action(console_init_action, "console_init"); /* execute all the boot actions to get us started */ action_for_each_trigger("init", action_add_queue_tail); /* Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random * wasn't ready immediately after wait_for_coldboot_done */ queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng"); queue_builtin_action(property_service_init_action, "property_service_init"); queue_builtin_action(signal_init_action, "signal_init"); /* Don't mount filesystems or start core system services if in charger mode. */ if (is_charger) { action_for_each_trigger("charger", action_add_queue_tail); } else { action_for_each_trigger("late-init", action_add_queue_tail); } /* run all property triggers based on current state of the properties */ queue_builtin_action(queue_property_triggers_action, "queue_property_triggers"); #if BOOTCHART queue_builtin_action(bootchart_init_action, "bootchart_init"); #endif for(;;) { int nr, i, timeout = -1; execute_one_command(); restart_processes(); if (!property_set_fd_init && get_property_set_fd() > 0) { ufds[fd_count].fd = get_property_set_fd(); ufds[fd_count].events = POLLIN; ufds[fd_count].revents = 0; fd_count++; property_set_fd_init = 1; } if (!signal_fd_init && get_signal_fd() > 0) { ufds[fd_count].fd = get_signal_fd(); ufds[fd_count].events = POLLIN; ufds[fd_count].revents = 0; fd_count++; signal_fd_init = 1; } if (!keychord_fd_init && get_keychord_fd() > 0) { ufds[fd_count].fd = get_keychord_fd(); ufds[fd_count].events = POLLIN; ufds[fd_count].revents = 0; fd_count++; keychord_fd_init = 1; } if (process_needs_restart) { timeout = (process_needs_restart - gettime()) * 1000; if (timeout < 0) timeout = 0; } if (!action_queue_empty() || cur_action) timeout = 0; #if BOOTCHART if (bootchart_count > 0) { if (timeout < 0 || timeout > BOOTCHART_POLLING_MS) timeout = BOOTCHART_POLLING_MS; if (bootchart_step() < 0 || --bootchart_count == 0) { bootchart_finish(); bootchart_count = 0; } } #endif nr = poll(ufds, fd_count, timeout); if (nr <= 0) continue; for (i = 0; i < fd_count; i++) { if (ufds[i].revents & POLLIN) { if (ufds[i].fd == get_property_set_fd()) handle_property_set_fd(); else if (ufds[i].fd == get_keychord_fd()) handle_keychord(); else if (ufds[i].fd == get_signal_fd()) handle_signal(); } } } return 0; }
int main(int argc, char **argv) { int fd_count = 0; struct pollfd ufds[4]; char *tmpdev; char* debuggable; char tmp[32]; int property_set_fd_init = 0; int signal_fd_init = 0; int keychord_fd_init = 0; bool is_charger = false; // 判断是否是在充电 char* args_swapon[2]; args_swapon[0] = "swapon_all";; args_swapon[1] = "/fstab.sun8i";; char* args_write[3]; args_write[0] = "write"; args_write[1] = "/proc/sys/vm/page-cluster"; args_write[2] = "0"; if (!strcmp(basename(argv[0]), "ueventd")) return ueventd_main(argc, argv); if (!strcmp(basename(argv[0]), "watchdogd")) return watchdogd_main(argc, argv); /* clear the umask */ umask(0); /* Get the basic filesystem setup we need put * together in the initramdisk on / and then we'll * let the rc file figure out the rest. */ // 创建设备节点 mkdir("/dev", 0755); mkdir("/proc", 0755); mkdir("/sys", 0755); mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"); mkdir("/dev/pts", 0755); mkdir("/dev/socket", 0755); mount("devpts", "/dev/pts", "devpts", 0, NULL); mount("proc", "/proc", "proc", 0, NULL); mount("sysfs", "/sys", "sysfs", 0, NULL); /* indicate that booting is in progress to background fw loaders, etc */ close(open("/dev/.booting", O_WRONLY | O_CREAT, 0000)); /* We must have some place other than / to create the * device nodes for kmsg and null, otherwise we won't * be able to remount / read-only later on. * Now that tmpfs is mounted on /dev, we can actually * talk to the outside world. */ open_devnull_stdio(); // stdio/stdout/stderr都指向__null__设备 klog_init(); // 从这里创建__kmsg__设备 property_init(); // 1. 完成property的环境变量初始化等动作 get_hardware_name(hardware, &revision); process_kernel_cmdline(); // 属性初始设置 union selinux_callback cb; cb.func_log = klog_write; selinux_set_callback(SELINUX_CB_LOG, cb); cb.func_audit = audit_callback; selinux_set_callback(SELINUX_CB_AUDIT, cb); selinux_initialize(); /* These directories were necessarily created before initial policy load * and therefore need their security context restored to the proper value. * This must happen before /dev is populated by ueventd. */ restorecon("/dev"); restorecon("/dev/socket"); restorecon("/dev/__properties__"); restorecon_recursive("/sys"); is_charger = !strcmp(bootmode, "charger"); // 从bootloader中获取是否在充电的信息 usb_charge_flag = is_charger; INFO("property init\n"); if (!is_charger) property_load_boot_defaults(); get_kernel_cmdline_partitions(); get_kernel_cmdline_signature(); INFO("reading config file\n"); init_parse_config_file("/init.rc"); action_for_each_trigger("early-init", action_add_queue_tail); queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done"); queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng"); queue_builtin_action(keychord_init_action, "keychord_init"); /* execute all the boot actions to get us started */ action_for_each_trigger("init", action_add_queue_tail); action_for_each_trigger("early-fs", action_add_queue_tail); /* skip mounting filesystems in charger mode */ if (!is_charger) { // 显示initlog.rle,也就是android第二张图片 queue_builtin_action(console_init_action, "console_init"); action_for_each_trigger("fs", action_add_queue_tail); action_for_each_trigger("post-fs", action_add_queue_tail); action_for_each_trigger("post-fs-data", action_add_queue_tail); //SWAP TO ZRAM if low mem devices if (!(get_dram_size() > 512)) { char trigger[] = {"early-fs"}; ERROR("***************************LOW MEM DEVICE DETECT"); add_command(trigger, 2, args_swapon); char trigger2[] = {"post-fs-data"}; add_command(trigger2, 3, args_write); } } /* Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random * wasn't ready immediately after wait_for_coldboot_done */ queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng"); queue_builtin_action(property_service_init_action, "property_service_init"); queue_builtin_action(signal_init_action, "signal_init"); queue_builtin_action(check_startup_action, "check_startup"); if (is_charger) { // 如果是charger模式,则调用charger.c queue_builtin_action(console_init_action, "console_init"); action_for_each_trigger("charger", action_add_queue_tail); } else { action_for_each_trigger("early-boot", action_add_queue_tail); action_for_each_trigger("boot", action_add_queue_tail); } /* run all property triggers based on current state of the properties */ queue_builtin_action(queue_property_triggers_action, "queue_property_triggers"); #if BOOTCHART queue_builtin_action(bootchart_init_action, "bootchart_init"); #endif for(;;) { // 监视事件 事件处理循环 int nr, i, timeout = -1; execute_one_command(); restart_processes(); if (!property_set_fd_init && get_property_set_fd() > 0) { // 通过套接字传递信息 ufds[fd_count].fd = get_property_set_fd(); ufds[fd_count].events = POLLIN; ufds[fd_count].revents = 0; fd_count++; property_set_fd_init = 1; } if (!signal_fd_init && get_signal_fd() > 0) { ufds[fd_count].fd = get_signal_fd(); ufds[fd_count].events = POLLIN; ufds[fd_count].revents = 0; fd_count++; signal_fd_init = 1; } if (!keychord_fd_init && get_keychord_fd() > 0) { ufds[fd_count].fd = get_keychord_fd(); ufds[fd_count].events = POLLIN; ufds[fd_count].revents = 0; fd_count++; keychord_fd_init = 1; } if (process_needs_restart) { timeout = (process_needs_restart - gettime()) * 1000; if (timeout < 0) timeout = 0; } if (!action_queue_empty() || cur_action) timeout = 0; #if BOOTCHART if (bootchart_count > 0) { if (timeout < 0 || timeout > BOOTCHART_POLLING_MS) timeout = BOOTCHART_POLLING_MS; if (bootchart_step() < 0 || --bootchart_count == 0) { bootchart_finish(); bootchart_count = 0; } } #endif nr = poll(ufds, fd_count, timeout); // 获取事件(热插拔检测) if (nr <= 0) continue; for (i = 0; i < fd_count; i++) { // 处理套接字传回的信息 if (ufds[i].revents & POLLIN) { if (ufds[i].fd == get_property_set_fd()) // 处理属性变更 handle_property_set_fd(); else if (ufds[i].fd == get_keychord_fd()) handle_keychord(); else if (ufds[i].fd == get_signal_fd()) // 处理子进程传回的信息 handle_signal(); } } } return 0; }