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:
Vojtech Bocek
2016-02-06 20:51:50 +01:00
parent cae487184e
commit c61c3a4ebf
9 changed files with 185 additions and 139 deletions

View File

@@ -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

View File

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

View File

@@ -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);
}

View File

@@ -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':"

View File

@@ -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;

View File

@@ -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
View 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);
}
}

View File

@@ -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

View File

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