SELinux-related 6.0 fixes
* Run restorecon on /data/.layout_version * Fix firmware image mounting, remove obsolete fw_mounter * Add mechanism to append things to rc files
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
@@ -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':"
|
||||
|
||||
100
multirom.c
100
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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
123
rcadditions.c
Normal file
123
rcadditions.c
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
||||
@@ -15,11 +15,22 @@
|
||||
* along with MultiROM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user