Isolate root daemon from requests

This commit is contained in:
topjohnwu 2017-04-22 00:54:08 +08:00
parent 38c867ea94
commit be5739508b
6 changed files with 51 additions and 33 deletions

View File

@ -23,7 +23,9 @@
pthread_t sepol_patch; pthread_t sepol_patch;
static void request_handler(int client) { static void *request_handler(void *args) {
int client = *((int *) args);
free(args);
client_request req = read_int(client); client_request req = read_int(client);
char *s; char *s;
int pid, status, code; int pid, status, code;
@ -68,6 +70,7 @@ static void request_handler(int client) {
close(client); close(client);
break; break;
} }
return NULL;
} }
/* Setup the address and return socket fd */ /* Setup the address and return socket fd */
@ -112,12 +115,12 @@ void start_daemon() {
xsetsid(); xsetsid();
xsetcon("u:r:su:s0"); xsetcon("u:r:su:s0");
// Patch selinux with medium patch, blocking // Patch selinux with medium patch before we do anything
load_policydb("/sys/fs/selinux/policy"); load_policydb("/sys/fs/selinux/policy");
sepol_med_rules(); sepol_med_rules();
dump_policydb("/sys/fs/selinux/load"); dump_policydb("/sys/fs/selinux/load");
// Continue the larger patch in another thread, will join later // Continue the larger patch in another thread, we will need to join later
pthread_create(&sepol_patch, NULL, large_sepol_patch, NULL); pthread_create(&sepol_patch, NULL, large_sepol_patch, NULL);
struct sockaddr_un sun; struct sockaddr_un sun;
@ -144,11 +147,18 @@ void start_daemon() {
xmount(NULL, "/", NULL, MS_REMOUNT, NULL); xmount(NULL, "/", NULL, MS_REMOUNT, NULL);
create_links(NULL, "/sbin"); create_links(NULL, "/sbin");
chmod("/sbin", 0755); chmod("/sbin", 0755);
mkdir("/magisk", 0755);
chmod("/magisk", 0755);
xmount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL); xmount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL);
// Loop forever to listen to requests // Loop forever to listen to requests
while(1) { while(1) {
request_handler(xaccept(fd, NULL, NULL)); int *client = xmalloc(sizeof(int));
*client = xaccept(fd, NULL, NULL);
pthread_t thread;
xpthread_create(&thread, NULL, request_handler, client);
// Detach the thread, we will never join it
pthread_detach(thread);
} }
} }

View File

