Integrate MagiskSU into Magisk daemon
This commit is contained in:
parent
796c3009c7
commit
6ad993704c
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -6,20 +6,23 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#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;
|
||||
}
|
40
jni/magisk.h
40
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 <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <android/log.h>
|
||||
|
||||
#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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
36
jni/main.c
36
jni/main.c
@ -1,30 +1,18 @@
|
||||
/* main.c - The entry point, should be multi-call
|
||||
/* main.c - The multicall entry point
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
2
jni/su
2
jni/su
@ -1 +1 @@
|
||||
Subproject commit 8770e8fb88a5688a1635ea384085b6d09b4242c6
|
||||
Subproject commit c42c44a55254416fc2ccdb89395f42e8a580a67f
|
@ -7,17 +7,42 @@
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <pwd.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#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;
|
||||
|
@ -9,9 +9,15 @@
|
||||
#include <pthread.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user