Reorganize libutils and cleanups

This commit is contained in:
topjohnwu 2018-10-12 21:46:09 -04:00
parent d5a56d9e85
commit a9121fa28f
7 changed files with 128 additions and 147 deletions

View File

@ -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 *
****************/

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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
*/

View File

@ -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);

View File

@ -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);