@ -32,5 +32,6 @@ static void *logger_thread(void *args) {
/* Start a new thread to monitor logcat and dump to logfile */ /* Start a new thread to monitor logcat and dump to logfile */
void monitor_logs() { void monitor_logs() {
pthread_t log_monitor_thread; pthread_t log_monitor_thread;
pthread_create(&log_monitor_thread, NULL, logger_thread, NULL); xpthread_create(&log_monitor_thread, NULL, logger_thread, NULL);
pthread_detach(log_monitor_thread);
} }

View File

@ -37,9 +37,9 @@ int add_list(char *proc) {
ps_filter_proc_name(proc, kill_proc); ps_filter_proc_name(proc, kill_proc);
// Critical region // Critical region
pthread_mutex_lock(&lock); pthread_mutex_lock(&hide_lock);
hide_list = new_list; hide_list = new_list;
pthread_mutex_unlock(&lock); pthread_mutex_unlock(&hide_lock);
// Free old list // Free old list
vec_destroy(temp); vec_destroy(temp);
@ -74,9 +74,9 @@ int rm_list(char *proc) {
LOGI("hide_list rm: [%s]\n", proc); LOGI("hide_list rm: [%s]\n", proc);
ps_filter_proc_name(proc, kill_proc); ps_filter_proc_name(proc, kill_proc);
// Critical region // Critical region
pthread_mutex_lock(&lock); pthread_mutex_lock(&hide_lock);
hide_list = new_list; hide_list = new_list;
pthread_mutex_unlock(&lock); pthread_mutex_unlock(&hide_lock);
if (vector_to_file(HIDELIST, hide_list)) if (vector_to_file(HIDELIST, hide_list))
return 1; return 1;
} }

View File

@ -23,7 +23,7 @@ struct vector *hide_list = NULL;
int hideEnabled = 0; int hideEnabled = 0;
static pthread_t proc_monitor_thread; static pthread_t proc_monitor_thread;
pthread_mutex_t lock; pthread_mutex_t hide_lock;
void kill_proc(int pid) { void kill_proc(int pid) {
kill(pid, SIGTERM); kill(pid, SIGTERM);
@ -43,12 +43,11 @@ static void usage(char *arg0) {
} }
void launch_magiskhide(int client) { void launch_magiskhide(int client) {
if (hideEnabled) if (hideEnabled) {
goto success; write_int(client, 0);
/* close(client);
* The setns system call do not support multithread processes return;
* We have to fork a new process, and communicate with pipe }
*/
LOGI("* Starting MagiskHide\n"); LOGI("* Starting MagiskHide\n");
@ -60,7 +59,11 @@ void launch_magiskhide(int client) {
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv) == -1) if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv) == -1)
goto error; goto error;
// Launch the hide daemon /*
* The setns system call do not support multithread processes
* We have to fork a new process, and communicate with sockets
*/
if (hide_daemon()) if (hide_daemon())
goto error; goto error;
@ -73,15 +76,18 @@ void launch_magiskhide(int client) {
// Add SafetyNet by default // Add SafetyNet by default
add_list(strdup("com.google.android.gms.unstable")); add_list(strdup("com.google.android.gms.unstable"));
// Start a new thread to monitor processes // Initialize the mutex lock
pthread_mutex_init(&lock, NULL); pthread_mutex_init(&hide_lock, NULL);
if (xpthread_create(&proc_monitor_thread, NULL, proc_monitor, NULL))
goto error;
success:
write_int(client, 0); write_int(client, 0);
close(client); close(client);
// Get thread reference
proc_monitor_thread = pthread_self();
// Start monitoring
proc_monitor();
return; return;
error: error:
hideEnabled = 0; hideEnabled = 0;
write_int(client, 1); write_int(client, 1);
@ -98,16 +104,18 @@ error:
} }
void stop_magiskhide(int client) { void stop_magiskhide(int client) {
if (!hideEnabled) if (!hideEnabled) {
write_int(client, 0);
close(client);
return; return;
}
LOGI("* Stopping MagiskHide\n"); LOGI("* Stopping MagiskHide\n");
pthread_kill(proc_monitor_thread, SIGUSR1);
pthread_join(proc_monitor_thread, NULL);
hideEnabled = 0; hideEnabled = 0;
setprop("persist.magisk.hide", "0"); setprop("persist.magisk.hide", "0");
pthread_kill(proc_monitor_thread, SIGUSR1);
write_int(client, 0); write_int(client, 0);
close(client); close(client);
} }

View File

@ -15,7 +15,7 @@ void kill_proc(int pid);
int hide_daemon(); int hide_daemon();
// Process monitor // Process monitor
void *proc_monitor(void *args); void proc_monitor();
// Preprocess // Preprocess
void manage_selinux(); void manage_selinux();
@ -30,6 +30,6 @@ int destroy_list();
extern int sv[2], hide_pid, hideEnabled; extern int sv[2], hide_pid, hideEnabled;
extern struct vector *hide_list; extern struct vector *hide_list;
extern pthread_mutex_t lock; extern pthread_mutex_t hide_lock;
#endif #endif

View File

@ -44,7 +44,7 @@ static void quit_pthread(int sig) {
write(sv[0], &kill, sizeof(kill)); write(sv[0], &kill, sizeof(kill));
close(sv[0]); close(sv[0]);
waitpid(hide_pid, NULL, 0); waitpid(hide_pid, NULL, 0);
pthread_mutex_destroy(&lock); pthread_mutex_destroy(&hide_lock);
LOGD("proc_monitor: terminating...\n"); LOGD("proc_monitor: terminating...\n");
pthread_exit(NULL); pthread_exit(NULL);
} }
@ -63,7 +63,7 @@ static void proc_monitor_err() {
quit_pthread(SIGUSR1); quit_pthread(SIGUSR1);
} }
void *proc_monitor(void *args) { void proc_monitor() {
// Register the cancel signal // Register the cancel signal
signal(SIGUSR1, quit_pthread); signal(SIGUSR1, quit_pthread);
// The error handler should only exit the thread, not the whole process // The error handler should only exit the thread, not the whole process
@ -120,7 +120,7 @@ void *proc_monitor(void *args) {
ret = 0; ret = 0;
// Critical region // Critical region
pthread_mutex_lock(&lock); pthread_mutex_lock(&hide_lock);
vec_for_each(hide_list, line) { vec_for_each(hide_list, line) {
if (strcmp(processName, line) == 0) { if (strcmp(processName, line) == 0) {
read_namespace(pid, buffer, 32); read_namespace(pid, buffer, 32);
@ -152,7 +152,7 @@ void *proc_monitor(void *args) {
break; break;
} }
} }
pthread_mutex_unlock(&lock); pthread_mutex_unlock(&hide_lock);
if (ret) { if (ret) {
// Wait hide process to kill itself // Wait hide process to kill itself
@ -163,5 +163,4 @@ void *proc_monitor(void *args) {
// Should never be here // Should never be here
quit_pthread(SIGUSR1); quit_pthread(SIGUSR1);
return NULL;
} }