Add zygote server notifier

This commit is contained in:
topjohnwu
2019-03-04 16:45:18 -05:00
parent e73fa57d54
commit 6c3896079d
8 changed files with 68 additions and 13 deletions

View File

@ -11,13 +11,15 @@
static int (*applet_main[]) (int, char *[]) = static int (*applet_main[]) (int, char *[]) =
{ magisk_main, su_client_main, resetprop_main, magiskhide_main, nullptr }; { magisk_main, su_client_main, resetprop_main, magiskhide_main, nullptr };
__attribute__((noreturn)) static void call_applets(int argc, char *argv[]) { [[noreturn]] static void call_applets(int argc, char *argv[]) {
// Applets // Applets
for (int i = 0; applet_names[i]; ++i) { for (int i = 0; applet_names[i]; ++i) {
if (strcmp(basename(argv[0]), applet_names[i]) == 0) { if (strcmp(basename(argv[0]), applet_names[i]) == 0) {
exit((*applet_main[i])(argc, argv)); exit((*applet_main[i])(argc, argv));
} }
} }
if (strncmp(basename(argv[0]), "app_process", 11) == 0)
exit(app_process_main(argc, argv));
fprintf(stderr, "%s: applet not found\n", argv[0]); fprintf(stderr, "%s: applet not found\n", argv[0]);
exit(1); exit(1);
} }

View File

