mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-27 12:05:30 +00:00
Reorganize libutils and cleanups
This commit is contained in:
parent
d5a56d9e85
commit
a9121fa28f
@ -462,7 +462,7 @@ static int prepare_img() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void install_apk(const char *apk) {
|
||||
static void install_apk(const char *apk) {
|
||||
setfilecon(apk, "u:object_r:"SEPOL_FILE_DOMAIN":s0");
|
||||
while (1) {
|
||||
sleep(5);
|
||||
@ -486,6 +486,43 @@ void install_apk(const char *apk) {
|
||||
unlink(apk);
|
||||
}
|
||||
|
||||
static int check_data() {
|
||||
struct vector v;
|
||||
vec_init(&v);
|
||||
file_to_vector("/proc/mounts", &v);
|
||||
char *line;
|
||||
int mnt = 0;
|
||||
vec_for_each(&v, line) {
|
||||
if (strstr(line, " /data ") && strstr(line, "tmpfs") == NULL) {
|
||||
mnt = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
vec_deep_destroy(&v);
|
||||
int data = 0;
|
||||
if (mnt) {
|
||||
char *crypto = getprop("ro.crypto.state");
|
||||
if (crypto != NULL) {
|
||||
if (strcmp(crypto, "unencrypted") == 0) {
|
||||
// Unencrypted, we can directly access data
|
||||
data = 1;
|
||||
} else {
|
||||
// Encrypted, check whether vold is started
|
||||
char *vold = getprop("init.svc.vold");
|
||||
if (vold != NULL) {
|
||||
free(vold);
|
||||
data = 1;
|
||||
}
|
||||
}
|
||||
free(crypto);
|
||||
} else {
|
||||
// ro.crypto.state is not set, assume it's unencrypted
|
||||
data = 1;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
static void *start_magisk_hide(void *args) {
|
||||
launch_magiskhide(-1);
|
||||
return NULL;
|
||||
@ -503,6 +540,27 @@ static void auto_start_magiskhide() {
|
||||
free(hide_prop);
|
||||
}
|
||||
|
||||
void unlock_blocks() {
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
int fd, dev, OFF = 0;
|
||||
|
||||
if ((dev = xopen("/dev/block", O_RDONLY | O_CLOEXEC)) < 0)
|
||||
return;
|
||||
dir = xfdopendir(dev);
|
||||
|
||||
while((entry = readdir(dir))) {
|
||||
if (entry->d_type == DT_BLK) {
|
||||
if ((fd = openat(dev, entry->d_name, O_RDONLY)) < 0)
|
||||
continue;
|
||||
if (ioctl(fd, BLKROSET, &OFF) == -1)
|
||||
PLOGE("unlock %s", entry->d_name);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
close(dev);
|
||||
}
|
||||
|
||||
/****************
|
||||
* Entry points *
|
||||
****************/
|
||||
|
@ -17,13 +17,18 @@
|
||||
#include "magisk.h"
|
||||
#include "utils.h"
|
||||
#include "daemon.h"
|
||||
#include "resetprop.h"
|
||||
#include "selinux.h"
|
||||
#include "flags.h"
|
||||
|
||||
int setup_done = 0;
|
||||
int seperate_vendor = 0;
|
||||
|
||||
static void get_client_cred(int fd, struct ucred *cred) {
|
||||
socklen_t ucred_length = sizeof(*cred);
|
||||
if(getsockopt(fd, SOL_SOCKET, SO_PEERCRED, cred, &ucred_length))
|
||||
PLOGE("getsockopt");
|
||||
}
|
||||
|
||||
static void *request_handler(void *args) {
|
||||
int client = *((int *) args);
|
||||
free(args);
|
||||
|
@ -41,11 +41,6 @@ enum {
|
||||
HIDE_ITEM_NOT_EXIST,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
MAIN_DAEMON,
|
||||
LOG_DAEMON
|
||||
} daemon_t;
|
||||
|
||||
// daemon.c
|
||||
|
||||
int connect_daemon();
|
||||
@ -78,6 +73,7 @@ void write_key_token(int fd, const char *key, int tok);
|
||||
* Boot Stages *
|
||||
***************/
|
||||
|
||||
void unlock_blocks();
|
||||
void startup();
|
||||
void post_fs_data(int client);
|
||||
void late_start(int client);
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#include <libgen.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
@ -15,7 +16,6 @@
|
||||
#include "resetprop.h"
|
||||
#include "magiskhide.h"
|
||||
#include "daemon.h"
|
||||
#include "selinux.h"
|
||||
|
||||
static char *prop_key[] =
|
||||
{ "ro.boot.vbmeta.device_state", "ro.boot.verifiedbootstate", "ro.boot.flash.locked", "ro.boot.veritymode",
|
||||
@ -63,6 +63,54 @@ static void rm_magisk_prop(const char *name, const char *value, void *v) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Call func for each process */
|
||||
static void ps(void (*func)(int)) {
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
|
||||
if (!(dir = xopendir("/proc")))
|
||||
return;
|
||||
|
||||
while ((entry = xreaddir(dir))) {
|
||||
if (entry->d_type == DT_DIR) {
|
||||
if (is_num(entry->d_name))
|
||||
func(atoi(entry->d_name));
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
static int check_proc_name(int pid, const char *name) {
|
||||
char buf[128];
|
||||
FILE *f;
|
||||
sprintf(buf, "/proc/%d/comm", pid);
|
||||
if ((f = fopen(buf, "r"))) {
|
||||
fgets(buf, sizeof(buf), f);
|
||||
if (strcmp(buf, name) == 0)
|
||||
return 1;
|
||||
} else {
|
||||
// The PID is already killed
|
||||
return 0;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
sprintf(buf, "/proc/%d/cmdline", pid);
|
||||
f = fopen(buf, "r");
|
||||
fgets(buf, sizeof(buf), f);
|
||||
fclose(f);
|
||||
if (strcmp(basename(buf), name) == 0)
|
||||
return 1;
|
||||
|
||||
sprintf(buf, "/proc/%d/exe", pid);
|
||||
if (access(buf, F_OK) != 0)
|
||||
return 0;
|
||||
xreadlink(buf, buf, sizeof(buf));
|
||||
if (strcmp(basename(buf), name) == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void kill_proc_cb(int pid) {
|
||||
if (check_proc_name(pid, proc_name))
|
||||
kill(pid, SIGTERM);
|
||||
|
@ -29,6 +29,8 @@
|
||||
#include "pts.h"
|
||||
#include "flags.h"
|
||||
|
||||
#define quit_signals ((int []) { SIGALRM, SIGABRT, SIGHUP, SIGPIPE, SIGQUIT, SIGTERM, SIGINT, 0 })
|
||||
|
||||
static void usage(int status) {
|
||||
FILE *stream = (status == EXIT_SUCCESS) ? stdout : stderr;
|
||||
|
||||
@ -84,6 +86,15 @@ static void sighandler(int sig) {
|
||||
}
|
||||
}
|
||||
|
||||
static void setup_sighandlers(void (*handler)(int)) {
|
||||
struct sigaction act;
|
||||
memset(&act, 0, sizeof(act));
|
||||
act.sa_handler = handler;
|
||||
for (int i = 0; quit_signals[i]; ++i) {
|
||||
sigaction(quit_signals[i], &act, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Connect daemon, send argc, argv, cwd, pts slave
|
||||
*/
|
||||
|
@ -20,13 +20,6 @@
|
||||
|
||||
// xwrap.c
|
||||
|
||||
#ifndef SOCK_CLOEXEC
|
||||
#define SOCK_CLOEXEC O_CLOEXEC
|
||||
#endif
|
||||
#ifndef SOCK_NONBLOCK
|
||||
#define SOCK_NONBLOCK O_NONBLOCK
|
||||
#endif
|
||||
|
||||
FILE *xfopen(const char *pathname, const char *mode);
|
||||
FILE *xfdopen(int fd, const char *mode);
|
||||
#define GET_MACRO(_1, _2, _3, NAME, ...) NAME
|
||||
@ -83,24 +76,17 @@ int xpoll(struct pollfd *fds, nfds_t nfds, int timeout);
|
||||
|
||||
// misc.c
|
||||
|
||||
#define quit_signals ((int []) { SIGALRM, SIGABRT, SIGHUP, SIGPIPE, SIGQUIT, SIGTERM, SIGINT, 0 })
|
||||
|
||||
unsigned get_shell_uid();
|
||||
unsigned get_system_uid();
|
||||
unsigned get_radio_uid();
|
||||
int check_data();
|
||||
int file_to_vector(const char* filename, struct vector *v);
|
||||
int vector_to_file(const char* filename, struct vector *v);
|
||||
ssize_t fdgets(char *buf, size_t size, int fd);
|
||||
void ps(void (*func)(int));
|
||||
int check_proc_name(int pid, const char *filter);
|
||||
void unlock_blocks();
|
||||
void setup_sighandlers(void (*handler)(int));
|
||||
int is_num(const char *s);
|
||||
int exec_array(int err, int *fd, void (*setenv)(struct vector *), char *const *argv);
|
||||
int exec_command(int err, int *fd, void (*setenv)(struct vector*), const char *argv0, ...);
|
||||
int exec_command_sync(char *const argv0, ...);
|
||||
int bind_mount(const char *from, const char *to);
|
||||
void get_client_cred(int fd, struct ucred *cred);
|
||||
int switch_mnt_ns(int pid);
|
||||
int fork_dont_care();
|
||||
void wait_till_exists(const char *target);
|
||||
@ -146,7 +132,6 @@ int setattrat(int dirfd, const char *pathname, struct file_attr *a);
|
||||
int fsetattr(int fd, struct file_attr *a);
|
||||
void fclone_attr(const int sourcefd, const int targetfd);
|
||||
void clone_attr(const char *source, const char *target);
|
||||
|
||||
void mmap_ro(const char *filename, void **buf, size_t *size);
|
||||
void mmap_rw(const char *filename, void **buf, size_t *size);
|
||||
void fd_full_read(int fd, void **buf, size_t *size);
|
||||
|
@ -22,7 +22,6 @@
|
||||
|
||||
#include "logging.h"
|
||||
#include "utils.h"
|
||||
#include "resetprop.h"
|
||||
#include "flags.h"
|
||||
|
||||
unsigned get_shell_uid() {
|
||||
@ -49,43 +48,6 @@ unsigned get_radio_uid() {
|
||||
return ppwd->pw_uid;
|
||||
}
|
||||
|
||||
int check_data() {
|
||||
struct vector v;
|
||||
vec_init(&v);
|
||||
file_to_vector("/proc/mounts", &v);
|
||||
char *line;
|
||||
int mnt = 0;
|
||||
vec_for_each(&v, line) {
|
||||
if (strstr(line, " /data ") && strstr(line, "tmpfs") == NULL) {
|
||||
mnt = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
vec_deep_destroy(&v);
|
||||
int data = 0;
|
||||
if (mnt) {
|
||||
char *crypto = getprop("ro.crypto.state");
|
||||
if (crypto != NULL) {
|
||||
if (strcmp(crypto, "unencrypted") == 0) {
|
||||
// Unencrypted, we can directly access data
|
||||
data = 1;
|
||||
} else {
|
||||
// Encrypted, check whether vold is started
|
||||
char *vold = getprop("init.svc.vold");
|
||||
if (vold != NULL) {
|
||||
free(vold);
|
||||
data = 1;
|
||||
}
|
||||
}
|
||||
free(crypto);
|
||||
} else {
|
||||
// ro.crypto.state is not set, assume it's unencrypted
|
||||
data = 1;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/* All the string should be freed manually!! */
|
||||
int file_to_vector(const char* filename, struct vector *v) {
|
||||
if (access(filename, R_OK) != 0)
|
||||
@ -122,7 +84,7 @@ int vector_to_file(const char *filename, struct vector *v) {
|
||||
}
|
||||
|
||||
/* Check if the string only contains digits */
|
||||
static int is_num(const char *s) {
|
||||
int is_num(const char *s) {
|
||||
int len = strlen(s);
|
||||
for (int i = 0; i < len; ++i)
|
||||
if (s[i] < '0' || s[i] > '9')
|
||||
@ -149,84 +111,6 @@ ssize_t fdgets(char *buf, const size_t size, int fd) {
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Call func for each process */
|
||||
void ps(void (*func)(int)) {
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
|
||||
if (!(dir = xopendir("/proc")))
|
||||
return;
|
||||
|
||||
while ((entry = xreaddir(dir))) {
|
||||
if (entry->d_type == DT_DIR) {
|
||||
if (is_num(entry->d_name))
|
||||
func(atoi(entry->d_name));
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
int check_proc_name(int pid, const char *name) {
|
||||
char buf[128];
|
||||
FILE *f;
|
||||
sprintf(buf, "/proc/%d/comm", pid);
|
||||
if ((f = fopen(buf, "r"))) {
|
||||
fgets(buf, sizeof(buf), f);
|
||||
if (strcmp(buf, name) == 0)
|
||||
return 1;
|
||||
} else {
|
||||
// The PID is already killed
|
||||
return 0;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
sprintf(buf, "/proc/%d/cmdline", pid);
|
||||
f = fopen(buf, "r");
|
||||
fgets(buf, sizeof(buf), f);
|
||||
fclose(f);
|
||||
if (strcmp(basename(buf), name) == 0)
|
||||
return 1;
|
||||
|
||||
sprintf(buf, "/proc/%d/exe", pid);
|
||||
if (access(buf, F_OK) != 0)
|
||||
return 0;
|
||||
xreadlink(buf, buf, sizeof(buf));
|
||||
if (strcmp(basename(buf), name) == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void unlock_blocks() {
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
int fd, dev, OFF = 0;
|
||||
|
||||
if ((dev = xopen("/dev/block", O_RDONLY | O_CLOEXEC)) < 0)
|
||||
return;
|
||||
dir = xfdopendir(dev);
|
||||
|
||||
while((entry = readdir(dir))) {
|
||||
if (entry->d_type == DT_BLK) {
|
||||
if ((fd = openat(dev, entry->d_name, O_RDONLY)) < 0)
|
||||
continue;
|
||||
if (ioctl(fd, BLKROSET, &OFF) == -1)
|
||||
PLOGE("unlock %s", entry->d_name);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
close(dev);
|
||||
}
|
||||
|
||||
void setup_sighandlers(void (*handler)(int)) {
|
||||
struct sigaction act;
|
||||
memset(&act, 0, sizeof(act));
|
||||
act.sa_handler = handler;
|
||||
for (int i = 0; quit_signals[i]; ++i) {
|
||||
sigaction(quit_signals[i], &act, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
fd == NULL -> Ignore output
|
||||
*fd < 0 -> Open pipe and set *fd to the read end
|
||||
@ -324,12 +208,6 @@ int bind_mount(const char *from, const char *to) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void get_client_cred(int fd, struct ucred *cred) {
|
||||
socklen_t ucred_length = sizeof(*cred);
|
||||
if(getsockopt(fd, SOL_SOCKET, SO_PEERCRED, cred, &ucred_length))
|
||||
PLOGE("getsockopt");
|
||||
}
|
||||
|
||||
int switch_mnt_ns(int pid) {
|
||||
char mnt[32];
|
||||
snprintf(mnt, sizeof(mnt), "/proc/%d/ns/mnt", pid);
|
||||
|
Loading…
Reference in New Issue
Block a user