diff --git a/native/jni/Android.mk b/native/jni/Android.mk index 89b65aaf3..a1b21d1b7 100644 --- a/native/jni/Android.mk +++ b/native/jni/Android.mk @@ -19,6 +19,7 @@ LOCAL_SRC_FILES := \ core/socket.cpp \ core/db.cpp \ core/scripting.cpp \ + core/restorecon.cpp \ magiskhide/magiskhide.cpp \ magiskhide/proc_monitor.cpp \ magiskhide/hide_utils.cpp \ diff --git a/native/jni/core/restorecon.cpp b/native/jni/core/restorecon.cpp new file mode 100644 index 000000000..204cbc1d1 --- /dev/null +++ b/native/jni/core/restorecon.cpp @@ -0,0 +1,100 @@ +#include + +#include +#include +#include + +using namespace std; + +#define UNLABEL_CON "u:object_r:unlabeled:s0" +#define SYSTEM_CON "u:object_r:system_file:s0" +#define ADB_CON "u:object_r:adb_data_file:s0" +#define ROOT_CON "u:object_r:rootfs:s0" +#define MAGISK_CON "u:object_r:" SEPOL_FILE_DOMAIN ":s0" + +static void restore_syscon(int dirfd) { + struct dirent *entry; + DIR *dir; + char *con; + + fgetfilecon(dirfd, &con); + if (strlen(con) == 0 || strcmp(con, UNLABEL_CON) == 0) + fsetfilecon(dirfd, SYSTEM_CON); + freecon(con); + + dir = xfdopendir(dirfd); + while ((entry = xreaddir(dir))) { + if (entry->d_name == "."sv || entry->d_name == ".."sv) + continue; + int fd = openat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC); + if (entry->d_type == DT_DIR) { + restore_syscon(fd); + } else if (entry->d_type == DT_REG) { + fgetfilecon(fd, &con); + if (con[0] == '\0' || strcmp(con, UNLABEL_CON) == 0) + fsetfilecon(fd, SYSTEM_CON); + freecon(con); + } else if (entry->d_type == DT_LNK) { + getfilecon_at(dirfd, entry->d_name, &con); + if (con[0] == '\0' || strcmp(con, UNLABEL_CON) == 0) + setfilecon_at(dirfd, entry->d_name, con); + freecon(con); + } + close(fd); + } +} + +static void restore_magiskcon(int dirfd) { + struct dirent *entry; + DIR *dir; + + fsetfilecon(dirfd, MAGISK_CON); + fchown(dirfd, 0, 0); + + dir = xfdopendir(dirfd); + while ((entry = xreaddir(dir))) { + if (entry->d_name == "."sv || entry->d_name == ".."sv) + continue; + int fd = xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC); + if (entry->d_type == DT_DIR) { + restore_magiskcon(fd); + } else if (entry->d_type) { + fsetfilecon(fd, MAGISK_CON); + fchown(fd, 0, 0); + } + close(fd); + } +} + +void restorecon() { + int fd = xopen(SELINUX_CONTEXT, O_WRONLY | O_CLOEXEC); + if (write(fd, ADB_CON, sizeof(ADB_CON)) >= 0) + lsetfilecon(SECURE_DIR, ADB_CON); + close(fd); + lsetfilecon(MODULEROOT, SYSTEM_CON); + fd = xopen(MODULEROOT, O_RDONLY | O_CLOEXEC); + restore_syscon(fd); + close(fd); + fd = xopen(DATABIN, O_RDONLY | O_CLOEXEC); + restore_magiskcon(fd); + close(fd); +} + +void restore_rootcon() { + setfilecon("/sbin", ROOT_CON); + setfilecon(MAGISKTMP, ROOT_CON); + setfilecon(MIRRDIR, ROOT_CON); + setfilecon(BLOCKDIR, ROOT_CON); + + auto dir = xopen_dir("/sbin"); + int dfd = dirfd(dir.get()); + + for (dirent *entry; (entry = xreaddir(dir.get()));) { + if (entry->d_name == "."sv || entry->d_name == ".."sv) + continue; + setfilecon_at(dfd, entry->d_name, ROOT_CON); + } + + setfilecon("/sbin/magisk", MAGISK_CON); + setfilecon("/sbin/magiskinit", MAGISK_CON); +} diff --git a/native/jni/utils/selinux.cpp b/native/jni/utils/selinux.cpp index c9eb6997b..01eba7947 100644 --- a/native/jni/utils/selinux.cpp +++ b/native/jni/utils/selinux.cpp @@ -1,22 +1,9 @@ #include -#include -#include -#include -#include -#include -#include -#include #include #include -using namespace std::literals; - -#define UNLABEL_CON "u:object_r:unlabeled:s0" -#define SYSTEM_CON "u:object_r:system_file:s0" -#define ADB_CON "u:object_r:adb_data_file:s0" -#define ROOT_CON "u:object_r:rootfs:s0" -#define MAGISK_CON "u:object_r:" SEPOL_FILE_DOMAIN ":s0" +using namespace std; // Stub implementation @@ -131,92 +118,3 @@ void dload_selinux() { * Always use builtin implementations for SELinux stuffs. */ selinux_builtin_impl(); } - -static void restore_syscon(int dirfd) { - struct dirent *entry; - DIR *dir; - char *con; - - fgetfilecon(dirfd, &con); - if (strlen(con) == 0 || strcmp(con, UNLABEL_CON) == 0) - fsetfilecon(dirfd, SYSTEM_CON); - freecon(con); - - dir = xfdopendir(dirfd); - while ((entry = xreaddir(dir))) { - if (entry->d_name == "."sv || entry->d_name == ".."sv) - continue; - int fd = openat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC); - if (entry->d_type == DT_DIR) { - restore_syscon(fd); - } else if (entry->d_type == DT_REG) { - fgetfilecon(fd, &con); - if (con[0] == '\0' || strcmp(con, UNLABEL_CON) == 0) - fsetfilecon(fd, SYSTEM_CON); - freecon(con); - } else if (entry->d_type == DT_LNK) { - getfilecon_at(dirfd, entry->d_name, &con); - if (con[0] == '\0' || strcmp(con, UNLABEL_CON) == 0) - setfilecon_at(dirfd, entry->d_name, con); - freecon(con); - } - close(fd); - } -} - -static void restore_magiskcon(int dirfd) { - struct dirent *entry; - DIR *dir; - - fsetfilecon(dirfd, MAGISK_CON); - fchown(dirfd, 0, 0); - - dir = xfdopendir(dirfd); - while ((entry = xreaddir(dir))) { - if (entry->d_name == "."sv || entry->d_name == ".."sv) - continue; - int fd = xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC); - if (entry->d_type == DT_DIR) { - restore_magiskcon(fd); - } else if (entry->d_type) { - fsetfilecon(fd, MAGISK_CON); - fchown(fd, 0, 0); - } - close(fd); - } -} - -void restorecon() { - int fd; - fd = xopen(SELINUX_CONTEXT, O_WRONLY | O_CLOEXEC); - if (write(fd, ADB_CON, sizeof(ADB_CON)) >= 0) - lsetfilecon(SECURE_DIR, ADB_CON); - close(fd); - lsetfilecon(MODULEROOT, SYSTEM_CON); - fd = xopen(MODULEROOT, O_RDONLY | O_CLOEXEC); - restore_syscon(fd); - close(fd); - fd = xopen(DATABIN, O_RDONLY | O_CLOEXEC); - restore_magiskcon(fd); - close(fd); -} - -void restore_rootcon() { - setfilecon("/sbin", ROOT_CON); - setfilecon(MAGISKTMP, ROOT_CON); - setfilecon(MIRRDIR, ROOT_CON); - setfilecon(BLOCKDIR, ROOT_CON); - - auto dir = xopen_dir("/sbin"); - int dfd = dirfd(dir.get()); - - for (dirent *entry; (entry = xreaddir(dir.get()));) { - if (entry->d_name == "."sv || entry->d_name == ".."sv) - continue; - setfilecon_at(dfd, entry->d_name, ROOT_CON); - } - - setfilecon("/sbin/magisk.bin", MAGISK_CON); - setfilecon("/sbin/magisk", MAGISK_CON); - setfilecon("/sbin/magiskinit", MAGISK_CON); -}