mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-24 02:25:28 +00:00
Prevent race condition on /magisk symlink
This commit is contained in:
parent
2db60e0a6b
commit
72b5985398
@ -100,7 +100,7 @@ void stop_magiskhide(int client) {
|
|||||||
setprop(MAGISKHIDE_PROP, "0");
|
setprop(MAGISKHIDE_PROP, "0");
|
||||||
// Remove without actually removing persist props
|
// Remove without actually removing persist props
|
||||||
deleteprop2(MAGISKHIDE_PROP, 0);
|
deleteprop2(MAGISKHIDE_PROP, 0);
|
||||||
pthread_kill(proc_monitor_thread, SIGUSR1);
|
pthread_kill(proc_monitor_thread, TERM_THREAD);
|
||||||
|
|
||||||
write_int(client, DAEMON_SUCCESS);
|
write_int(client, DAEMON_SUCCESS);
|
||||||
close(client);
|
close(client);
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#define TERM_THREAD SIGUSR1
|
||||||
|
#define HIDE_DONE SIGUSR2
|
||||||
|
|
||||||
// Kill process
|
// Kill process
|
||||||
void kill_proc(int pid);
|
void kill_proc(int pid);
|
||||||
|
|
||||||
|
@ -20,10 +20,10 @@
|
|||||||
#include "magiskhide.h"
|
#include "magiskhide.h"
|
||||||
|
|
||||||
static char init_ns[32], zygote_ns[2][32], cache_block[256];
|
static char init_ns[32], zygote_ns[2][32], cache_block[256];
|
||||||
static int zygote_num, has_cache = 1, pipefd[2] = { -1, -1 };
|
static int hide_queue = 0, zygote_num, has_cache = 1, pipefd[2] = { -1, -1 };
|
||||||
|
|
||||||
// Workaround for the lack of pthread_cancel
|
// Workaround for the lack of pthread_cancel
|
||||||
static void quit_pthread(int sig) {
|
static void term_thread(int sig) {
|
||||||
LOGD("proc_monitor: running cleanup\n");
|
LOGD("proc_monitor: running cleanup\n");
|
||||||
destroy_list();
|
destroy_list();
|
||||||
hideEnabled = 0;
|
hideEnabled = 0;
|
||||||
@ -38,6 +38,15 @@ static void quit_pthread(int sig) {
|
|||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void hide_done(int sig) {
|
||||||
|
--hide_queue;
|
||||||
|
if (hide_queue == 0) {
|
||||||
|
xmount(NULL, "/", NULL, MS_REMOUNT, NULL);
|
||||||
|
xsymlink(MOUNTPOINT, FAKEPOINT);
|
||||||
|
xmount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int read_namespace(const int pid, char* target, const size_t size) {
|
static int read_namespace(const int pid, char* target, const size_t size) {
|
||||||
char path[32];
|
char path[32];
|
||||||
snprintf(path, sizeof(path), "/proc/%d/ns/mnt", pid);
|
snprintf(path, sizeof(path), "/proc/%d/ns/mnt", pid);
|
||||||
@ -63,7 +72,7 @@ static void lazy_unmount(const char* mountpoint) {
|
|||||||
LOGD("hide_daemon: Unmount Failed (%s)\n", mountpoint);
|
LOGD("hide_daemon: Unmount Failed (%s)\n", mountpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hide_daemon(int pid) {
|
static void hide_daemon(int pid, int ppid) {
|
||||||
LOGD("hide_daemon: start unmount for pid=[%d]\n", pid);
|
LOGD("hide_daemon: start unmount for pid=[%d]\n", pid);
|
||||||
|
|
||||||
char *line, buffer[PATH_MAX];
|
char *line, buffer[PATH_MAX];
|
||||||
@ -135,7 +144,7 @@ exit:
|
|||||||
vec_destroy(&mount_list);
|
vec_destroy(&mount_list);
|
||||||
// Wait a while and link it back
|
// Wait a while and link it back
|
||||||
sleep(10);
|
sleep(10);
|
||||||
xsymlink(MOUNTPOINT, FAKEPOINT);
|
kill(ppid, HIDE_DONE);
|
||||||
_exit(0);
|
_exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,15 +152,17 @@ void proc_monitor() {
|
|||||||
// Register the cancel signal
|
// Register the cancel signal
|
||||||
struct sigaction act;
|
struct sigaction act;
|
||||||
memset(&act, 0, sizeof(act));
|
memset(&act, 0, sizeof(act));
|
||||||
act.sa_handler = quit_pthread;
|
act.sa_handler = term_thread;
|
||||||
sigaction(SIGUSR1, &act, NULL);
|
sigaction(TERM_THREAD, &act, NULL);
|
||||||
|
act.sa_handler = hide_done;
|
||||||
|
sigaction(HIDE_DONE, &act, NULL);
|
||||||
|
|
||||||
cache_block[0] = '\0';
|
cache_block[0] = '\0';
|
||||||
|
|
||||||
// Get the mount namespace of init
|
// Get the mount namespace of init
|
||||||
if (read_namespace(1, init_ns, 32)) {
|
if (read_namespace(1, init_ns, 32)) {
|
||||||
LOGE("proc_monitor: Your kernel doesn't support mount namespace :(\n");
|
LOGE("proc_monitor: Your kernel doesn't support mount namespace :(\n");
|
||||||
quit_pthread(SIGUSR1);
|
term_thread(TERM_THREAD);
|
||||||
}
|
}
|
||||||
LOGI("proc_monitor: init ns=%s\n", init_ns);
|
LOGI("proc_monitor: init ns=%s\n", init_ns);
|
||||||
|
|
||||||
@ -227,8 +238,10 @@ void proc_monitor() {
|
|||||||
* The setns system call do not support multithread processes
|
* The setns system call do not support multithread processes
|
||||||
* We have to fork a new process, setns, then do the unmounts
|
* We have to fork a new process, setns, then do the unmounts
|
||||||
*/
|
*/
|
||||||
|
++hide_queue;
|
||||||
|
int selfpid = getpid();
|
||||||
if (fork_dont_care() == 0)
|
if (fork_dont_care() == 0)
|
||||||
hide_daemon(pid);
|
hide_daemon(pid, selfpid);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user