diff --git a/Android.mk b/Android.mk index 172a740..c121cb8 100644 --- a/Android.mk +++ b/Android.mk @@ -19,6 +19,7 @@ LOCAL_SRC_FILES:= \ multirom_ui_portrait.c \ multirom_ui_themes.c \ pong.c \ + rcadditions.c \ rom_quirks.c \ # With these, GCC optimizes aggressively enough so full-screen alpha blending @@ -60,9 +61,6 @@ include $(BUILD_EXECUTABLE) # Trampoline include $(multirom_local_path)/trampoline/Android.mk -# fw_mounter -include $(multirom_local_path)/fw_mounter/Android.mk - # ZIP installer include $(multirom_local_path)/install_zip/Android.mk diff --git a/fw_mounter/Android.mk b/fw_mounter/Android.mk deleted file mode 100644 index a53e22c..0000000 --- a/fw_mounter/Android.mk +++ /dev/null @@ -1,17 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_C_INCLUDES += $(multirom_local_path) -LOCAL_SRC_FILES:= \ - fw_mounter.c \ - -LOCAL_MODULE := fw_mounter -LOCAL_MODULE_TAGS := eng - -LOCAL_FORCE_STATIC_EXECUTABLE := true -LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT) -LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED) - -LOCAL_STATIC_LIBRARIES := libcutils libc libmultirom_static - -include $(BUILD_EXECUTABLE) diff --git a/fw_mounter/fw_mounter.c b/fw_mounter/fw_mounter.c deleted file mode 100644 index 259648d..0000000 --- a/fw_mounter/fw_mounter.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of MultiROM. - * - * MultiROM is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MultiROM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with MultiROM. If not, see . - */ - -#include -#include -#include - -#include "../lib/log.h" -#include "../lib/util.h" -#include "../lib/fstab.h" -#include "fw_mounter_defines.h" - -int main(int argc, char *argv[]) -{ - mrom_set_log_tag("fw_mounter"); - - struct fstab *f = fstab_load(FW_MOUNTER_FSTAB, 0); - if(!f) - { - ERROR("Failed to load %s\n", FW_MOUNTER_FSTAB); - return -1; - } - - struct fstab_part *fw_part = fstab_find_first_by_path(f, "/firmware"); - if(!fw_part) - { - ERROR("Unable to find partition /firmware in %s!\n", FW_MOUNTER_FSTAB); - return -1; - } - - ERROR("Mounting %s to %s\n", fw_part->device, fw_part->path); - return mount_image(fw_part->device, fw_part->path, fw_part->type, fw_part->mountflags, fw_part->options); -} diff --git a/install_zip/Android.mk b/install_zip/Android.mk index e9dd87a..029e8ba 100644 --- a/install_zip/Android.mk +++ b/install_zip/Android.mk @@ -24,7 +24,7 @@ ifneq ($(MR_DEVICE_VARIANTS),) MR_DEVICES += $(MR_DEVICE_VARIANTS) endif -$(MULTIROM_ZIP_TARGET): multirom trampoline fw_mounter signapk bbootimg mrom_kexec_static mrom_adbd $(multirom_extra_dep) +$(MULTIROM_ZIP_TARGET): multirom trampoline signapk bbootimg mrom_kexec_static mrom_adbd $(multirom_extra_dep) @echo @echo @echo "A crowdfunding campaign for MultiROM took place in 2013. These people got perk 'The Tenth':" diff --git a/multirom.c b/multirom.c index 3acacbe..ae3b607 100644 --- a/multirom.c +++ b/multirom.c @@ -51,7 +51,6 @@ #include "hooks.h" #include "rom_quirks.h" #include "kexec.h" -#include "fw_mounter/fw_mounter_defines.h" #define REALDATA "/realdata" #define BUSYBOX_BIN "busybox" @@ -253,7 +252,7 @@ void multirom_emergency_reboot(void) char *tail; char *last_end; int cur_y; - uid_t media_rw_id; + unsigned int media_rw_id; if(multirom_init_fb(0) < 0) { @@ -306,7 +305,7 @@ void multirom_emergency_reboot(void) free(klog); media_rw_id = decode_uid("media_rw"); - if(media_rw_id != -1) + if(media_rw_id != -1U) chown("../multirom_log.txt", (uid_t)media_rw_id, (gid_t)media_rw_id); chmod("../multirom_log.txt", 0666); @@ -990,13 +989,16 @@ int multirom_prepare_for_boot(struct multirom_status *s, struct multirom_rom *to { exit &= ~(EXIT_UMOUNT); - if(multirom_prep_android_mounts(to_boot) == -1) + if(multirom_prep_android_mounts(s, to_boot) == -1) return -1; - if(multirom_create_media_link() == -1) + if(multirom_create_media_link(s) == -1) return -1; rom_quirks_on_initrd_finalized(); + + rcadditions_write_to_files(&s->rc); + rcadditions_free(&s->rc); } if(to_boot->partition) @@ -1064,66 +1066,39 @@ char *multirom_find_fstab_in_rc(const char *rcfile) // works. There is a chance Google will disable all services which don't have // context set in sepolicy. That will be a problem. -static int multirom_inject_fw_mounter(char *rc_with_mount_all, struct fstab_part *fw_part) +// UPDATE: fw_mounter gets shut down by SELinux on 6.0, inject .rc files and file_contexts instead. + +static int multirom_inject_fw_mounter(struct multirom_status *s, struct fstab_part *fw_part) { - static const char *trigger_line = " start mrom_fw_mounter\n"; - static const char *service_block = - "\nservice mrom_fw_mounter "FW_MOUNTER_PATH"\n" - " disabled\n" - " oneshot\n" - " user root\n" - " group root\n"; + char buf[512]; - char *rc_file, *p; - size_t rc_len, alloc_size; - char line[512]; - FILE *f = fopen(rc_with_mount_all, "r+e"); - if(!f) + rcadditions_append_contexts(&s->rc, + "/realdata/media/0/multirom/roms/[^/]+/firmware.img u:object_r:asec_image_file:s0\n" + "/realdata/media/multirom/roms/[^/]+/firmware.img u:object_r:asec_image_file:s0\n"); + + snprintf(buf, sizeof(buf), " restorecon %s\n", fw_part->device); + rcadditions_append_trigger(&s->rc, "fs", buf); + + snprintf(buf, sizeof(buf), " mount %s loop@%s %s ", fw_part->type, fw_part->device, fw_part->path); + rcadditions_append_trigger(&s->rc, "fs", buf); + + if(fw_part->options_raw) { - ERROR("Failed to open file \"%s\" to inject fw_mounter!\n", rc_with_mount_all); - fstab_destroy_part(fw_part); - return -1; + char *c, *opts = strdup(fw_part->options_raw); + for(c = opts; *c; ++c) + if(*c == ',') + *c = ' '; + rcadditions_append_trigger(&s->rc, "fs", opts); + free(opts); } - fseek(f, 0, SEEK_END); - rc_len = ftell(f); - fseek(f, 0, SEEK_SET); - - alloc_size = rc_len + 1 + strlen(trigger_line); - rc_file = malloc(alloc_size); - rc_file[0] = 0; - - while(fgets(line, sizeof(line), f)) - { - for(p = line; isspace(*p); ++p); - - if(*p && *p != '#' && line[strlen(line)-1] == '\n' && strncmp(p, "mount_all", 9) == 0) - strcat(rc_file, trigger_line); - strcat(rc_file, line); - } - - fseek(f, 0, SEEK_SET); - fputs(rc_file, f); - fputs(service_block, f); - - free(rc_file); - fclose(f); - - // copy fw_mounter to /sbin - snprintf(line, sizeof(line), "%s/%s", mrom_dir(), FW_MOUNTER_BIN); - copy_file(line, FW_MOUNTER_PATH); - chmod(FW_MOUNTER_PATH, 0755); - - // prepare fstab for it - struct fstab *fw_fstab = fstab_create_empty(2); - fstab_add_part_struct(fw_fstab, fw_part); - fstab_save(fw_fstab, FW_MOUNTER_FSTAB); - fstab_destroy(fw_fstab); + rcadditions_append_trigger(&s->rc, "fs", "\n"); + fstab_destroy_part(fw_part); return 0; } -int multirom_prep_android_mounts(struct multirom_rom *rom) +int multirom_prep_android_mounts(struct multirom_status *s, struct multirom_rom *rom) { char in[128]; char out[128]; @@ -1219,14 +1194,11 @@ int multirom_prep_android_mounts(struct multirom_rom *rom) if(has_fw && fw_part) { - // Can't mount the image here because it might clash with /firmware mounted - // for encryption - INFO("Mounting ROM's FW image instead of FW partition, using fw_mounter\n"); + INFO("Mounting ROM's FW image instead of FW partition\n"); snprintf(from, sizeof(from), "%s/firmware.img", rom->base_path); fw_part->device = realloc(fw_part->device, strlen(from)+1); strcpy(fw_part->device, from); - multirom_inject_fw_mounter(rc_with_mount_all, fw_part); - fw_part = NULL; + multirom_inject_fw_mounter(s, fw_part); } #if MR_DEVICE_HOOKS >= 1 @@ -1328,7 +1300,7 @@ exit: return res; } -int multirom_create_media_link(void) +int multirom_create_media_link(struct multirom_status *s) { int media_new = 0; int api_level = multirom_get_api_level("/system/build.prop"); @@ -1399,6 +1371,10 @@ int multirom_create_media_link(void) fclose(f); chmod(LAYOUT_VERSION, 0600); } + + // We need to set SELinux context for this file in case it was created by multirom, + // but can't do it here because selinux was not initialized + rcadditions_append_trigger(&s->rc, "post-fs-data", " restorecon " LAYOUT_VERSION "\n"); } return 0; diff --git a/multirom.h b/multirom.h index abba9dc..09462a2 100644 --- a/multirom.h +++ b/multirom.h @@ -24,6 +24,7 @@ #include "lib/fstab.h" #include "lib/containers.h" #include "kexec.h" +#include "rcadditions.h" enum { @@ -114,6 +115,7 @@ struct multirom_status struct usb_partition **partitions; char *curr_rom_part; struct fstab *fstab; + struct rcadditions rc; }; int multirom(const char *rom_to_boot); @@ -134,8 +136,8 @@ int multirom_prepare_for_boot(struct multirom_status *s, struct multirom_rom *to void multirom_free_status(struct multirom_status *s); void multirom_free_rom(void *rom); int multirom_init_fb(int rotation); -int multirom_prep_android_mounts(struct multirom_rom *rom); -int multirom_create_media_link(void); +int multirom_prep_android_mounts(struct multirom_status *s, struct multirom_rom *rom); +int multirom_create_media_link(struct multirom_status *s); int multirom_process_android_fstab(char *fstab_name, int has_fw, struct fstab_part **fw_part); int multirom_get_api_level(const char *path); int multirom_get_rom_type(struct multirom_rom *rom); diff --git a/rcadditions.c b/rcadditions.c new file mode 100644 index 0000000..cf4af5b --- /dev/null +++ b/rcadditions.c @@ -0,0 +1,123 @@ +/* + * This file is part of MultiROM. + * + * MultiROM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MultiROM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MultiROM. If not, see . + */ + +#include +#include +#include +#include +#include + +#include "lib/log.h" +#include "rcadditions.h" + +static void append_string_buffer(char **buf, const char *what) { + size_t old_len = 0; + if(*buf) + old_len += strlen(*buf); + + *buf = realloc(*buf, old_len + strlen(what) + 1); + (*buf)[old_len] = 0; + strcat(*buf, what); +} + +void rcadditions_append_trigger(struct rcadditions *r, const char *trigger, const char *what) { + if(r->triggers == NULL) + r->triggers = map_create(); + + char **ref = (char**)map_get_ref(r->triggers, trigger); + if(ref == NULL) + map_add_not_exist(r->triggers, trigger, strdup(what)); + else + append_string_buffer(ref, what); +} + +void rcadditions_append_file(struct rcadditions *r, const char *what) { + append_string_buffer(&r->eof_append, what); +} + +void rcadditions_append_contexts(struct rcadditions *r, const char *what) { + append_string_buffer(&r->file_contexts_append, what); +} + +void rcadditions_free(struct rcadditions *r) +{ + free(r->eof_append); + r->eof_append = NULL; + + free(r->file_contexts_append); + r->file_contexts_append = NULL; + + map_destroy(r->triggers, &free); + r->triggers = NULL; +} + +void rcadditions_write_to_files(struct rcadditions *r) +{ + if(r->eof_append == NULL && r->triggers == NULL) + return; + + FILE *f = fopen("/init.multirom.rc", "we"); + if(!f) + { + ERROR("Failed to create init.multirom.rc: %s\n", strerror(errno)); + return; + } + + fputs("# This file is autogenerated by MultiROM during boot\n\n", f); + + if(r->triggers) + { + size_t i = 0; + for(; i < r->triggers->size; ++i) + { + fprintf(f, "on %s\n", r->triggers->keys[i]); + fputs((char*)r->triggers->values[i], f); + fputc('\n', f); + } + } + + if(r->eof_append) + { + fputc('\n', f); + fputs(r->eof_append, f); + } + fclose(f); + + chmod("/init.multirom.rc", 0750); + + f = fopen("/init.rc", "ae"); + if(!f) + { + ERROR("Failed to open init.rc: %s\n", strerror(errno)); + return; + } + fputs("\n# Added by MultiROM\nimport /init.multirom.rc\n", f); + fclose(f); + + if(r->file_contexts_append) + { + f = fopen("/file_contexts", "ae"); + if(!f) + { + ERROR("Failed to open file_contexts: %s\n", strerror(errno)); + return; + } + fputs("\n# Added by multirom during boot\n", f); + fputs(r->file_contexts_append, f); + fclose(f); + } +} diff --git a/fw_mounter/fw_mounter_defines.h b/rcadditions.h similarity index 56% rename from fw_mounter/fw_mounter_defines.h rename to rcadditions.h index 7a397ef..7304106 100644 --- a/fw_mounter/fw_mounter_defines.h +++ b/rcadditions.h @@ -15,11 +15,22 @@ * along with MultiROM. If not, see . */ - #ifndef FW_MOUNTER_DEFINES_H - #define FW_MOUNTER_DEFINES_H +#ifndef RCADDITIONS_H +#define RCADDITIONS_H - #define FW_MOUNTER_FSTAB "/sbin/fw_mounter.fstab" - #define FW_MOUNTER_BIN "fw_mounter" - #define FW_MOUNTER_PATH "/sbin/"FW_MOUNTER_BIN +#include "lib/containers.h" - #endif +struct rcadditions +{ + map *triggers; + char *eof_append; + char *file_contexts_append; +}; + +void rcadditions_append_trigger(struct rcadditions *r, const char *trigger, const char *what); +void rcadditions_append_file(struct rcadditions *r, const char *what); +void rcadditions_append_contexts(struct rcadditions *r, const char *what); +void rcadditions_free(struct rcadditions *r); +void rcadditions_write_to_files(struct rcadditions *r); + +#endif diff --git a/rom_quirks.c b/rom_quirks.c index 92f0fc7..f479887 100644 --- a/rom_quirks.c +++ b/rom_quirks.c @@ -85,7 +85,7 @@ static void inject_file_contexts(void) fclose(f); - INFO("Injecting /file_contexts"); + INFO("Injecting /file_contexts\n"); f = fopen("/file_contexts", "ae"); if(!f) {