New invincible implementation

This commit is contained in:
topjohnwu 2017-11-28 03:42:48 +08:00
parent d15fff95b9
commit b4015f877f
7 changed files with 53 additions and 20 deletions

View File

@ -69,6 +69,8 @@ LOCAL_C_INCLUDES := \
LOCAL_SRC_FILES := \
core/magiskinit.c \
core/socket.c \
utils/misc.c \
utils/vector.c \
utils/file.c \
utils/xwrap.c \

View File

@ -128,7 +128,8 @@ void start_daemon() {
struct sockaddr_un sun;
fd = setup_socket(&sun);
xbind(fd, (struct sockaddr*) &sun, sizeof(sun));
if (xbind(fd, (struct sockaddr*) &sun, sizeof(sun)))
exit(1);
xlisten(fd, 10);
if ((is_restart = access(MAGISKTMP, F_OK) == 0)) {
@ -149,9 +150,6 @@ void start_daemon() {
// Unlock all blocks for rw
unlock_blocks();
// Notifiy init the daemon is started
close(xopen(UNBLOCKFILE, O_RDONLY | O_CREAT));
// Loop forever to listen for requests
while(1) {
int *client = xmalloc(sizeof(int));
@ -167,7 +165,7 @@ void start_daemon() {
int connect_daemon() {
struct sockaddr_un sun;
int fd = setup_socket(&sun);
if (xconnect(fd, (struct sockaddr*) &sun, sizeof(sun))) {
if (connect(fd, (struct sockaddr*) &sun, sizeof(sun))) {
// If we cannot access the daemon, we start a daemon in the child process if possible
if (getuid() != UID_ROOT || getgid() != UID_ROOT) {
@ -181,10 +179,8 @@ int connect_daemon() {
start_daemon();
}
do {
// Wait for 10ms
usleep(10);
} while (connect(fd, (struct sockaddr*) &sun, sizeof(sun)));
while (connect(fd, (struct sockaddr*) &sun, sizeof(sun)))
usleep(10000);
}
return fd;
}

View File

@ -148,8 +148,9 @@ int main(int argc, char *argv[]) {
clone_attr(argv[2], argv[3]);
return 0;
} else if (strcmp(argv[1], "--daemon") == 0) {
// Start daemon, this process won't return
if (xfork() == 0)
start_daemon();
return 0;
} else if (strcmp(argv[1], "--post-fs") == 0) {
int fd = connect_daemon();
write_int(fd, POST_FS);

View File

@ -38,11 +38,13 @@
#include <lzma.h>
#include <cil/cil.h>
#include "magisk.h"
#include "dump.h"
#include "magiskrc.h"
#include "utils.h"
#include "magiskpolicy.h"
#include "magiskrc.h"
#include "dump.h"
#include "daemon.h"
#include "magisk.h"
// #define VLOG(fmt, ...) printf(fmt, __VA_ARGS__) /* Enable to debug */
#define VLOG(fmt, ...)
@ -341,13 +343,40 @@ static int dump_magiskrc(const char *path, mode_t mode) {
}
static void magisk_init_daemon() {
// Fork a new process for full patch
setsid();
sepol_allow("su", ALL, ALL, ALL);
// Wait till init cold boot done
wait_till_exists("/dev/.coldboot_done");
// Transit our context to su (mimic setcon)
int fd, crap;
fd = open("/proc/self/attr/current", O_WRONLY);
write(fd, "u:r:su:s0", 9);
close(fd);
// Dump full patch to kernel
dump_policydb(SELINUX_LOAD);
close(open(PATCHDONE, O_RDONLY | O_CREAT, 0));
destroy_policydb();
// Keep Magisk daemon always alive
struct sockaddr_un sun;
fd = setup_socket(&sun);
while (1) {
while (connect(fd, (struct sockaddr*) &sun, sizeof(sun)))
usleep(10000); /* Wait 10 ms after each try */
/* Should hold forever */
read(fd, &crap, sizeof(crap));
/* If things went here, it means the other side of the socket is closed
* We restart the daemon again */
if (fork_dont_care() == 0) {
execv("/sbin/magisk", (char *[]) { "resetprop", "magisk.daemon", "1", NULL } );
exit(1);
}
}
exit(0);
}
@ -434,8 +463,10 @@ int main(int argc, char *argv[]) {
umount("/vendor");
if (fork() == 0)
if (fork_dont_care() == 0) {
strcpy(argv[0], "magiskinit");
magisk_init_daemon();
}
// Finally, give control back!
execv("/init", argv);

View File

@ -45,6 +45,7 @@ void start_debug_log();
#include <stdio.h>
#define LOGI(...)
#define LOGE(...) { fprintf(stderr, __VA_ARGS__); exit(1); }
#define PLOGE(fmt, args...) { fprintf(stderr, fmt " failed with %d: %s\n\n", ##args, errno, strerror(errno)); exit(1); }

View File

@ -4,9 +4,6 @@ const char magiskrc[] =
"on post-fs\n"
" start logd\n"
" start magisk_daemon\n"
" wait /dev/.magisk.unblock 5\n"
" rm /dev/.magisk.unblock\n"
" start magisk_pfs\n"
" wait /dev/.magisk.unblock 10\n"
"\n"
@ -19,11 +16,16 @@ const char magiskrc[] =
" rm /dev/.magisk.unblock\n"
"\n"
"on property:magisk.daemon=1\n"
" start magisk_daemon\n"
"\n"
// Services
"service magisk_daemon /sbin/magisk --daemon\n"
" user root\n"
" seclabel u:r:su:s0\n"
" oneshot\n"
"\n"
"service magisk_pfs /sbin/magisk --post-fs\n"

@ -1 +1 @@
Subproject commit e5b6121d176ee75cbfce58c471cd5d9dc1eb7caa
Subproject commit 8ee9984e4e0a0ce1917d4b131205c79a15f85876