diff --git a/jni/Android.mk b/jni/Android.mk index 942280aec..7dabbee1a 100644 --- a/jni/Android.mk +++ b/jni/Android.mk @@ -8,6 +8,7 @@ LOCAL_SHARED_LIBRARIES := libsqlite libselinux LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/utils \ $(LOCAL_PATH)/daemon \ + $(LOCAL_PATH)/resetprop \ $(LOCAL_PATH)/selinux/libselinux/include \ $(LOCAL_PATH)/selinux/libsepol/include \ $(LOCAL_PATH)/sqlite3 @@ -17,9 +18,9 @@ LOCAL_SRC_FILES := \ utils/misc.c \ utils/vector.c \ utils/xwrap.c \ - utils/log_monitor.c \ daemon/daemon.c \ daemon/socket_trans.c \ + daemon/log_monitor.c \ magiskhide/magiskhide.c \ magiskhide/hide_daemon.c \ magiskhide/proc_monitor.c \ @@ -29,13 +30,14 @@ LOCAL_SRC_FILES := \ magiskpolicy/utils.c \ resetprop/resetprop.cpp \ resetprop/libc_logging.cpp \ - resetprop/system_properties.cpp - # su/su.c \ - # su/daemon.c \ - # su/activity.c \ - # su/db.c \ - # su/utils.c \ - # su/pts.c + resetprop/system_properties.cpp \ + su/su.c \ + su/activity.c \ + su/db.c \ + su/misc.c \ + su/pts.c \ + su/su_client.c \ + su/su_socket.c LOCAL_CFLAGS := -Wno-implicit-exception-spec-mismatch -DDEBUG LOCAL_LDLIBS := -llog diff --git a/jni/daemon/daemon.c b/jni/daemon/daemon.c index 4dbf555a8..7a8241ff3 100644 --- a/jni/daemon/daemon.c +++ b/jni/daemon/daemon.c @@ -36,23 +36,31 @@ static void request_handler(int client) { // TODO: Remove hidelist break; case SUPERUSER: - // TODO: Run su + su_daemon_receiver(client); + break; + case CHECK_VERSION: + write_string(client, VERSION_STR); + close(client); + break; + case CHECK_VERSION_CODE: + write_int(client, VERSION_CODE); + close(client); break; case TEST: s = read_string(client); LOGI("%s\n", s); free(s); write_int(client, 0); + close(client); break; } - close(client); } /* Setup the address and return socket fd */ static int setup_socket(struct sockaddr_un *sun) { int fd = xsocket(AF_LOCAL, SOCK_STREAM, 0); if (fcntl(fd, F_SETFD, FD_CLOEXEC)) { - PLOGE("fcntl FD_CLOEXEC"); + PLOGE("fcntl FD_CLOEXEC"); } memset(sun, 0, sizeof(*sun)); @@ -66,7 +74,7 @@ static void do_nothing() {} void start_daemon() { // Launch the daemon, create new session, set proper context - if (getuid() != AID_ROOT || getgid() != AID_ROOT) { + if (getuid() != UID_ROOT || getgid() != UID_ROOT) { fprintf(stderr, "Starting daemon requires root: %s\n", strerror(errno)); PLOGE("start daemon"); } @@ -90,7 +98,7 @@ void start_daemon() { // Change process name strcpy(argv0, "magisk_daemon"); // The root daemon should not do anything if an error occurs - // It should stay intact in any circumstances + // It should stay intact under any circumstances err_handler = do_nothing; // Start log monitor diff --git a/jni/daemon/daemon.h b/jni/daemon/daemon.h index 8648277ed..70fd9abdd 100644 --- a/jni/daemon/daemon.h +++ b/jni/daemon/daemon.h @@ -1,6 +1,9 @@ /* daemon.h - Utility functions for daemon-client communication */ +#ifndef _DAEMON_H_ +#define _DAEMON_H_ + // Commands require connecting to daemon typedef enum { @@ -9,6 +12,8 @@ typedef enum { ADD_HIDELIST, RM_HIDELIST, SUPERUSER, + CHECK_VERSION, + CHECK_VERSION_CODE, TEST } client_request; @@ -25,3 +30,9 @@ int read_int(int fd); void write_int(int fd, int val); char* read_string(int fd); void write_string(int fd, const char* val); + +// log_monitor.c + +void monitor_logs(); + +#endif diff --git a/jni/utils/log_monitor.c b/jni/daemon/log_monitor.c similarity index 83% rename from jni/utils/log_monitor.c rename to jni/daemon/log_monitor.c index c21399ac1..03ad8d385 100644 --- a/jni/utils/log_monitor.c +++ b/jni/daemon/log_monitor.c @@ -6,20 +6,23 @@ */ #include +#include #include #include "magisk.h" #include "utils.h" +#include "daemon.h" static void *logger_thread(void *args) { + char buffer[PATH_MAX]; // rename("/cache/magisk.log", "/cache/last_magisk.log"); FILE *logfile = xfopen("/cache/magisk_test.log", "w"); // Disable buffering setbuf(logfile, NULL); // Start logcat FILE *p = popen("logcat -s Magisk", "r"); - while (fgets(magiskbuf, BUF_SIZE, p)) { - fprintf(logfile, "%s", magiskbuf); + while (fgets(buffer, sizeof(buffer), p)) { + fprintf(logfile, "%s", buffer); } return NULL; } diff --git a/jni/magisk.h b/jni/magisk.h index 540446800..c83d93c94 100644 --- a/jni/magisk.h +++ b/jni/magisk.h @@ -1,23 +1,24 @@ /* magisk.h - Top header - * - * Contain global functions like logging, - * and entrypoint for main */ #ifndef _MAGISK_H_ #define _MAGISK_H_ +#include #include #include #include #include -#define AID_SHELL (get_shell_uid()) -#define AID_ROOT 0 -#define AID_SYSTEM (get_system_uid()) -#define AID_RADIO (get_radio_uid()) -#define REQUESTOR_DAEMON_PATH "\0MAGISK" +#define VERSION_CODE 130 +#define VERSION 13.0 +#define VERSION_STR xstr(VERSION) ":MAGISK" + +#define str(a) #a +#define xstr(a) str(a) + +#define REQUESTOR_DAEMON_PATH "\0MAGISK" #define REQUESTOR_DAEMON_PATH_LEN 7 #define LOG_TAG "Magisk" @@ -26,8 +27,11 @@ extern __thread void (*err_handler)(void); // Two common error handlers -void exit_proc(); -void exit_thread(); +static inline void exit_proc() { exit(1); } +static inline void exit_thread() { pthread_exit(NULL); } + +// Dummy function to depress debug message +static inline void stub(const char *fmt, ...) {} #ifdef DEBUG #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) @@ -38,20 +42,14 @@ void exit_thread(); #define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) -#define PLOGE(fmt, args...) LOGE(fmt " failed with %d: %s", ##args, errno, strerror(errno)); err_handler() - -void stub(const char *fmt, ...); - -// Global buffer (only for main thread!!) -#define BUF_SIZE 4096 -extern char magiskbuf[BUF_SIZE]; +#define PLOGE(fmt, args...) { LOGE(fmt " failed with %d: %s", ##args, errno, strerror(errno)); err_handler(); } extern char *argv0; /* For changing process name */ // Multi-call entrypoints int magiskhide_main(int argc, char *argv[]); int magiskpolicy_main(int argc, char *argv[]); -// int su_main(int argc, char *argv[]); +int su_client_main(int argc, char *argv[]); #ifdef __cplusplus extern "C" { @@ -68,5 +66,11 @@ int resetprop_main(int argc, char *argv[]); void launch_magiskhide(int client); void stop_magiskhide(int client); +/************* + * Superuser * + *************/ + +void su_daemon_receiver(int client); + #endif diff --git a/jni/magiskhide/hide_daemon.c b/jni/magiskhide/hide_daemon.c index b58475055..06ad4d6c5 100644 --- a/jni/magiskhide/hide_daemon.c +++ b/jni/magiskhide/hide_daemon.c @@ -74,7 +74,7 @@ int hide_daemon() { int fd; FILE *fp; - char cache_block[256], *line; + char buffer[4096], cache_block[256], *line; struct vector mount_list; cache_block[0] = '\0'; @@ -87,18 +87,18 @@ int hide_daemon() { _exit(0); } - snprintf(magiskbuf, BUF_SIZE, "/proc/%d/ns/mnt", pid); - if(access(magiskbuf, F_OK) == -1) continue; // Maybe process died.. + snprintf(buffer, sizeof(buffer), "/proc/%d/ns/mnt", pid); + if(access(buffer, F_OK) == -1) continue; // Maybe process died.. - fd = xopen(magiskbuf, O_RDONLY); + fd = xopen(buffer, O_RDONLY); // Switch to its namespace xsetns(fd, 0); close(fd); manage_selinux(); - snprintf(magiskbuf, BUF_SIZE, "/proc/%d/mounts", pid); - fp = xfopen(magiskbuf, "r"); + snprintf(buffer, sizeof(buffer), "/proc/%d/mounts", pid); + fp = xfopen(buffer, "r"); vec_init(&mount_list); file_to_vector(&mount_list, fp); @@ -116,8 +116,8 @@ int hide_daemon() { vec_for_each_r(&mount_list, line) { if (strstr(line, "tmpfs /system") || strstr(line, "tmpfs /vendor") || strstr(line, "tmpfs /sbin") || (strstr(line, cache_block) && strstr(line, "/system/")) ) { - sscanf(line, "%*s %512s", magiskbuf); - lazy_unmount(magiskbuf); + sscanf(line, "%*s %512s", buffer); + lazy_unmount(buffer); } free(line); } @@ -132,8 +132,8 @@ int hide_daemon() { // Unmount loop mounts vec_for_each_r(&mount_list, line) { if (strstr(line, "/dev/block/loop") && !strstr(line, DUMMYPATH)) { - sscanf(line, "%*s %512s", magiskbuf); - lazy_unmount(magiskbuf); + sscanf(line, "%*s %512s", buffer); + lazy_unmount(buffer); } free(line); } diff --git a/jni/magiskhide/magiskhide.c b/jni/magiskhide/magiskhide.c index 0d5daf3d2..f3429e839 100644 --- a/jni/magiskhide/magiskhide.c +++ b/jni/magiskhide/magiskhide.c @@ -83,9 +83,11 @@ void launch_magiskhide(int client) { isEnabled = 1; write_int(client, 0); + close(client); return; error: write_int(client, 1); + close(client); return; } @@ -106,6 +108,7 @@ void stop_magiskhide(int client) { isEnabled = 0; write_int(client, 0); + close(client); } int magiskhide_main(int argc, char *argv[]) { @@ -123,8 +126,9 @@ int magiskhide_main(int argc, char *argv[]) { req = RM_HIDELIST; } else if (strcmp(argv[1], "--ls") == 0) { FILE *fp = xfopen(HIDELIST, "r"); - while (fgets(magiskbuf, BUF_SIZE, fp)) { - printf("%s", magiskbuf); + char buffer[512]; + while (fgets(buffer, sizeof(buffer), fp)) { + printf("%s", buffer); } fclose(fp); return 0; diff --git a/jni/main.c b/jni/main.c index 620ddf950..f79d8b2bb 100644 --- a/jni/main.c +++ b/jni/main.c @@ -1,30 +1,18 @@ -/* main.c - The entry point, should be multi-call +/* main.c - The multicall entry point */ #include -#include #include "utils.h" #include "magisk.h" #include "daemon.h" -char magiskbuf[BUF_SIZE]; char *argv0; -void stub(const char *fmt, ...) {} - // Global error hander function // Should be changed each thread/process __thread void (*err_handler)(void); -void exit_proc() { - exit(-1); -} - -void exit_thread() { - pthread_exit(NULL); -} - int main(int argc, char *argv[]) { argv0 = argv[0]; // Exit the whole app if error occurs by default @@ -32,12 +20,28 @@ int main(int argc, char *argv[]) { char * arg = strrchr(argv[0], '/'); if (arg) ++arg; if (strcmp(arg, "magisk") == 0) { - if (strcmp(argv[1], "--post-fs") == 0) { + if (strcmp(argv[1], "-v") == 0) { + printf("Client: %s\n", VERSION_STR); + int fd = connect_daemon(); + write_int(fd, CHECK_VERSION); + char *v = read_string(fd); + printf("Daemon: %s\n", v); + free(v); + return 0; + } else if (strcmp(argv[1], "-V") == 0) { + int fd = connect_daemon(); + write_int(fd, CHECK_VERSION_CODE); + printf("%d\n", read_int(fd)); + return 0; + } else if (strcmp(argv[1], "--post-fs") == 0) { // TODO: post-fs mode return 0; } else if (strcmp(argv[1], "--post-fs-data") == 0) { // TODO: post-fs-data mode return 0; + } else if (strcmp(argv[1], "--service") == 0) { + // TODO: late_start service mode + return 0; } else if (strcmp(argv[1], "--install") == 0) { // TODO: Install symlinks return 0; @@ -57,7 +61,7 @@ int main(int argc, char *argv[]) { // Applets if (strcmp(arg, "su") == 0) { - // return su_main(argc, argv); + return su_client_main(argc, argv); } else if (strcmp(arg, "magiskpolicy") == 0) { return magiskpolicy_main(argc, argv); } else if (strcmp(arg, "resetprop") == 0) { @@ -68,4 +72,4 @@ int main(int argc, char *argv[]) { fprintf(stderr, "Applet \'%s\' not found\n", arg); } return 1; -} \ No newline at end of file +} diff --git a/jni/su b/jni/su index 8770e8fb8..c42c44a55 160000 --- a/jni/su +++ b/jni/su @@ -1 +1 @@ -Subproject commit 8770e8fb88a5688a1635ea384085b6d09b4242c6 +Subproject commit c42c44a55254416fc2ccdb89395f42e8a580a67f diff --git a/jni/utils/misc.c b/jni/utils/misc.c index 65a56e2bf..6df17877a 100644 --- a/jni/utils/misc.c +++ b/jni/utils/misc.c @@ -7,17 +7,42 @@ #include #include #include - +#include #include #include "magisk.h" #include "utils.h" +unsigned get_shell_uid() { + struct passwd* ppwd = getpwnam("shell"); + if (NULL == ppwd) + return 2000; + + return ppwd->pw_uid; +} + +unsigned get_system_uid() { + struct passwd* ppwd = getpwnam("system"); + if (NULL == ppwd) + return 1000; + + return ppwd->pw_uid; +} + +unsigned get_radio_uid() { + struct passwd* ppwd = getpwnam("radio"); + if (NULL == ppwd) + return 1001; + + return ppwd->pw_uid; +} + int check_data() { + char buffer[4096]; FILE *fp = xfopen("/proc/mounts", "r"); - while (fgets(magiskbuf, BUF_SIZE, fp)) { - if (strstr(magiskbuf, " /data ")) { - if (strstr(magiskbuf, "tmpfs")) + while (fgets(buffer, sizeof(buffer), fp)) { + if (strstr(buffer, " /data ")) { + if (strstr(buffer, "tmpfs")) return 0; else return 1; diff --git a/jni/utils/utils.h b/jni/utils/utils.h index 26dd54ce2..1ae3b2978 100644 --- a/jni/utils/utils.h +++ b/jni/utils/utils.h @@ -9,9 +9,15 @@ #include #include #include +#include #include "vector.h" +#define UID_SHELL (get_shell_uid()) +#define UID_ROOT 0 +#define UID_SYSTEM (get_system_uid()) +#define UID_RADIO (get_radio_uid()) + // xwrap.c FILE *xfopen(const char *pathname, const char *mode); @@ -38,13 +44,14 @@ ssize_t xrecvmsg(int sockfd, struct msghdr *msg, int flags); int xpthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); int xsocketpair(int domain, int type, int protocol, int sv[2]); - -// log_monitor.c - -void monitor_logs(); +int xstat(const char *pathname, struct stat *buf); +int xdup2(int oldfd, int newfd); // misc.c +unsigned get_shell_uid(); +unsigned get_system_uid(); +unsigned get_radio_uid(); int check_data(); void file_to_vector(struct vector *v, FILE *fp); int isNum(const char *s); diff --git a/jni/utils/xwrap.c b/jni/utils/xwrap.c index 7810e1f09..28b26f4f9 100644 --- a/jni/utils/xwrap.c +++ b/jni/utils/xwrap.c @@ -210,4 +210,20 @@ int xsocketpair(int domain, int type, int protocol, int sv[2]) { return ret; } +int xstat(const char *pathname, struct stat *buf) { + int ret = stat(pathname, buf); + if (ret == -1) { + PLOGE("stat %s", pathname); + } + return ret; +} + +int xdup2(int oldfd, int newfd) { + int ret = dup2(oldfd, newfd); + if (ret == -1) { + PLOGE("dup2"); + } + return ret; +} +