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)
{