@ -575,11 +575,30 @@ static void dump_logs() {
pthread_exit(nullptr); pthread_exit(nullptr);
} }
[[noreturn]] static inline void core_only() { [[noreturn]] static void core_only() {
auto_start_magiskhide(); auto_start_magiskhide();
cp_afc("/sbin/magisk", MAGISKTMP "/app_process");
struct stat st;
for (const char *app : { "app_process", "app_process32", "app_process64" }) {
sprintf(buf, "/system/bin/%s", app);
if (lstat(buf, &st) == 0 && S_ISREG(st.st_mode)) {
clone_attr(buf, MAGISKTMP "/app_process");
bind_mount(MAGISKTMP "/app_process", buf);
}
}
unblock_boot_process(); unblock_boot_process();
} }
void zygote_notify(int client, struct ucred *cred) {
/* TODO: notify services that need zygote PIDs */
char *path = read_string(client);
LOGD("%s PID=[%d]\n", path, cred->pid);
close(client);
usleep(100000);
bind_mount(MAGISKTMP "/app_process", path);
free(path);
}
void post_fs_data(int client) { void post_fs_data(int client) {
// ack // ack
write_int(client, 0); write_int(client, 0);

View File

@ -88,7 +88,9 @@ static void *request_handler(void *args) {
break; break;
case SQLITE_CMD: case SQLITE_CMD:
exec_sql(client); exec_sql(client);
close(client); break;
case ZYGOTE_NOTIFY:
zygote_notify(client, &credential);
break; break;
default: default:
close(client); close(client);
@ -161,13 +163,13 @@ int switch_mnt_ns(int pid) {
return ret; return ret;
} }
int connect_daemon() { int connect_daemon(bool create) {
struct sockaddr_un sun; struct sockaddr_un sun;
socklen_t len = setup_sockaddr(&sun, MAIN_SOCKET); socklen_t len = setup_sockaddr(&sun, MAIN_SOCKET);
int fd = xsocket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0); int fd = xsocket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
if (connect(fd, (struct sockaddr*) &sun, len)) { if (connect(fd, (struct sockaddr*) &sun, len)) {
if (getuid() != UID_ROOT || getgid() != UID_ROOT) { if (!create || getuid() != UID_ROOT || getgid() != UID_ROOT) {
fprintf(stderr, "No daemon is currently running!\n"); LOGE("No daemon is currently running!\n");
exit(1); exit(1);
} }

View File

@ -320,4 +320,5 @@ void exec_sql(int client) {
return; return;
); );
write_int(client, 0); write_int(client, 0);
close(client);
} }

View File

@ -1,3 +1,4 @@
#include <sys/mount.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
@ -81,19 +82,19 @@ int magisk_main(int argc, char *argv[]) {
cp_afc(argv[2], argv[3]); cp_afc(argv[2], argv[3]);
return 0; return 0;
} else if (strcmp(argv[1], "--daemon") == 0) { } else if (strcmp(argv[1], "--daemon") == 0) {
int fd = connect_daemon(); int fd = connect_daemon(true);
write_int(fd, DO_NOTHING); write_int(fd, DO_NOTHING);
return 0; return 0;
} else if (strcmp(argv[1], "--post-fs-data") == 0) { } else if (strcmp(argv[1], "--post-fs-data") == 0) {
int fd = connect_daemon(); int fd = connect_daemon(true);
write_int(fd, POST_FS_DATA); write_int(fd, POST_FS_DATA);
return read_int(fd); return read_int(fd);
} else if (strcmp(argv[1], "--service") == 0) { } else if (strcmp(argv[1], "--service") == 0) {
int fd = connect_daemon(); int fd = connect_daemon(true);
write_int(fd, LATE_START); write_int(fd, LATE_START);
return read_int(fd); return read_int(fd);
} else if (strcmp(argv[1], "--boot-complete") == 0) { } else if (strcmp(argv[1], "--boot-complete") == 0) {
int fd = connect_daemon(); int fd = connect_daemon(true);
write_int(fd, BOOT_COMPLETE); write_int(fd, BOOT_COMPLETE);
return read_int(fd); return read_int(fd);
} else if (strcmp(argv[1], "--sqlite") == 0) { } else if (strcmp(argv[1], "--sqlite") == 0) {
@ -111,3 +112,29 @@ int magisk_main(int argc, char *argv[]) {
#endif #endif
usage(); usage();
} }
int app_process_main(int argc, char *argv[]) {
char path[512];
bool zygote = false;
for (int i = 0; i < argc; ++i) {
if (strcmp(argv[i], "--zygote") == 0) {
zygote = true;
break;
}
}
if (zygote) {
// Notify main daemon
sprintf(path, "/system/bin/%s", basename(argv[0]));
umount2(path, MNT_DETACH);
int fd = connect_daemon();
write_int(fd, ZYGOTE_NOTIFY);
write_string(fd, path);
close(fd);
} else {
// Redirect to system mirror
sprintf(path, MIRRDIR "/system/bin/%s", basename(argv[0]));
}
argv[0] = path;
execve(path, argv, environ);
return -1;
}

View File

@ -21,6 +21,7 @@ enum {
BOOT_COMPLETE, BOOT_COMPLETE,
MAGISKHIDE, MAGISKHIDE,
SQLITE_CMD, SQLITE_CMD,
ZYGOTE_NOTIFY,
}; };
// Return codes for daemon // Return codes for daemon
@ -33,7 +34,7 @@ enum {
// daemon.c // daemon.c
int connect_daemon(); int connect_daemon(bool create = false);
int switch_mnt_ns(int pid); int switch_mnt_ns(int pid);
// socket.c // socket.c
@ -60,6 +61,7 @@ void write_key_token(int fd, const char *key, int tok);
***************/ ***************/
void unlock_blocks(); void unlock_blocks();
void zygote_notify(int client, struct ucred *cred);
void post_fs_data(int client); void post_fs_data(int client);
void late_start(int client); void late_start(int client);
void boot_complete(int client); void boot_complete(int client);

View File

@ -41,8 +41,8 @@
extern int SDK_INT; extern int SDK_INT;
#define applet_names ((const char *[]) { "magisk", "su", "resetprop", "magiskhide", nullptr }) constexpr const char *applet_names[] = { "magisk", "su", "resetprop", "magiskhide", nullptr };
#define init_applet ((const char *[]) { "magiskpolicy", "supolicy", nullptr }) constexpr const char *init_applet[] = { "magiskpolicy", "supolicy", nullptr };
// Multi-call entrypoints // Multi-call entrypoints
int magisk_main(int argc, char *argv[]); int magisk_main(int argc, char *argv[]);
@ -50,5 +50,6 @@ int magiskhide_main(int argc, char *argv[]);
int magiskpolicy_main(int argc, char *argv[]); int magiskpolicy_main(int argc, char *argv[]);
int su_client_main(int argc, char *argv[]); int su_client_main(int argc, char *argv[]);
int resetprop_main(int argc, char *argv[]); int resetprop_main(int argc, char *argv[]);
int app_process_main(int argc, char *argv[]);
#endif #endif

View File

@ -78,6 +78,7 @@ void sepol_magisk_rules() {
allowSuClient("untrusted_app_25"); allowSuClient("untrusted_app_25");
allowSuClient("untrusted_app_27"); allowSuClient("untrusted_app_27");
allowSuClient("update_engine"); allowSuClient("update_engine");
allowSuClient("zygote");
// suRights // suRights
sepol_allow("servicemanager", SEPOL_PROC_DOMAIN, "dir", "search"); sepol_allow("servicemanager", SEPOL_PROC_DOMAIN, "dir", "search");