improve: APatch detection; fix: Magisk detection and Magisk manager detection; fix: fd leak

This commit both improves the APatch detection, making it more stricter, and fixes Magisk detection, together with its manager detection, allowing it to successfully boot. Also fixes a fd leak which makes it better at a long run.
This commit is contained in:
ThePedroo
2024-10-01 17:11:22 -03:00
parent 05ae6941ba
commit b392730366
5 changed files with 93 additions and 35 deletions

View File

@@ -12,12 +12,28 @@
enum RootImplState apatch_get_existence(void) { enum RootImplState apatch_get_existence(void) {
struct stat s; struct stat s;
if (stat("/data/adb/apd", &s) != 0) { if (stat("/data/adb/apd", &s) != 0) {
if (errno != ENOENT) LOGE("Failed to stat APatch apd binary: %s\n", strerror(errno)); if (errno != ENOENT) {
LOGE("Failed to stat APatch apd binary: %s\n", strerror(errno));
}
errno = 0; errno = 0;
return Inexistent; return Inexistent;
} }
char *PATH = getenv("PATH");
if (PATH == NULL) {
LOGE("Failed to get PATH environment variable: %s\n", strerror(errno));
errno = 0;
return Inexistent;
}
if (strstr(PATH, "/data/adb/ap/bin") == NULL) {
LOGE("APatch's APD binary is not in PATH\n");
return Inexistent;
}
char apatch_version[32]; char apatch_version[32];
char *const argv[] = { "apd", "-V", NULL }; char *const argv[] = { "apd", "-V", NULL };
@@ -30,8 +46,6 @@ enum RootImplState apatch_get_existence(void) {
int version = atoi(apatch_version + strlen("apd ")); int version = atoi(apatch_version + strlen("apd "));
LOGI("Meow-- Version: %d\n", version);
if (version == 0) return Abnormal; if (version == 0) return Abnormal;
if (version >= MIN_APATCH_VERSION && version <= 999999) return Supported; if (version >= MIN_APATCH_VERSION && version <= 999999) return Supported;
if (version >= 1 && version <= MIN_APATCH_VERSION - 1) return TooOld; if (version >= 1 && version <= MIN_APATCH_VERSION - 1) return TooOld;

View File

@@ -22,45 +22,96 @@ char *magisk_managers[] = {
"io.github.huskydg.magisk" "io.github.huskydg.magisk"
}; };
#define SBIN_MAGISK lp_select("/sbin/magisk32", "/sbin/magisk64")
#define DEBUG_RAMDISK_MAGISK lp_select("/debug_ramdisk/magisk32", "/debug_ramdisk/magisk64")
#define BITLESS_DEBUG_RAMDISK_MAGISK "/debug_ramdisk/magisk"
enum magisk_variants variant = Official; enum magisk_variants variant = Official;
/* INFO: Longest path */
static char path_to_magisk[sizeof(DEBUG_RAMDISK_MAGISK)];
enum RootImplState magisk_get_existence(void) { enum RootImplState magisk_get_existence(void) {
char *argv[] = { "magisk", "-v", NULL }; struct stat s;
if (stat(SBIN_MAGISK, &s) != 0) {
char magisk_info[32]; LOGE("Failed to stat Magisk /sbin/magisk binary: %s\n", strerror(errno));
if (!exec_command(magisk_info, sizeof(magisk_info), "/sbin/magisk", argv)) {
LOGE("Failed to execute magisk binary: %s\n", strerror(errno)); if (errno != ENOENT) {
LOGE("Failed to stat Magisk /sbin/magisk binary: %s\n", strerror(errno));
}
errno = 0; errno = 0;
return Inexistent; if (stat(DEBUG_RAMDISK_MAGISK, &s) != 0) {
LOGE("Failed to stat Magisk %s binary: %s\n", DEBUG_RAMDISK_MAGISK, strerror(errno));
if (errno != ENOENT) {
LOGE("Failed to stat Magisk %s binary: %s\n", DEBUG_RAMDISK_MAGISK, strerror(errno));
}
errno = 0;
if (stat(BITLESS_DEBUG_RAMDISK_MAGISK, &s) != 0) {
LOGE("Failed to stat Magisk %s binary: %s\n", BITLESS_DEBUG_RAMDISK_MAGISK, strerror(errno));
if (errno != ENOENT) {
LOGE("Failed to stat Magisk /debug_ramdisk/magisk binary: %s\n", strerror(errno));
}
errno = 0;
return Inexistent;
}
/* INFO: /debug_ramdisk/magisk64 (or 32) doesn't exist but /debug_ramdisk/magisk does */
strcpy(path_to_magisk, BITLESS_DEBUG_RAMDISK_MAGISK);
} else {
/* INFO: /sbin/magisk doesn't exist but /debug_ramdisk/magisk does */
strcpy(path_to_magisk, DEBUG_RAMDISK_MAGISK);
}
} else {
/* INFO: /sbin/magisk exists */
strcpy(path_to_magisk, SBIN_MAGISK);
} }
for (unsigned long i = 0; i < sizeof(supported_variants) / sizeof(char *); i++) { char *argv[] = { "magisk", "-v", NULL };
if (strstr(magisk_info, supported_variants[i])) variant = (enum magisk_variants)(i + 1);
}
argv[1] = "-V"; char magisk_info[128];
if (!exec_command(magisk_info, sizeof(magisk_info), (const char *)path_to_magisk, argv)) {
char magisk_version[32];
if (!exec_command(magisk_version, sizeof(magisk_version), "/sbin/magisk", argv)) {
LOGE("Failed to execute magisk binary: %s\n", strerror(errno)); LOGE("Failed to execute magisk binary: %s\n", strerror(errno));
errno = 0; errno = 0;
return Abnormal; return Abnormal;
} }
LOGI("Magisk info: %s\n", magisk_info);
for (unsigned long i = 0; i < sizeof(supported_variants) / sizeof(supported_variants[0]); i++) {
if (strstr(magisk_info, supported_variants[i])) variant = (enum magisk_variants)(i + 1);
}
argv[1] = "-V";
char magisk_version[32];
if (!exec_command(magisk_version, sizeof(magisk_version), (const char *)path_to_magisk, argv)) {
LOGE("Failed to execute magisk binary: %s\n", strerror(errno));
errno = 0;
return Abnormal;
}
LOGI("Magisk version: %s\n", magisk_version);
if (atoi(magisk_version) >= MIN_MAGISK_VERSION) return Supported; if (atoi(magisk_version) >= MIN_MAGISK_VERSION) return Supported;
else return TooOld; else return TooOld;
} }
bool magisk_uid_granted_root(uid_t uid) { bool magisk_uid_granted_root(uid_t uid) {
LOGI("Checking if UID %d is granted root access\n", uid);
char sqlite_cmd[256]; char sqlite_cmd[256];
snprintf(sqlite_cmd, sizeof(sqlite_cmd), "select 1 from policies where uid=%d and policy=2 limit 1", uid); snprintf(sqlite_cmd, sizeof(sqlite_cmd), "select 1 from policies where uid=%d and policy=2 limit 1", uid);
char *const argv[] = { "magisk", "--sqlite", sqlite_cmd, NULL }; char *const argv[] = { "magisk", "--sqlite", sqlite_cmd, NULL };
char result[32]; char result[32];
if (!exec_command(result, sizeof(result), "/sbin/magisk", argv)) { if (!exec_command(result, sizeof(result), (const char *)path_to_magisk, argv)) {
LOGE("Failed to execute magisk binary: %s\n", strerror(errno)); LOGE("Failed to execute magisk binary: %s\n", strerror(errno));
errno = 0; errno = 0;
@@ -71,6 +122,8 @@ bool magisk_uid_granted_root(uid_t uid) {
} }
bool magisk_uid_should_umount(uid_t uid) { bool magisk_uid_should_umount(uid_t uid) {
LOGI("Checking if UID %d should unmount\n", uid);
struct dirent *entry; struct dirent *entry;
DIR *proc = opendir("/proc"); DIR *proc = opendir("/proc");
if (!proc) { if (!proc) {
@@ -130,7 +183,7 @@ bool magisk_uid_should_umount(uid_t uid) {
char *const argv[] = { "magisk", "--sqlite", sqlite_cmd, NULL }; char *const argv[] = { "magisk", "--sqlite", sqlite_cmd, NULL };
char result[32]; char result[32];
if (!exec_command(result, sizeof(result), "/sbin/magisk", argv)) { if (!exec_command(result, sizeof(result), (const char *)path_to_magisk, argv)) {
LOGE("Failed to execute magisk binary: %s\n", strerror(errno)); LOGE("Failed to execute magisk binary: %s\n", strerror(errno));
errno = 0; errno = 0;
@@ -144,13 +197,15 @@ bool magisk_uid_should_umount(uid_t uid) {
} }
bool magisk_uid_is_manager(uid_t uid) { bool magisk_uid_is_manager(uid_t uid) {
LOGI("Checking if UID %d is a Magisk manager\n", uid);
char sqlite_cmd[256]; char sqlite_cmd[256];
snprintf(sqlite_cmd, sizeof(sqlite_cmd), "select value from strings where key=\"requester\" limit 1"); snprintf(sqlite_cmd, sizeof(sqlite_cmd), "select value from strings where key=\"requester\" limit 1");
char *const argv[] = { "magisk", "--sqlite", sqlite_cmd, NULL }; char *const argv[] = { "magisk", "--sqlite", sqlite_cmd, NULL };
char output[32]; char output[128] = { 0 };
if (!exec_command(output, sizeof(output), "/sbin/magisk", argv)) { if (!exec_command(output, sizeof(output), (const char *)path_to_magisk, argv)) {
LOGE("Failed to execute magisk binary: %s\n", strerror(errno)); LOGE("Failed to execute magisk binary: %s\n", strerror(errno));
errno = 0; errno = 0;
@@ -172,14 +227,13 @@ bool magisk_uid_is_manager(uid_t uid) {
return s.st_uid == uid; return s.st_uid == uid;
} else { } else {
char stat_path[PATH_MAX]; char stat_path[PATH_MAX];
snprintf(stat_path, sizeof(stat_path), "/data/user_de/0/%s", output + strlen("value=")); snprintf(stat_path, sizeof(stat_path), "/data/user_de/0/%s", output + strlen("value=")); /* BUG: ISSUE HERE, OUTPUT IS NOT VALID */
LOGI("Checking |%s|\n", stat_path); LOGI("Checking |%s|\n", stat_path);
struct stat s; struct stat s;
if (stat(stat_path, &s) == -1) { if (stat(stat_path, &s) == -1) {
LOGE("Failed to stat %s: %s\n", stat_path, strerror(errno)); LOGE("Failed to stat %s WHAT %s\n", stat_path, strerror(errno));
LOGE("???\n");
errno = 0; errno = 0;
return false; return false;

View File

@@ -18,10 +18,6 @@
#include "utils.h" #include "utils.h"
/* INFO 50ms wait */
// #define ALLOW_WAIT_ON_DEBUG() usleep(500 * 1000)
#define ALLOW_WAIT_ON_DEBUG() {}
bool switch_mount_namespace(pid_t pid) { bool switch_mount_namespace(pid_t pid) {
char path[PATH_MAX]; char path[PATH_MAX];
snprintf(path, sizeof(path), "/proc/%d/ns/mnt", pid); snprintf(path, sizeof(path), "/proc/%d/ns/mnt", pid);
@@ -267,8 +263,6 @@ int gread_fd(int fd) {
#define write_func(type) \ #define write_func(type) \
ssize_t write_## type(int fd, type val) { \ ssize_t write_## type(int fd, type val) { \
ALLOW_WAIT_ON_DEBUG(); \
\
return write(fd, &val, sizeof(type)); \ return write(fd, &val, sizeof(type)); \
} }
@@ -293,8 +287,6 @@ ssize_t write_string(int fd, const char *restrict str) {
size_t len[1]; size_t len[1];
len[0] = strlen(str); len[0] = strlen(str);
ALLOW_WAIT_ON_DEBUG();
ssize_t written_bytes = write(fd, &len, sizeof(size_t)); ssize_t written_bytes = write(fd, &len, sizeof(size_t));
if (written_bytes != sizeof(size_t)) { if (written_bytes != sizeof(size_t)) {
LOGE("Failed to write string length: Not all bytes were written (%zd != %zu).\n", written_bytes, sizeof(size_t)); LOGE("Failed to write string length: Not all bytes were written (%zd != %zu).\n", written_bytes, sizeof(size_t));

View File

@@ -36,10 +36,6 @@ int chcon(const char *path, const char *restrict context);
int unix_listener_from_path(char *path); int unix_listener_from_path(char *path);
// ssize_t send_fd(int sockfd, int fd);
// int recv_fd(int sockfd);
ssize_t gwrite_fd(int fd, int sendfd); ssize_t gwrite_fd(int fd, int sendfd);
int gread_fd(int fd); int gread_fd(int fd);

View File

@@ -784,6 +784,8 @@ void zygiskd_start(char *restrict argv[]) {
} }
} }
if (action != RequestCompanionSocket) close(client_fd);
continue; continue;
} }