Massive refactoring

Remove post-fs mode
This commit is contained in:
topjohnwu 2018-04-22 02:16:56 +08:00
parent 614c552e55
commit 9484ec0c17
9 changed files with 202 additions and 248 deletions

View File

@ -351,7 +351,7 @@ static void simple_mount(const char *path) {
DIR *dir;
struct dirent *entry;
snprintf(buf, PATH_MAX, "%s%s", CACHEMOUNT, path);
snprintf(buf, PATH_MAX, "%s%s", SIMPLEMOUNT, path);
if (!(dir = opendir(buf)))
return;
@ -369,7 +369,7 @@ static void simple_mount(const char *path) {
free(new_path);
} else if (entry->d_type == DT_REG) {
// Actual file path
snprintf(buf, PATH_MAX, "%s%s", CACHEMOUNT, buf2);
snprintf(buf, PATH_MAX, "%s%s", SIMPLEMOUNT, buf2);
// Clone all attributes
clone_attr(buf2, buf);
// Finally, mount the file
@ -465,15 +465,13 @@ static void unblock_boot_process() {
pthread_exit(NULL);
}
void post_fs(int client) {
LOGI("** post-fs mode running\n");
// ack
write_int(client, 0);
close(client);
void startup() {
if (!check_data())
return;
// Uninstall or core only mode
// uninstaller or core-only mode
if (access(UNINSTALLER, F_OK) == 0 || access(DISABLEFILE, F_OK) == 0)
goto unblock;
goto initialize;
// Allocate buffer
buf = xmalloc(PATH_MAX);
@ -482,32 +480,148 @@ void post_fs(int client) {
simple_mount("/system");
simple_mount("/vendor");
unblock:
unblock_boot_process();
}
initialize:
LOGI("** Initializing Magisk\n");
void post_fs_data(int client) {
// ack
write_int(client, 0);
close(client);
if (!is_daemon_init && !check_data())
goto unblock;
// Unlock all blocks for rw
unlock_blocks();
// Start the debug log
start_debug_full_log();
// Magisk binaries
char *bin_path = NULL;
if (access("/cache/data_bin", F_OK) == 0)
bin_path = "/cache/data_bin";
else if (access("/data/data/com.topjohnwu.magisk/install", F_OK) == 0)
bin_path = "/data/data/com.topjohnwu.magisk/install";
else if (access("/data/user_de/0/com.topjohnwu.magisk/install", F_OK) == 0)
bin_path = "/data/user_de/0/com.topjohnwu.magisk/install";
if (bin_path) {
rm_rf(DATABIN);
cp_afc(bin_path, DATABIN);
rm_rf(bin_path);
}
LOGI("** post-fs-data mode running\n");
// Migration
rm_rf("/data/magisk");
unlink("/data/magisk.img");
unlink("/data/magisk_debug.log");
xmkdir("/data/adb", 0700);
chmod("/data/adb", 0700);
// Allocate buffer
if (buf == NULL) buf = xmalloc(PATH_MAX);
if (buf2 == NULL) buf2 = xmalloc(PATH_MAX);
vec_init(&module_list);
LOGI("* Creating /sbin overlay");
DIR *dir;
struct dirent *entry;
int root, sbin, fd;
char buf[PATH_MAX];
void *magisk, *init;
size_t magisk_size, init_size;
// Initialize
if (!is_daemon_init)
daemon_init();
// Create hardlink mirror of /sbin to /root
xmount(NULL, "/", NULL, MS_REMOUNT, NULL);
mkdir("/root", 0750);
full_read("/sbin/magisk", &magisk, &magisk_size);
unlink("/sbin/magisk");
full_read("/sbin/magiskinit", &init, &init_size);
unlink("/sbin/magiskinit");
root = xopen("/root", O_RDONLY | O_CLOEXEC);
sbin = xopen("/sbin", O_RDONLY | O_CLOEXEC);
link_dir(sbin, root);
close(sbin);
// uninstaller
// Mount the /sbin tmpfs overlay
xmount("tmpfs", "/sbin", "tmpfs", 0, NULL);
chmod("/sbin", 0755);
setfilecon("/sbin", "u:object_r:rootfs:s0");
sbin = xopen("/sbin", O_RDONLY | O_CLOEXEC);
// Setup magisk symlinks
fd = creat("/sbin/magisk", 0755);
xwrite(fd, magisk, magisk_size);
close(fd);
free(magisk);
setfilecon("/sbin/magisk", "u:object_r:"SEPOL_FILE_DOMAIN":s0");
for (int i = 0; applet[i]; ++i) {
snprintf(buf, PATH_MAX, "/sbin/%s", applet[i]);
xsymlink("/sbin/magisk", buf);
}
// Setup magiskinit symlinks
fd = creat("/sbin/magiskinit", 0755);
xwrite(fd, init, init_size);
close(fd);
free(init);
setfilecon("/sbin/magiskinit", "u:object_r:"SEPOL_FILE_DOMAIN":s0");
for (int i = 0; init_applet[i]; ++i) {
snprintf(buf, PATH_MAX, "/sbin/%s", init_applet[i]);
xsymlink("/sbin/magiskinit", buf);
}
// Create symlinks pointing back to /root
dir = xfdopendir(root);
while((entry = xreaddir(dir))) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue;
snprintf(buf, PATH_MAX, "/root/%s", entry->d_name);
symlinkat(buf, sbin, entry->d_name);
}
close(sbin);
close(root);
LOGI("* Mounting mirrors");
struct vector mounts;
vec_init(&mounts);
file_to_vector("/proc/mounts", &mounts);
char *line;
int skip_initramfs = 0;
// Check whether skip_initramfs device
vec_for_each(&mounts, line) {
if (strstr(line, " /system_root ")) {
xmkdirs(MIRRDIR "/system", 0755);
bind_mount("/system_root/system", MIRRDIR "/system");
skip_initramfs = 1;
break;
}
}
vec_for_each(&mounts, line) {
if (!skip_initramfs && strstr(line, " /system ")) {
sscanf(line, "%s", buf);
xmkdirs(MIRRDIR "/system", 0755);
xmount(buf, MIRRDIR "/system", "ext4", MS_RDONLY, NULL);
#ifdef MAGISK_DEBUG
LOGI("mount: %s <- %s\n", MIRRDIR "/system", buf);
#else
LOGI("mount: %s\n", MIRRDIR "/system");
#endif
} else if (strstr(line, " /vendor ")) {
seperate_vendor = 1;
sscanf(line, "%s", buf);
xmkdirs(MIRRDIR "/vendor", 0755);
xmount(buf, MIRRDIR "/vendor", "ext4", MS_RDONLY, NULL);
#ifdef MAGISK_DEBUG
LOGI("mount: %s <- %s\n", MIRRDIR "/vendor", buf);
#else
LOGI("mount: %s\n", MIRRDIR "/vendor");
#endif
}
free(line);
}
vec_destroy(&mounts);
if (!seperate_vendor) {
xsymlink(MIRRDIR "/system/vendor", MIRRDIR "/vendor");
#ifdef MAGISK_DEBUG
LOGI("link: %s <- %s\n", MIRRDIR "/vendor", MIRRDIR "/system/vendor");
#else
LOGI("link: %s\n", MIRRDIR "/vendor");
#endif
}
xmkdirs(MIRRDIR "/bin", 0755);
bind_mount(DATABIN, MIRRDIR "/bin");
LOGI("* Setting up internal busybox");
xmkdirs(BBPATH, 0755);
exec_command_sync(MIRRDIR "/bin/busybox", "--install", "-s", BBPATH, NULL);
xsymlink(MIRRDIR "/bin/busybox", BBPATH "/busybox");
// uninstall
if (access(UNINSTALLER, F_OK) == 0) {
close(open(UNBLOCKFILE, O_RDONLY | O_CREAT));
setenv("BOOTMODE", "true", 1);
@ -515,6 +629,28 @@ void post_fs_data(int client) {
return;
}
// Start post-fs-data mode
execv("/sbin/magisk", (char *[]) { "magisk", "--post-fs-data", NULL });
}
void post_fs_data(int client) {
// ack
write_int(client, 0);
close(client);
// Start the debug log
start_debug_full_log();
LOGI("** post-fs-data mode running\n");
xmount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL);
full_patch_pid = exec_command(0, NULL, NULL, "/sbin/magiskpolicy", "--live", "allow "SEPOL_PROC_DOMAIN" * * *", NULL);
// Allocate buffer
buf = xmalloc(PATH_MAX);
buf2 = xmalloc(PATH_MAX);
vec_init(&module_list);
// Merge, trim, mount magisk.img, which will also travel through the modules
// After this, it will create the module list
if (prepare_img())
@ -606,8 +742,6 @@ core_only:
}
auto_start_magiskhide();
unblock:
unblock_boot_process();
}

View File

@ -21,7 +21,6 @@
#include "resetprop.h"
#include "magiskpolicy.h"
int is_daemon_init = 0;
int seperate_vendor = 0;
int full_patch_pid;
@ -39,7 +38,6 @@ static void *request_handler(void *args) {
case ADD_HIDELIST:
case RM_HIDELIST:
case LS_HIDELIST:
case POST_FS:
case POST_FS_DATA:
case LATE_START:
if (credential.uid != 0) {
@ -78,9 +76,6 @@ static void *request_handler(void *args) {
write_int(client, MAGISK_VER_CODE);
close(client);
break;
case POST_FS:
post_fs(client);
break;
case POST_FS_DATA:
post_fs_data(client);
break;
@ -109,152 +104,9 @@ void auto_start_magiskhide() {
free(hide_prop);
}
void daemon_init() {
is_daemon_init = 1;
// Magisk binaries
char *bin_path = NULL;
if (access("/cache/data_bin", F_OK) == 0)
bin_path = "/cache/data_bin";
else if (access("/data/data/com.topjohnwu.magisk/install", F_OK) == 0)
bin_path = "/data/data/com.topjohnwu.magisk/install";
else if (access("/data/user_de/0/com.topjohnwu.magisk/install", F_OK) == 0)
bin_path = "/data/user_de/0/com.topjohnwu.magisk/install";
if (bin_path) {
rm_rf(DATABIN);
cp_afc(bin_path, DATABIN);
rm_rf(bin_path);
}
// Migration
rm_rf("/data/magisk");
unlink("/data/magisk.img");
unlink("/data/magisk_debug.log");
xmkdir("/data/adb", 0700);
chmod("/data/adb", 0700);
LOGI("* Creating /sbin overlay");
DIR *dir;
struct dirent *entry;
int root, sbin, fd;
char buf[PATH_MAX];
void *magisk, *init;
size_t magisk_size, init_size;
// Create hardlink mirror of /sbin to /root
xmount(NULL, "/", NULL, MS_REMOUNT, NULL);
mkdir("/root", 0750);
full_read("/sbin/magisk", &magisk, &magisk_size);
full_read("/sbin/magiskinit", &init, &init_size);
root = xopen("/root", O_RDONLY | O_CLOEXEC);
sbin = xopen("/sbin", O_RDONLY | O_CLOEXEC);
// unlink("/sbin/magisk");
unlink("/sbin/magiskinit");
link_dir(sbin, root);
close(sbin);
// Mount the /sbin tmpfs overlay
xmount("tmpfs", "/sbin", "tmpfs", 0, NULL);
chmod("/sbin", 0755);
setfilecon("/sbin", "u:object_r:rootfs:s0");
sbin = xopen("/sbin", O_RDONLY | O_CLOEXEC);
// Setup magisk
fd = creat("/sbin/magisk", 0755);
xwrite(fd, magisk, magisk_size);
close(fd);
free(magisk);
setfilecon("/sbin/magisk", "u:object_r:"SEPOL_FILE_DOMAIN":s0");
for (int i = 0; applet[i]; ++i) {
snprintf(buf, PATH_MAX, "/sbin/%s", applet[i]);
xsymlink("/sbin/magisk", buf);
}
// Setup magiskinit
fd = creat("/sbin/magiskinit", 0755);
xwrite(fd, init, init_size);
close(fd);
free(init);
setfilecon("/sbin/magiskinit", "u:object_r:"SEPOL_FILE_DOMAIN":s0");
for (int i = 0; init_applet[i]; ++i) {
snprintf(buf, PATH_MAX, "/sbin/%s", init_applet[i]);
xsymlink("/sbin/magiskinit", buf);
}
// Create symlinks pointing back to /root
dir = xfdopendir(root);
while((entry = xreaddir(dir))) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue;
snprintf(buf, PATH_MAX, "/root/%s", entry->d_name);
symlinkat(buf, sbin, entry->d_name);
}
close(sbin);
close(root);
xmount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL);
full_patch_pid = exec_command(0, NULL, NULL, "/sbin/magiskpolicy", "--live", "allow "SEPOL_PROC_DOMAIN" * * *", NULL);
LOGI("* Mounting mirrors");
struct vector mounts;
vec_init(&mounts);
file_to_vector("/proc/mounts", &mounts);
char *line;
int skip_initramfs = 0;
// Check whether skip_initramfs device
vec_for_each(&mounts, line) {
if (strstr(line, " /system_root ")) {
xmkdirs(MIRRDIR "/system", 0755);
bind_mount("/system_root/system", MIRRDIR "/system");
skip_initramfs = 1;
break;
}
}
vec_for_each(&mounts, line) {
if (!skip_initramfs && strstr(line, " /system ")) {
sscanf(line, "%s", buf);
xmkdirs(MIRRDIR "/system", 0755);
xmount(buf, MIRRDIR "/system", "ext4", MS_RDONLY, NULL);
#ifdef MAGISK_DEBUG
LOGI("mount: %s <- %s\n", MIRRDIR "/system", buf);
#else
LOGI("mount: %s\n", MIRRDIR "/system");
#endif
} else if (strstr(line, " /vendor ")) {
seperate_vendor = 1;
sscanf(line, "%s", buf);
xmkdirs(MIRRDIR "/vendor", 0755);
xmount(buf, MIRRDIR "/vendor", "ext4", MS_RDONLY, NULL);
#ifdef MAGISK_DEBUG
LOGI("mount: %s <- %s\n", MIRRDIR "/vendor", buf);
#else
LOGI("mount: %s\n", MIRRDIR "/vendor");
#endif
}
free(line);
}
vec_destroy(&mounts);
if (!seperate_vendor) {
xsymlink(MIRRDIR "/system/vendor", MIRRDIR "/vendor");
#ifdef MAGISK_DEBUG
LOGI("link: %s <- %s\n", MIRRDIR "/vendor", MIRRDIR "/system/vendor");
#else
LOGI("link: %s\n", MIRRDIR "/vendor");
#endif
}
xmkdirs(MIRRDIR "/bin", 0755);
bind_mount(DATABIN, MIRRDIR "/bin");
LOGI("* Setting up internal busybox");
xmkdirs(BBPATH, 0755);
exec_command_sync(MIRRDIR "/bin/busybox", "--install", "-s", BBPATH, NULL);
xsymlink(MIRRDIR "/bin/busybox", BBPATH "/busybox");
}
void start_daemon() {
void start_daemon(int post_fs_data) {
setsid();
setcon("u:r:"SEPOL_PROC_DOMAIN":s0");
umask(0);
int fd = xopen("/dev/null", O_RDWR | O_CLOEXEC);
xdup2(fd, STDIN_FILENO);
xdup2(fd, STDOUT_FILENO);
@ -278,13 +130,11 @@ void start_daemon() {
// Start the log monitor
monitor_logs();
if ((is_daemon_init = (access(MAGISKTMP, F_OK) == 0))) {
if (!post_fs_data && (access(MAGISKTMP, F_OK) == 0)) {
// Restart stuffs if the daemon is restarted
exec_command_sync("logcat", "-b", "all", "-c", NULL);
auto_start_magiskhide();
start_debug_log();
} else if (check_data()) {
daemon_init();
}
LOGI("Magisk v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") daemon started\n");
@ -292,9 +142,6 @@ void start_daemon() {
// Change process name
strcpy(argv0, "magisk_daemon");
// Unlock all blocks for rw
unlock_blocks();
// Loop forever to listen for requests
while(1) {
int *client = xmalloc(sizeof(int));
@ -307,7 +154,7 @@ void start_daemon() {
}
/* Connect the daemon, and return a socketfd */
int connect_daemon() {
int connect_daemon(int post_fs_data) {
struct sockaddr_un sun;
int fd = setup_socket(&sun);
if (connect(fd, (struct sockaddr*) &sun, sizeof(sun))) {
@ -321,7 +168,7 @@ int connect_daemon() {
if (xfork() == 0) {
LOGD("client: connect fail, try launching new daemon process\n");
close(fd);
start_daemon();
start_daemon(post_fs_data);
}
while (connect(fd, (struct sockaddr*) &sun, sizeof(sun)))

View File

@ -14,7 +14,6 @@
#include "utils.h"
#include "resetprop.h"
extern int is_daemon_init;
int loggable = 1;
static int am_proc_start_filter(const char *log) {
@ -107,38 +106,20 @@ static void *logger_thread(void *args) {
}
static void *magisk_log_thread(void *args) {
// Buffer logs before we have data access
struct vector logs;
vec_init(&logs);
FILE *log = xfopen(LOGFILE, "w");
setbuf(log, NULL);
int pipefd[2];
if (xpipe2(pipefd, O_CLOEXEC) == -1)
return NULL;
LOGD("log_monitor: magisk log dumper start");
// Register our listener
log_events[LOG_EVENT].fd = pipefd[1];
LOGD("log_monitor: magisk log dumper start");
for (char *line; xxread(pipefd[0], &line, sizeof(line)) > 0; free(line))
fprintf(log, "%s", line);
FILE *log = NULL;
for (char *line; xxread(pipefd[0], &line, sizeof(line)) > 0; free(line)) {
if (!is_daemon_init) {
vec_push_back(&logs, strdup(line));
} else {
if (log == NULL) {
// Dump buffered logs to file
log = xfopen(LOGFILE, "w");
setbuf(log, NULL);
char *tmp;
vec_for_each(&logs, tmp) {
fprintf(log, "%s", tmp);
free(tmp);
}
vec_destroy(&logs);
}
fprintf(log, "%s", line);
}
}
return NULL;
}

View File

@ -47,13 +47,14 @@ static void usage() {
" --resizeimg IMG SIZE resize ext4 image. SIZE is interpreted in MB\n"
" --mountimg IMG PATH mount IMG to PATH and prints the loop device\n"
" --umountimg PATH LOOP unmount PATH and delete LOOP device\n"
" --[init service] start init service\n"
" --daemon manually start magisk daemon\n"
" --[init trigger] start service for init trigger\n"
" --unlock-blocks set BLKROSET flag to OFF for all block devices\n"
" --restorecon fix selinux context on Magisk files and folders\n"
" --clone-attr SRC DEST clone permission, owner, and selinux context\n"
"\n"
"Supported init services:\n"
" daemon, post-fs, post-fs-data, service\n"
"Supported init triggers:\n"
" startup, post-fs-data, service\n"
"\n"
"Supported applets:\n"
, argv0, argv0);
@ -65,6 +66,7 @@ static void usage() {
}
int main(int argc, char *argv[]) {
umask(0);
argv0 = argv[0];
if (strcmp(basename(argv[0]), "magisk") == 0) {
if (argc < 2) usage();
@ -72,14 +74,14 @@ int main(int argc, char *argv[]) {
printf("%s (%d)\n", MAGISK_VER_STR, MAGISK_VER_CODE);
return 0;
} else if (strcmp(argv[1], "-v") == 0) {
int fd = connect_daemon();
int fd = connect_daemon(0);
write_int(fd, CHECK_VERSION);
char *v = read_string(fd);
printf("%s\n", v);
free(v);
return 0;
} else if (strcmp(argv[1], "-V") == 0) {
int fd = connect_daemon();
int fd = connect_daemon(0);
write_int(fd, CHECK_VERSION_CODE);
printf("%d\n", read_int(fd));
return 0;
@ -144,19 +146,18 @@ int main(int argc, char *argv[]) {
clone_attr(argv[2], argv[3]);
return 0;
} else if (strcmp(argv[1], "--daemon") == 0) {
if (xfork() == 0)
start_daemon();
int fd = connect_daemon(0);
close(fd);
return 0;
} else if (strcmp(argv[1], "--startup") == 0) {
startup();
return 0;
} else if (strcmp(argv[1], "--post-fs") == 0) {
int fd = connect_daemon();
write_int(fd, POST_FS);
return read_int(fd);
} else if (strcmp(argv[1], "--post-fs-data") == 0) {
int fd = connect_daemon();
int fd = connect_daemon(1);
write_int(fd, POST_FS_DATA);
return read_int(fd);
} else if (strcmp(argv[1], "--service") == 0) {
int fd = connect_daemon();
int fd = connect_daemon(0);
write_int(fd, LATE_START);
return read_int(fd);
} else {

View File

@ -18,7 +18,6 @@ enum {
SUPERUSER,
CHECK_VERSION,
CHECK_VERSION_CODE,
POST_FS,
POST_FS_DATA,
LATE_START,
LAUNCH_MAGISKHIDE,
@ -42,10 +41,9 @@ enum {
// daemon.c
void start_daemon();
int connect_daemon();
void start_daemon(int post_fs_data);
int connect_daemon(int post_fs_data);
void auto_start_magiskhide();
void daemon_init();
// socket.c
@ -61,7 +59,7 @@ void write_string(int fd, const char* val);
* Boot Stages *
***************/
void post_fs(int client);
void startup();
void post_fs_data(int client);
void late_start(int client);
void fix_filecon();

View File

@ -14,12 +14,9 @@
#endif
#define LOGFILE "/cache/magisk.log"
#define DEBUG_LOG "/data/adb/magisk_debug.log"
#define UNBLOCKFILE "/dev/.magisk.unblock"
#define PATCHDONE "/dev/.magisk.patch.done"
#define DISABLEFILE "/cache/.disable_magisk"
#define UNINSTALLER "/cache/magisk_uninstaller.sh"
#define CACHEMOUNT "/cache/magisk_mount"
#define MAGISKTMP "/sbin/.core"
#define MIRRDIR MAGISKTMP "/mirror"
#define BBPATH MAGISKTMP "/busybox"
@ -27,8 +24,12 @@
#define COREDIR MOUNTPOINT "/.core"
#define HOSTSFILE COREDIR "/hosts"
#define HIDELIST COREDIR "/hidelist"
#define MAINIMG "/data/adb/magisk.img"
#define DATABIN "/data/adb/magisk"
#define SECURE_DIR "/data/adb/"
#define MAINIMG SECURE_DIR "magisk.img"
#define DATABIN SECURE_DIR "magisk"
#define MAGISKDB SECURE_DIR "magisk.db"
#define SIMPLEMOUNT SECURE_DIR "magisk_simple"
#define DEBUG_LOG SECURE_DIR "magisk_debug.log"
#define MANAGERAPK DATABIN "/magisk.apk"
#define MAGISKRC "/init.magisk.rc"

View File

@ -6,14 +6,12 @@ const char magiskrc[] =
"on post-fs\n"
" start logd\n"
" start magisk_pfs\n"
" wait /dev/.magisk.unblock 10\n"
"\n"
"on post-fs-data\n"
" load_persist_props\n"
" rm /dev/.magisk.unblock\n"
" start magisk_pfsd\n"
" start magisk_startup\n"
" wait /dev/.magisk.unblock 10\n"
" rm /dev/.magisk.unblock\n"
"\n"
@ -26,13 +24,7 @@ const char magiskrc[] =
" oneshot\n"
"\n"
"service magisk_pfs /sbin/magisk --post-fs\n"
" user root\n"
" seclabel u:r:"SEPOL_PROC_DOMAIN":s0\n"
" oneshot\n"
"\n"
"service magisk_pfsd /sbin/magisk --post-fs-data\n"
"service magisk_startup /sbin/magisk --startup\n"
" user root\n"
" seclabel u:r:"SEPOL_PROC_DOMAIN":s0\n"
" oneshot\n"

View File

@ -135,7 +135,7 @@ int magiskhide_main(int argc, char *argv[]) {
} else {
usage(argv[0]);
}
int fd = connect_daemon();
int fd = connect_daemon(0);
write_int(fd, req);
if (req == ADD_HIDELIST || req == RM_HIDELIST) {
write_string(fd, argv[2]);

@ -1 +1 @@
Subproject commit c71ebb26505ac11e8bd9c6a6c69099ec3c2b7596
Subproject commit 42eab87edc319747a1b04cd6df2972a138efc1d1