mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-12-02 22:31:51 +00:00
Support Safe Mode detection
When detecting device is booting as Safe Mode, disable all modules and MagiskHide and skip all operations. The only thing that'll be available in this state is root (Magisk Manager will also be disabled by system). Since the next normal boot will also have all modules disabled, this can be used to rescue a device in the case when a rogue module causes bootloop and no custom recovery is available (or recoveries without the ability to decrypt data).
This commit is contained in:
@@ -21,6 +21,7 @@ using namespace std;
|
||||
|
||||
static bool no_secure_dir = false;
|
||||
static bool pfs_done = false;
|
||||
static bool safe_mode = false;
|
||||
|
||||
/*********
|
||||
* Setup *
|
||||
@@ -224,12 +225,6 @@ static void dump_logs() {
|
||||
pthread_exit(nullptr);
|
||||
}
|
||||
|
||||
[[noreturn]] static void core_only() {
|
||||
pfs_done = true;
|
||||
auto_start_magiskhide();
|
||||
unblock_boot_process();
|
||||
}
|
||||
|
||||
void post_fs_data(int client) {
|
||||
// ack
|
||||
write_int(client, 0);
|
||||
@@ -262,16 +257,21 @@ void post_fs_data(int client) {
|
||||
unblock_boot_process();
|
||||
}
|
||||
|
||||
LOGI("* Running post-fs-data.d scripts\n");
|
||||
exec_common_script("post-fs-data");
|
||||
if (getprop("persist.sys.safemode", true) == "1") {
|
||||
safe_mode = true;
|
||||
// Disable all modules and magiskhide so next boot will be clean
|
||||
foreach_modules("disable");
|
||||
stop_magiskhide();
|
||||
} else {
|
||||
LOGI("* Running post-fs-data.d scripts\n");
|
||||
exec_common_script("post-fs-data");
|
||||
handle_modules();
|
||||
auto_start_magiskhide();
|
||||
}
|
||||
|
||||
// Core only mode
|
||||
if (access(DISABLEFILE, F_OK) == 0)
|
||||
core_only();
|
||||
|
||||
handle_modules();
|
||||
|
||||
core_only();
|
||||
// We still want to do magic mount because root itself might need it
|
||||
magic_mount();
|
||||
unblock_boot_process();
|
||||
}
|
||||
|
||||
void late_start(int client) {
|
||||
@@ -290,7 +290,7 @@ void late_start(int client) {
|
||||
reboot();
|
||||
}
|
||||
|
||||
if (!pfs_done)
|
||||
if (!pfs_done || safe_mode)
|
||||
return;
|
||||
|
||||
auto_start_magiskhide();
|
||||
@@ -298,11 +298,8 @@ void late_start(int client) {
|
||||
LOGI("* Running service.d scripts\n");
|
||||
exec_common_script("service");
|
||||
|
||||
// Core only mode
|
||||
if (access(DISABLEFILE, F_OK) != 0) {
|
||||
LOGI("* Running module service scripts\n");
|
||||
exec_module_script("service", module_list);
|
||||
}
|
||||
LOGI("* Running module service scripts\n");
|
||||
exec_module_script("service", module_list);
|
||||
|
||||
// All boot stage done, cleanup
|
||||
module_list.clear();
|
||||
@@ -315,7 +312,7 @@ void boot_complete(int client) {
|
||||
write_int(client, 0);
|
||||
close(client);
|
||||
|
||||
if (!pfs_done)
|
||||
if (!pfs_done || safe_mode)
|
||||
return;
|
||||
|
||||
auto_start_magiskhide();
|
||||
|
||||
@@ -96,9 +96,10 @@ static void *request_handler(void *args) {
|
||||
exec_sql(client);
|
||||
break;
|
||||
case REMOVE_MODULES:
|
||||
remove_modules();
|
||||
foreach_modules("remove");
|
||||
write_int(client, 0);
|
||||
close(client);
|
||||
reboot();
|
||||
break;
|
||||
case GET_PATH:
|
||||
write_string(client, MAGISKTMP.data());
|
||||
|
||||
@@ -542,7 +542,7 @@ static void inject_magisk_bins(root_node *system) {
|
||||
delete bin->extract(init_applet[i]);
|
||||
}
|
||||
|
||||
static void mount_modules() {
|
||||
void magic_mount() {
|
||||
node_entry::mirror_dir = MAGISKTMP + "/" MIRRDIR;
|
||||
node_entry::module_mnt = MAGISKTMP + "/" MODULEMNT "/";
|
||||
|
||||
@@ -683,12 +683,10 @@ void handle_modules() {
|
||||
// Recollect modules (module scripts could remove itself)
|
||||
module_list.clear();
|
||||
collect_modules();
|
||||
|
||||
mount_modules();
|
||||
}
|
||||
|
||||
void remove_modules() {
|
||||
LOGI("* Remove all modules and reboot\n");
|
||||
void foreach_modules(const char *name) {
|
||||
LOGI("* Add %s to all modules\n", name);
|
||||
auto dir = open_dir(MODULEROOT);
|
||||
if (!dir)
|
||||
return;
|
||||
@@ -700,9 +698,8 @@ void remove_modules() {
|
||||
continue;
|
||||
|
||||
int modfd = xopenat(dfd, entry->d_name, O_RDONLY | O_CLOEXEC);
|
||||
close(xopenat(modfd, "remove", O_RDONLY | O_CREAT | O_CLOEXEC, 0));
|
||||
close(xopenat(modfd, name, O_RDONLY | O_CREAT | O_CLOEXEC, 0));
|
||||
close(modfd);
|
||||
}
|
||||
}
|
||||
reboot();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user