Commit cda57dd4 authored by topjohnwu's avatar topjohnwu

Fully migrate Magisk to C++

parent 4351de50
...@@ -32,14 +32,14 @@ LOCAL_C_INCLUDES := \ ...@@ -32,14 +32,14 @@ LOCAL_C_INCLUDES := \
$(LIBUTILS) $(LIBUTILS)
LOCAL_SRC_FILES := \ LOCAL_SRC_FILES := \
misc/applets.c \ misc/applets.cpp \
misc/img.c \ misc/img.cpp \
daemon/magisk.c \ daemon/magisk.cpp \
daemon/daemon.c \ daemon/daemon.cpp \
daemon/log_daemon.c \ daemon/log_daemon.cpp \
daemon/bootstages.c \ daemon/bootstages.cpp \
daemon/socket.c \ daemon/socket.cpp \
daemon/db.c \ daemon/db.cpp \
magiskhide/magiskhide.cpp \ magiskhide/magiskhide.cpp \
magiskhide/proc_monitor.cpp \ magiskhide/proc_monitor.cpp \
magiskhide/hide_utils.cpp \ magiskhide/hide_utils.cpp \
...@@ -47,10 +47,10 @@ LOCAL_SRC_FILES := \ ...@@ -47,10 +47,10 @@ LOCAL_SRC_FILES := \
resetprop/resetprop.cpp \ resetprop/resetprop.cpp \
resetprop/system_property_api.cpp \ resetprop/system_property_api.cpp \
resetprop/system_property_set.cpp \ resetprop/system_property_set.cpp \
su/su.c \ su/su.cpp \
su/connect.c \ su/connect.cpp \
su/pts.c \ su/pts.cpp \
su/su_daemon.c su/su_daemon.cpp
LOCAL_LDLIBS := -llog LOCAL_LDLIBS := -llog
include $(BUILD_EXECUTABLE) include $(BUILD_EXECUTABLE)
......
...@@ -31,7 +31,7 @@ static void get_client_cred(int fd, struct ucred *cred) { ...@@ -31,7 +31,7 @@ static void get_client_cred(int fd, struct ucred *cred) {
static void *request_handler(void *args) { static void *request_handler(void *args) {
int client = *((int *) args); int client = *((int *) args);
free(args); delete (int *) args;
int req = read_int(client); int req = read_int(client);
struct ucred credential; struct ucred credential;
...@@ -88,7 +88,7 @@ static void *request_handler(void *args) { ...@@ -88,7 +88,7 @@ static void *request_handler(void *args) {
static void main_daemon() { static void main_daemon() {
android_logging(); android_logging();
setsid(); setsid();
setcon("u:r:"SEPOL_PROC_DOMAIN":s0"); setcon("u:r:" SEPOL_PROC_DOMAIN ":s0");
int fd = xopen("/dev/null", O_RDWR | O_CLOEXEC); int fd = xopen("/dev/null", O_RDWR | O_CLOEXEC);
xdup2(fd, STDOUT_FILENO); xdup2(fd, STDOUT_FILENO);
xdup2(fd, STDERR_FILENO); xdup2(fd, STDERR_FILENO);
...@@ -123,7 +123,7 @@ static void main_daemon() { ...@@ -123,7 +123,7 @@ static void main_daemon() {
// Loop forever to listen for requests // Loop forever to listen for requests
while(1) { while(1) {
int *client = xmalloc(sizeof(int)); int *client = new int;
*client = xaccept4(fd, NULL, NULL, SOCK_CLOEXEC); *client = xaccept4(fd, NULL, NULL, SOCK_CLOEXEC);
pthread_t thread; pthread_t thread;
xpthread_create(&thread, NULL, request_handler, client); xpthread_create(&thread, NULL, request_handler, client);
......
...@@ -10,8 +10,8 @@ ...@@ -10,8 +10,8 @@
#define DB_VERSION 7 #define DB_VERSION 7
static int ver_cb(void *v, int col_num, char **data, char **col_name) { static int ver_cb(void *ver, int, char **data, char **) {
*((int *) v) = atoi(data[0]); *((int *) ver) = atoi(data[0]);
return 0; return 0;
} }
...@@ -19,7 +19,7 @@ static int ver_cb(void *v, int col_num, char **data, char **col_name) { ...@@ -19,7 +19,7 @@ static int ver_cb(void *v, int col_num, char **data, char **col_name) {
if (err) { \ if (err) { \
LOGE("sqlite3_exec: %s\n", err); \ LOGE("sqlite3_exec: %s\n", err); \
sqlite3_free(err); \ sqlite3_free(err); \
return NULL; \ return nullptr; \
} }
static sqlite3 *open_and_init_db() { static sqlite3 *open_and_init_db() {
...@@ -27,7 +27,7 @@ static sqlite3 *open_and_init_db() { ...@@ -27,7 +27,7 @@ static sqlite3 *open_and_init_db() {
int ret = sqlite3_open(MAGISKDB, &db); int ret = sqlite3_open(MAGISKDB, &db);
if (ret) { if (ret) {
LOGE("sqlite3 open failure: %s\n", sqlite3_errstr(ret)); LOGE("sqlite3 open failure: %s\n", sqlite3_errstr(ret));
return NULL; return nullptr;
} }
int ver, upgrade = 0; int ver, upgrade = 0;
char *err; char *err;
...@@ -36,7 +36,7 @@ static sqlite3 *open_and_init_db() { ...@@ -36,7 +36,7 @@ static sqlite3 *open_and_init_db() {
if (ver > DB_VERSION) { if (ver > DB_VERSION) {
// Don't support downgrading database // Don't support downgrading database
sqlite3_close_v2(db); sqlite3_close_v2(db);
return NULL; return nullptr;
} }
if (ver < 3) { if (ver < 3) {
// Policies // Policies
...@@ -44,20 +44,20 @@ static sqlite3 *open_and_init_db() { ...@@ -44,20 +44,20 @@ static sqlite3 *open_and_init_db() {
"CREATE TABLE IF NOT EXISTS policies " "CREATE TABLE IF NOT EXISTS policies "
"(uid INT, package_name TEXT, policy INT, until INT, " "(uid INT, package_name TEXT, policy INT, until INT, "
"logging INT, notification INT, PRIMARY KEY(uid))", "logging INT, notification INT, PRIMARY KEY(uid))",
NULL, NULL, &err); nullptr, nullptr, &err);
err_abort(err); err_abort(err);
// Logs // Logs
sqlite3_exec(db, sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS logs " "CREATE TABLE IF NOT EXISTS logs "
"(from_uid INT, package_name TEXT, app_name TEXT, from_pid INT, " "(from_uid INT, package_name TEXT, app_name TEXT, from_pid INT, "
"to_uid INT, action INT, time INT, command TEXT)", "to_uid INT, action INT, time INT, command TEXT)",
NULL, NULL, &err); nullptr, nullptr, &err);
err_abort(err); err_abort(err);
// Settings // Settings
sqlite3_exec(db, sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS settings " "CREATE TABLE IF NOT EXISTS settings "
"(key TEXT, value INT, PRIMARY KEY(key))", "(key TEXT, value INT, PRIMARY KEY(key))",
NULL, NULL, &err); nullptr, nullptr, &err);
err_abort(err); err_abort(err);
ver = 3; ver = 3;
upgrade = 1; upgrade = 1;
...@@ -67,13 +67,13 @@ static sqlite3 *open_and_init_db() { ...@@ -67,13 +67,13 @@ static sqlite3 *open_and_init_db() {
sqlite3_exec(db, sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS strings " "CREATE TABLE IF NOT EXISTS strings "
"(key TEXT, value TEXT, PRIMARY KEY(key))", "(key TEXT, value TEXT, PRIMARY KEY(key))",
NULL, NULL, &err); nullptr, nullptr, &err);
err_abort(err); err_abort(err);
ver = 4; ver = 4;
upgrade = 1; upgrade = 1;
} }
if (ver == 4) { if (ver == 4) {
sqlite3_exec(db, "UPDATE policies SET uid=uid%100000", NULL, NULL, &err); sqlite3_exec(db, "UPDATE policies SET uid=uid%100000", nullptr, nullptr, &err);
err_abort(err); err_abort(err);
/* Skip version 5 */ /* Skip version 5 */
ver = 6; ver = 6;
...@@ -84,7 +84,7 @@ static sqlite3 *open_and_init_db() { ...@@ -84,7 +84,7 @@ static sqlite3 *open_and_init_db() {
sqlite3_exec(db, sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS hidelist " "CREATE TABLE IF NOT EXISTS hidelist "
"(process TEXT, PRIMARY KEY(process))", "(process TEXT, PRIMARY KEY(process))",
NULL, NULL, &err); nullptr, nullptr, &err);
err_abort(err); err_abort(err);
ver = 7; ver = 7;
upgrade =1 ; upgrade =1 ;
...@@ -94,7 +94,7 @@ static sqlite3 *open_and_init_db() { ...@@ -94,7 +94,7 @@ static sqlite3 *open_and_init_db() {
// Set version // Set version
char query[32]; char query[32];
sprintf(query, "PRAGMA user_version=%d", ver); sprintf(query, "PRAGMA user_version=%d", ver);
sqlite3_exec(db, query, NULL, NULL, &err); sqlite3_exec(db, query, nullptr, nullptr, &err);
err_abort(err); err_abort(err);
} }
return db; return db;
...@@ -102,7 +102,7 @@ static sqlite3 *open_and_init_db() { ...@@ -102,7 +102,7 @@ static sqlite3 *open_and_init_db() {
sqlite3 *get_magiskdb() { sqlite3 *get_magiskdb() {
sqlite3 *db = open_and_init_db(); sqlite3 *db = open_and_init_db();
if (db == NULL) { if (db == nullptr) {
// Open fails, remove and reconstruct // Open fails, remove and reconstruct
unlink(MAGISKDB); unlink(MAGISKDB);
db = open_and_init_db(); db = open_and_init_db();
...@@ -111,7 +111,7 @@ sqlite3 *get_magiskdb() { ...@@ -111,7 +111,7 @@ sqlite3 *get_magiskdb() {
} }
static int settings_cb(void *v, int col_num, char **data, char **col_name) { static int settings_cb(void *v, int col_num, char **data, char **col_name) {
struct db_settings *dbs = v; auto dbs = (db_settings *) v;
int key = -1, value; int key = -1, value;
for (int i = 0; i < col_num; ++i) { for (int i = 0; i < col_num; ++i) {
if (strcmp(col_name[i], "key") == 0) { if (strcmp(col_name[i], "key") == 0) {
...@@ -131,7 +131,7 @@ static int settings_cb(void *v, int col_num, char **data, char **col_name) { ...@@ -131,7 +131,7 @@ static int settings_cb(void *v, int col_num, char **data, char **col_name) {
} }
int get_db_settings(sqlite3 *db, int key, struct db_settings *dbs) { int get_db_settings(sqlite3 *db, int key, struct db_settings *dbs) {
if (db == NULL) if (db == nullptr)
return 1; return 1;
char *err; char *err;
if (key > 0) { if (key > 0) {
...@@ -150,7 +150,7 @@ int get_db_settings(sqlite3 *db, int key, struct db_settings *dbs) { ...@@ -150,7 +150,7 @@ int get_db_settings(sqlite3 *db, int key, struct db_settings *dbs) {
} }
static int strings_cb(void *v, int col_num, char **data, char **col_name) { static int strings_cb(void *v, int col_num, char **data, char **col_name) {
struct db_strings *dbs = v; auto dbs = (db_strings *) v;
int key = -1; int key = -1;
char *value; char *value;
for (int i = 0; i < col_num; ++i) { for (int i = 0; i < col_num; ++i) {
...@@ -171,7 +171,7 @@ static int strings_cb(void *v, int col_num, char **data, char **col_name) { ...@@ -171,7 +171,7 @@ static int strings_cb(void *v, int col_num, char **data, char **col_name) {
} }
int get_db_strings(sqlite3 *db, int key, struct db_strings *str) { int get_db_strings(sqlite3 *db, int key, struct db_strings *str) {
if (db == NULL) if (db == nullptr)
return 1; return 1;
char *err; char *err;
if (key > 0) { if (key > 0) {
...@@ -190,7 +190,7 @@ int get_db_strings(sqlite3 *db, int key, struct db_strings *str) { ...@@ -190,7 +190,7 @@ int get_db_strings(sqlite3 *db, int key, struct db_strings *str) {
} }
static int policy_cb(void *v, int col_num, char **data, char **col_name) { static int policy_cb(void *v, int col_num, char **data, char **col_name) {
struct su_access *su = v; auto su = (su_access *) v;
for (int i = 0; i < col_num; i++) { for (int i = 0; i < col_num; i++) {
if (strcmp(col_name[i], "policy") == 0) if (strcmp(col_name[i], "policy") == 0)
su->policy = (policy_t) atoi(data[i]); su->policy = (policy_t) atoi(data[i]);
...@@ -204,11 +204,11 @@ static int policy_cb(void *v, int col_num, char **data, char **col_name) { ...@@ -204,11 +204,11 @@ static int policy_cb(void *v, int col_num, char **data, char **col_name) {
} }
int get_uid_policy(sqlite3 *db, int uid, struct su_access *su) { int get_uid_policy(sqlite3 *db, int uid, struct su_access *su) {
if (db == NULL) if (db == nullptr)
return 1; return 1;
char query[256], *err; char query[256], *err;
sprintf(query, "SELECT policy, logging, notification FROM policies " sprintf(query, "SELECT policy, logging, notification FROM policies "
"WHERE uid=%d AND (until=0 OR until>%li)", uid, time(NULL)); "WHERE uid=%d AND (until=0 OR until>%li)", uid, time(nullptr));
sqlite3_exec(db, query, policy_cb, su, &err); sqlite3_exec(db, query, policy_cb, su, &err);
if (err) { if (err) {
LOGE("sqlite3_exec: %s\n", err); LOGE("sqlite3_exec: %s\n", err);
...@@ -219,7 +219,7 @@ int get_uid_policy(sqlite3 *db, int uid, struct su_access *su) { ...@@ -219,7 +219,7 @@ int get_uid_policy(sqlite3 *db, int uid, struct su_access *su) {
} }
int validate_manager(char *alt_pkg, int userid, struct stat *st) { int validate_manager(char *alt_pkg, int userid, struct stat *st) {
if (st == NULL) { if (st == nullptr) {
struct stat stat; struct stat stat;
st = &stat; st = &stat;
} }
...@@ -229,7 +229,7 @@ int validate_manager(char *alt_pkg, int userid, struct stat *st) { ...@@ -229,7 +229,7 @@ int validate_manager(char *alt_pkg, int userid, struct stat *st) {
sprintf(app_path, "%s/%d/%s", base, userid, alt_pkg[0] ? alt_pkg : "xxx"); sprintf(app_path, "%s/%d/%s", base, userid, alt_pkg[0] ? alt_pkg : "xxx");
if (stat(app_path, st)) { if (stat(app_path, st)) {
// Check the official package name // Check the official package name
sprintf(app_path, "%s/%d/"JAVA_PACKAGE_NAME, base, userid); sprintf(app_path, "%s/%d/" JAVA_PACKAGE_NAME, base, userid);
if (stat(app_path, st)) { if (stat(app_path, st)) {
LOGE("su: cannot find manager"); LOGE("su: cannot find manager");
memset(st, 0, sizeof(*st)); memset(st, 0, sizeof(*st));
...@@ -256,7 +256,7 @@ int exec_sql(const char *sql) { ...@@ -256,7 +256,7 @@ int exec_sql(const char *sql) {
sqlite3 *db = get_magiskdb(); sqlite3 *db = get_magiskdb();
if (db) { if (db) {
char *err; char *err;
sqlite3_exec(db, sql, print_cb, NULL, &err); sqlite3_exec(db, sql, print_cb, nullptr, &err);
sqlite3_close_v2(db); sqlite3_close_v2(db);
if (err) { if (err) {
fprintf(stderr, "sql_err: %s\n", err); fprintf(stderr, "sql_err: %s\n", err);
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include "flags.h" #include "flags.h"
int log_daemon_started = 0; int log_daemon_started = 0;
static struct vector log_cmd, clear_cmd; static Array<const char *> log_cmd, clear_cmd;
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
enum { enum {
...@@ -33,7 +33,7 @@ struct log_listener { ...@@ -33,7 +33,7 @@ struct log_listener {
}; };
static int am_proc_start_filter(const char *log) { static int am_proc_start_filter(const char *log) {
return strstr(log, "am_proc_start") != NULL; return strstr(log, "am_proc_start") != nullptr;
} }
static int magisk_log_filter(const char *log) { static int magisk_log_filter(const char *log) {
...@@ -52,17 +52,17 @@ static struct log_listener events[] = { ...@@ -52,17 +52,17 @@ static struct log_listener events[] = {
}; };
#define EVENT_NUM (sizeof(events) / sizeof(struct log_listener)) #define EVENT_NUM (sizeof(events) / sizeof(struct log_listener))
static void sigpipe_handler(int sig) { static void sigpipe_handler(int) {
close(events[HIDE_EVENT].fd); close(events[HIDE_EVENT].fd);
events[HIDE_EVENT].fd = -1; events[HIDE_EVENT].fd = -1;
} }
static void *monitor_thread(void *args) { static void *monitor_thread(void *) {
// Block SIGPIPE to prevent interruption // Block SIGPIPE to prevent interruption
sigset_t block_set; sigset_t block_set;
sigemptyset(&block_set); sigemptyset(&block_set);
sigaddset(&block_set, SIGPIPE); sigaddset(&block_set, SIGPIPE);
pthread_sigmask(SIG_SETMASK, &block_set, NULL); pthread_sigmask(SIG_SETMASK, &block_set, nullptr);
// Give the main daemon some time before we monitor it // Give the main daemon some time before we monitor it
sleep(5); sleep(5);
int fd; int fd;
...@@ -77,12 +77,12 @@ static void *monitor_thread(void *args) { ...@@ -77,12 +77,12 @@ static void *monitor_thread(void *args) {
} }
} }
static void *logcat_thread(void *args) { static void *logcat_thread(void *) {
int log_fd = -1, log_pid; int log_fd = -1, log_pid;
char line[4096]; char line[4096];
while (1) { while (1) {
// Start logcat // Start logcat
log_pid = exec_array(0, &log_fd, NULL, (const char **) vec_entry(&log_cmd)); log_pid = exec_array(0, &log_fd, nullptr, log_cmd.data());
FILE *logs = fdopen(log_fd, "r"); FILE *logs = fdopen(log_fd, "r");
while (fgets(line, sizeof(line), logs)) { while (fgets(line, sizeof(line), logs)) {
if (line[0] == '-') if (line[0] == '-')
...@@ -99,12 +99,12 @@ static void *logcat_thread(void *args) { ...@@ -99,12 +99,12 @@ static void *logcat_thread(void *args) {
fclose(logs); fclose(logs);
log_fd = -1; log_fd = -1;
kill(log_pid, SIGTERM); kill(log_pid, SIGTERM);
waitpid(log_pid, NULL, 0); waitpid(log_pid, nullptr, 0);
LOGI("magisklogd: logcat output EOF"); LOGI("magisklogd: logcat output EOF");
// Clear buffer // Clear buffer
log_pid = exec_array(0, NULL, NULL, (const char **) vec_entry(&clear_cmd)); log_pid = exec_array(0, nullptr, nullptr, clear_cmd.data());
waitpid(log_pid, NULL, 0); waitpid(log_pid, nullptr, 0);
} }
} }
...@@ -117,36 +117,42 @@ static void log_daemon() { ...@@ -117,36 +117,42 @@ static void log_daemon() {
struct sigaction act; struct sigaction act;
memset(&act, 0, sizeof(act)); memset(&act, 0, sizeof(act));
act.sa_handler = sigpipe_handler; act.sa_handler = sigpipe_handler;
sigaction(SIGPIPE, &act, NULL); sigaction(SIGPIPE, &act, nullptr);
// Setup log dumps // Setup log dumps
rename(LOGFILE, LOGFILE ".bak"); rename(LOGFILE, LOGFILE ".bak");
events[LOG_EVENT].fd = xopen(LOGFILE, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC | O_APPEND, 0644); events[LOG_EVENT].fd = xopen(LOGFILE, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC | O_APPEND, 0644);
// Construct cmdline // Construct cmdline
vec_init(&log_cmd); log_cmd.push_back(MIRRDIR "/system/bin/logcat");
vec_push_back(&log_cmd, MIRRDIR "/system/bin/logcat");
// Test whether these buffers actually works // Test whether these buffers actually works
const char* b[] = { "main", "events", "crash" }; const char* b[] = { "main", "events", "crash" };
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
if (exec_command_sync(MIRRDIR "/system/bin/logcat", "-b", b[i], "-d", "-f", "/dev/null", NULL) == 0) if (exec_command_sync(MIRRDIR "/system/bin/logcat", "-b", b[i], "-d", "-f", "/dev/null", nullptr) == 0) {
vec_push_back_all(&log_cmd, "-b", b[i], NULL); log_cmd.push_back("-b");
log_cmd.push_back(b[i]);
}
} }
chmod("/dev/null", 0666); chmod("/dev/null", 0666);
vec_dup(&log_cmd, &clear_cmd); clear_cmd = log_cmd;
vec_push_back_all(&log_cmd, "-v", "threadtime", "-s", "am_proc_start", "Magisk", NULL); log_cmd.push_back("-v");
log_cmd.push_back("threadtime");
log_cmd.push_back("-s");
log_cmd.push_back("am_proc_start");
log_cmd.push_back("Magisk");
#ifdef MAGISK_DEBUG #ifdef MAGISK_DEBUG
vec_push_back(&log_cmd, "*:F"); log_cmd.push_back("*:F");
#endif #endif
vec_push_back(&log_cmd, NULL); log_cmd.push_back(nullptr);
vec_push_back(&clear_cmd, "-c");
vec_push_back(&clear_cmd, NULL); clear_cmd.push_back("-c");
clear_cmd.push_back(nullptr);
// Start worker threads // Start worker threads
pthread_t thread; pthread_t thread;
pthread_create(&thread, NULL, monitor_thread, NULL); pthread_create(&thread, nullptr, monitor_thread, nullptr);
pthread_detach(thread); pthread_detach(thread);
xpthread_create(&thread, NULL, logcat_thread, NULL); xpthread_create(&thread, nullptr, logcat_thread, nullptr);
pthread_detach(thread); pthread_detach(thread);
// Handle socket requests // Handle socket requests
...@@ -157,7 +163,7 @@ static void log_daemon() { ...@@ -157,7 +163,7 @@ static void log_daemon() {
exit(1); exit(1);
xlisten(sockfd, 10); xlisten(sockfd, 10);
while(1) { while(1) {
int fd = xaccept4(sockfd, NULL, NULL, SOCK_CLOEXEC); int fd = xaccept4(sockfd, nullptr, nullptr, SOCK_CLOEXEC);
switch(read_int(fd)) { switch(read_int(fd)) {
case HIDE_CONNECT: case HIDE_CONNECT:
pthread_mutex_lock(&lock); pthread_mutex_lock(&lock);
...@@ -175,7 +181,7 @@ static void log_daemon() { ...@@ -175,7 +181,7 @@ static void log_daemon() {
int start_log_daemon() { int start_log_daemon() {
if (!log_daemon_started) { if (!log_daemon_started) {
if (exec_command_sync(MIRRDIR "/system/bin/logcat", "-d", "-f", "/dev/null", NULL) == 0) { if (exec_command_sync(MIRRDIR "/system/bin/logcat", "-d", "-f", "/dev/null", nullptr) == 0) {
if (fork_dont_care() == 0) if (fork_dont_care() == 0)
log_daemon(); log_daemon();
log_daemon_started = 1; log_daemon_started = 1;
......
...@@ -26,7 +26,7 @@ static int create_links(const char *bin, const char *path) { ...@@ -26,7 +26,7 @@ static int create_links(const char *bin, const char *path) {
return ret; return ret;
} }
static void usage() { [[noreturn]] static void usage() {
fprintf(stderr, fprintf(stderr,
"Magisk v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") (by topjohnwu) multi-call binary\n" "Magisk v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") (by topjohnwu) multi-call binary\n"
"\n" "\n"
...@@ -117,5 +117,4 @@ int magisk_main(int argc, char *argv[]) { ...@@ -117,5 +117,4 @@ int magisk_main(int argc, char *argv[]) {
} }
usage(); usage();
return 1;
} }
...@@ -50,6 +50,7 @@ int socket_accept(int sockfd, int timeout) { ...@@ -50,6 +50,7 @@ int socket_accept(int sockfd, int timeout) {
int recv_fd(int sockfd) { int recv_fd(int sockfd) {
// Need to receive data from the message, otherwise don't care about it. // Need to receive data from the message, otherwise don't care about it.
char iovbuf; char iovbuf;
struct cmsghdr *cmsg;
struct iovec iov = { struct iovec iov = {
.iov_base = &iovbuf, .iov_base = &iovbuf,
...@@ -79,7 +80,7 @@ int recv_fd(int sockfd) { ...@@ -79,7 +80,7 @@ int recv_fd(int sockfd) {
goto error; goto error;
} }
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); cmsg = CMSG_FIRSTHDR(&msg);
if (cmsg == NULL || if (cmsg == NULL ||
cmsg->cmsg_len != CMSG_LEN(sizeof(int)) || cmsg->cmsg_len != CMSG_LEN(sizeof(int)) ||
...@@ -104,8 +105,9 @@ error: ...@@ -104,8 +105,9 @@ error:
*/ */
void send_fd(int sockfd, int fd) { void send_fd(int sockfd, int fd) {
// Need to send some data in the message, this will do. // Need to send some data in the message, this will do.
char junk[] = { '\0' };
struct iovec iov = { struct iovec iov = {
.iov_base = "", .iov_base = junk,
.iov_len = 1, .iov_len = 1,
}; };
...@@ -166,7 +168,7 @@ void write_int_be(int fd, int val) { ...@@ -166,7 +168,7 @@ void write_int_be(int fd, int val) {
} }
static char *rd_str(int fd, int len) { static char *rd_str(int fd, int len) {
char* val = xmalloc(sizeof(char) * (len + 1)); char *val = (char *) xmalloc(sizeof(char) * (len + 1));
xxread(fd, val, len); xxread(fd, val, len);
val[len] = '\0'; val[len] = '\0';
return val; return val;
......
...@@ -4,10 +4,6 @@ ...@@ -4,10 +4,6 @@
#include <sqlite3.h> #include <sqlite3.h>
#include <sys/stat.h> #include <sys/stat.h>
#ifdef __cplusplus
extern "C" {
#endif
/*************** /***************
* DB Settings * * DB Settings *
***************/ ***************/
...@@ -19,7 +15,7 @@ extern "C" { ...@@ -19,7 +15,7 @@ extern "C" {
"mnt_ns" \ "mnt_ns" \
}) })
#define DB_SETTINGS_NUM (sizeof(DB_SETTING_KEYS) / sizeof(char*)) #define DB_SETTINGS_NUM 3
// Settings indices // Settings indices
enum { enum {
...@@ -52,15 +48,14 @@ enum { ...@@ -52,15 +48,14 @@ enum {
struct db_settings { struct db_settings {
int v[DB_SETTINGS_NUM]; int v[DB_SETTINGS_NUM];
db_settings()
: v {
ROOT_ACCESS_APPS_AND_ADB,
MULTIUSER_MODE_OWNER_ONLY,
NAMESPACE_MODE_REQUESTER
} {}
}; };
#define DEFAULT_DB_SETTINGS \
(struct db_settings) { .v = { \
ROOT_ACCESS_APPS_AND_ADB, \
MULTIUSER_MODE_OWNER_ONLY, \
NAMESPACE_MODE_REQUESTER, \
}}
/************** /**************
* DB Strings * * DB Strings *
**************/ **************/
...@@ -70,7 +65,7 @@ NAMESPACE_MODE_REQUESTER, \ ...@@ -70,7 +65,7 @@ NAMESPACE_MODE_REQUESTER, \
"requester", \ "requester", \
}) })
#define DB_STRING_NUM (sizeof(DB_STRING_KEYS) / sizeof(char*)) #define DB_STRING_NUM 1
// Strings indices // Strings indices
enum { enum {
...@@ -79,6 +74,10 @@ enum { ...@@ -79,6 +74,10 @@ enum {
struct db_strings { struct db_strings {
char s[DB_STRING_NUM][128]; char s[DB_STRING_NUM][128];
db_strings() {
for (int i = 0; i < DB_STRING_NUM; ++i)
s[i][0] = '\0';
}
}; };
/************* /*************
...@@ -97,19 +96,19 @@ struct su_access { ...@@ -97,19 +96,19 @@ struct su_access {
int notify; int notify;
}; };
#define DEFAULT_SU_ACCESS (struct su_access) { \ #define DEFAULT_SU_ACCESS (su_access) { \
.policy = QUERY, \ .policy = QUERY, \
.log = 1, \ .log = 1, \
.notify = 1 \ .notify = 1 \
} }
#define SILENT_SU_ACCESS (struct su_access) { \ #define SILENT_SU_ACCESS (su_access) { \
.policy = ALLOW, \ .policy = ALLOW, \
.log = 0, \ .log = 0, \
.notify = 0 \ .notify = 0 \
} }
#define NO_SU_ACCESS (struct su_access) { \ #define NO_SU_ACCESS (su_access) { \
.policy = DENY, \ .policy = DENY, \
.log = 0, \ .log = 0, \
.notify = 0 \ .notify = 0 \
...@@ -126,8 +125,4 @@ int get_uid_policy(sqlite3 *db, int uid, struct su_access *su); ...@@ -126,8 +125,4 @@ int get_uid_policy(sqlite3 *db, int uid, struct su_access *su);
int validate_manager(char *alt_pkg, int userid, struct stat *st); int validate_manager(char *alt_pkg, int userid, struct stat *st);
int exec_sql(const char *sql); int exec_sql(const char *sql);
#ifdef __cplusplus
}
#endif
#endif //DB_H #endif //DB_H
#ifndef IMG_H #ifndef IMG_H
#define IMG_H #define IMG_H
#ifdef __cplusplus
extern "C" {
#endif
int create_img(const char *img, int size); int create_img(const char *img, int size);
int resize_img(const char *img, int size); int resize_img(const char *img, int size);
char *mount_image(const char *img, const char *target); char *mount_image(const char *img, const char *target);
...@@ -8,4 +12,8 @@ int umount_image(const char *target, const char *device); ...@@ -8,4 +12,8 @@ int umount_image(const char *target, const char *device);
int merge_img(const char *source, const char *target); int merge_img(const char *source, const char *target);
int trim_img(const char *img, const char *mount, char *loop); int trim_img(const char *img, const char *mount, char *loop);
#ifdef __cplusplus
}
#endif
#endif //IMG_H #endif //IMG_H
...@@ -45,8 +45,8 @@ extern "C" { ...@@ -45,8 +45,8 @@ extern "C" {
extern char *argv0; /* For changing process name */ extern char *argv0; /* For changing process name */
#define applet_names ((char *[]) { "magisk", "su", "resetprop", "magiskhide", "imgtool", NULL }) #define applet_names ((const char *[]) { "magisk", "su", "resetprop", "magiskhide", "imgtool", NULL })
#define init_applet ((char *[]) { "magiskpolicy", "supolicy", NULL }) #define init_applet ((const char *[]) { "magiskpolicy", "supolicy", NULL })
extern int (*applet_main[]) (int, char *[]), (*init_applet_main[]) (int, char *[]); extern int (*applet_main[]) (int, char *[]), (*init_applet_main[]) (int, char *[]);
......
/* resetprop.h - API for resetprop /* resetprop.h - API for resetprop
*/ */
#ifndef _RESETPROP_H_ #pragma once
#define _RESETPROP_H_
#ifdef __cplusplus
extern "C" {
#endif
int prop_exist(const char *name); int prop_exist(const char *name);
int setprop(const char *name, const char *value); int setprop(const char *name, const char *value, const bool trigger = true);
int setprop2(const char *name, const char *value, const int trigger); char *getprop(const char *name, bool persist = false);
char *getprop(const char *name); void getprop(void (*callback)(const char *, const char *, void *), void *cookie, bool persist = false);
char *getprop2(const char *name, int persist); int deleteprop(const char *name, bool persist = false);
int deleteprop(const char *name); int load_prop_file(const char *filename, const bool trigger = true);
int deleteprop2(const char *name, const int persist);
int read_prop_file(const char* filename, const int trigger);
void getprop_all(void (*callback)(const char *, const char *, void *), void *cookie, int persist);
#ifdef __cplusplus
}
#endif
#endif
...@@ -51,7 +51,7 @@ void hide_sensitive_props() { ...@@ -51,7 +51,7 @@ void hide_sensitive_props() {
value = getprop(prop_key[i]); value = getprop(prop_key[i]);
if (value) { if (value) {
if (strcmp(value, prop_value[i]) != 0) if (strcmp(value, prop_value[i]) != 0)
setprop2(prop_key[i], prop_value[i], 0); setprop(prop_key[i], prop_value[i], false);
free(value); free(value);
} }
} }
...@@ -133,10 +133,10 @@ static void kill_process(const char *name) { ...@@ -133,10 +133,10 @@ static void kill_process(const char *name) {
void clean_magisk_props() { void clean_magisk_props() {
LOGD("hide_utils: Cleaning magisk props\n"); LOGD("hide_utils: Cleaning magisk props\n");
getprop_all([](const char *name, auto, auto) -> void { getprop([](const char *name, auto, auto) -> void {
if (strstr(name, "magisk")) if (strstr(name, "magisk"))
deleteprop2(name, 0); deleteprop(name);
}, nullptr, 0); }, nullptr, false);
} }
static int add_list(sqlite3 *db, char *proc) { static int add_list(sqlite3 *db, char *proc) {
......
...@@ -39,14 +39,14 @@ int launch_magiskhide() { ...@@ -39,14 +39,14 @@ int launch_magiskhide() {
if (!log_daemon_started) { if (!log_daemon_started) {
setprop(MAGISKHIDE_PROP, "0"); setprop(MAGISKHIDE_PROP, "0");
// Remove without actually removing persist props // Remove without actually removing persist props
deleteprop2(MAGISKHIDE_PROP, 0); deleteprop(MAGISKHIDE_PROP);
return LOGCAT_DISABLED; return LOGCAT_DISABLED;
} }
hide_enabled = 1; hide_enabled = 1;
LOGI("* Starting MagiskHide\n"); LOGI("* Starting MagiskHide\n");
deleteprop2(MAGISKHIDE_PROP, 1); deleteprop(MAGISKHIDE_PROP, true);
hide_sensitive_props(); hide_sensitive_props();
...@@ -77,7 +77,7 @@ int stop_magiskhide() { ...@@ -77,7 +77,7 @@ int stop_magiskhide() {
hide_enabled = 0; hide_enabled = 0;
setprop(MAGISKHIDE_PROP, "0"); setprop(MAGISKHIDE_PROP, "0");
// Remove without actually removing persist props // Remove without actually removing persist props
deleteprop2(MAGISKHIDE_PROP, 0); deleteprop(MAGISKHIDE_PROP);
pthread_kill(proc_monitor_thread, TERM_THREAD); pthread_kill(proc_monitor_thread, TERM_THREAD);
return DAEMON_SUCCESS; return DAEMON_SUCCESS;
......
...@@ -9,9 +9,7 @@ ...@@ -9,9 +9,7 @@
#define TERM_THREAD SIGUSR1 #define TERM_THREAD SIGUSR1
// Daemon entries // Daemon entries
extern "C" {
int launch_magiskhide(); int launch_magiskhide();
}
int stop_magiskhide(); int stop_magiskhide();
int add_list(int client); int add_list(int client);
int rm_list(int client); int rm_list(int client);
......
/* img.c - All image related functions /* img.cpp - All image related functions
*/ */
#include <unistd.h> #include <unistd.h>
......
...@@ -112,9 +112,9 @@ static int init_resetprop() { ...@@ -112,9 +112,9 @@ static int init_resetprop() {
return 0; return 0;
} }
static void print_props(int persist) { static void print_props(bool persist) {
auto prop_list = Array<prop_t>(); auto prop_list = Array<prop_t>();
getprop_all(collect_props, &prop_list, persist); getprop(collect_props, &prop_list, persist);
prop_list.sort(); prop_list.sort();
for (auto &prop : prop_list) for (auto &prop : prop_list)
printf("[%s]: [%s]\n", prop.name, prop.value); printf("[%s]: [%s]\n", prop.name, prop.value);
...@@ -129,12 +129,8 @@ int prop_exist(const char *name) { ...@@ -129,12 +129,8 @@ int prop_exist(const char *name) {
return __system_property_find(name) != nullptr; return __system_property_find(name) != nullptr;
} }
char *getprop(const char *name) {
return getprop2(name, 0);
}
// Get prop by name, return string (should free manually!) // Get prop by name, return string (should free manually!)
char *getprop2(const char *name, int persist) { char *getprop(const char *name, bool persist) {
if (!check_legal_property_name(name) || init_resetprop()) if (!check_legal_property_name(name) || init_resetprop())
return nullptr; return nullptr;
const prop_info *pi = __system_property_find(name); const prop_info *pi = __system_property_find(name);
...@@ -157,7 +153,7 @@ char *getprop2(const char *name, int persist) { ...@@ -157,7 +153,7 @@ char *getprop2(const char *name, int persist) {
} }
} }
void getprop_all(void (*callback)(const char *, const char *, void *), void *cookie, int persist) { void getprop(void (*callback)(const char *, const char *, void *), void *cookie, bool persist) {
if (init_resetprop()) return; if (init_resetprop()) return;
read_cb_t read_cb(callback, cookie); read_cb_t read_cb(callback, cookie);
__system_property_foreach(read_props, &read_cb); __system_property_foreach(read_props, &read_cb);
...@@ -167,11 +163,7 @@ void getprop_all(void (*callback)(const char *, const char *, void *), void *coo ...@@ -167,11 +163,7 @@ void getprop_all(void (*callback)(const char *, const char *, void *), void *coo
} }
} }
int setprop(const char *name, const char *value) { int setprop(const char *name, const char *value, const bool trigger) {
return setprop2(name, value, 1);
}
int setprop2(const char *name, const char *value, const int trigger) {
if (!check_legal_property_name(name)) if (!check_legal_property_name(name))
return 1; return 1;
if (init_resetprop()) if (init_resetprop())
...@@ -205,11 +197,7 @@ int setprop2(const char *name, const char *value, const int trigger) { ...@@ -205,11 +197,7 @@ int setprop2(const char *name, const char *value, const int trigger) {
return ret; return ret;
} }
int deleteprop(const char *name) { int deleteprop(const char *name, bool persist) {
return deleteprop2(name, 1);
}
int deleteprop2(const char *name, int persist) {
if (!check_legal_property_name(name)) if (!check_legal_property_name(name))
return 1; return 1;
if (init_resetprop()) return -1; if (init_resetprop()) return -1;
...@@ -221,7 +209,7 @@ int deleteprop2(const char *name, int persist) { ...@@ -221,7 +209,7 @@ int deleteprop2(const char *name, int persist) {
return __system_property_del(name) && !(persist && strncmp(name, "persist.", 8) == 0); return __system_property_del(name) && !(persist && strncmp(name, "persist.", 8) == 0);
} }
int read_prop_file(const char* filename, const int trigger) { int load_prop_file(const char *filename, const bool trigger) {
if (init_resetprop()) return -1; if (init_resetprop()) return -1;
LOGD("resetprop: Load prop file [%s]\n", filename); LOGD("resetprop: Load prop file [%s]\n", filename);
FILE *fp = fopen(filename, "r"); FILE *fp = fopen(filename, "r");
...@@ -255,7 +243,7 @@ int read_prop_file(const char* filename, const int trigger) { ...@@ -255,7 +243,7 @@ int read_prop_file(const char* filename, const int trigger) {
if ( ((pch == nullptr) || (i >= (pch - line))) || (pch >= line + read - 1) ) continue; if ( ((pch == nullptr) || (i >= (pch - line))) || (pch >= line + read - 1) ) continue;
// Separate the string // Separate the string
*pch = '\0'; *pch = '\0';
setprop2(line + i, pch + 1, trigger); setprop(line + i, pch + 1, trigger);
} }
free(line); free(line);
fclose(fp); fclose(fp);
...@@ -264,8 +252,8 @@ int read_prop_file(const char* filename, const int trigger) { ...@@ -264,8 +252,8 @@ int read_prop_file(const char* filename, const int trigger) {
int resetprop_main(int argc, char *argv[]) { int resetprop_main(int argc, char *argv[]) {
log_cb.d = [](auto fmt, auto ap) -> int { return verbose ? vfprintf(stderr, fmt, ap) : 0; }; log_cb.d = [](auto fmt, auto ap) -> int { return verbose ? vfprintf(stderr, fmt, ap) : 0; };
int trigger = 1, persist = 0; bool trigger = true, persist = false;
char *argv0 = argv[0], *prop; char *argv0 = argv[0], *prop;
--argc; --argc;
...@@ -277,9 +265,9 @@ int resetprop_main(int argc, char *argv[]) { ...@@ -277,9 +265,9 @@ int resetprop_main(int argc, char *argv[]) {
switch (argv[0][idx]) { switch (argv[0][idx]) {
case '-': case '-':
if (strcmp(argv[0], "--file") == 0 && argc == 2) { if (strcmp(argv[0], "--file") == 0 && argc == 2) {
return read_prop_file(argv[1], trigger); return load_prop_file(argv[1], trigger);
} else if (strcmp(argv[0], "--delete") == 0 && argc == 2) { } else if (strcmp(argv[0], "--delete") == 0 && argc == 2) {
return deleteprop2(argv[1], persist); return deleteprop(argv[1], persist);
} else if (strcmp(argv[0], "--help") == 0) { } else if (strcmp(argv[0], "--help") == 0) {
usage(argv0); usage(argv0);
} }
...@@ -309,13 +297,13 @@ int resetprop_main(int argc, char *argv[]) { ...@@ -309,13 +297,13 @@ int resetprop_main(int argc, char *argv[]) {
print_props(persist); print_props(persist);
return 0; return 0;
case 1: case 1:
prop = getprop2(argv[0], persist); prop = getprop(argv[0], persist);
if (prop == nullptr) return 1; if (prop == nullptr) return 1;
printf("%s\n", prop); printf("%s\n", prop);
free(prop); free(prop);
return 0; return 0;
case 2: case 2:
return setprop2(argv[0], argv[1], trigger); return setprop(argv[0], argv[1], trigger);
default: default:
usage(argv0); usage(argv0);
} }
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#define AM_PATH "/system/bin/app_process", "/system/bin", "com.android.commands.am.Am" #define AM_PATH "/system/bin/app_process", "/system/bin", "com.android.commands.am.Am"
static char *get_command(const struct su_request *to) { static const char *get_command(const struct su_request *to) {
if (to->command[0]) if (to->command[0])
return to->command; return to->command;
if (to->shell[0]) if (to->shell[0])
...@@ -27,7 +27,7 @@ static char *get_command(const struct su_request *to) { ...@@ -27,7 +27,7 @@ static char *get_command(const struct su_request *to) {
return DEFAULT_SHELL; return DEFAULT_SHELL;
} }
static void silent_run(char * const args[]) { static void silent_run(const char *args[]) {
if (fork_dont_care()) if (fork_dont_care())
return; return;
int zero = open("/dev/zero", O_RDONLY | O_CLOEXEC); int zero = open("/dev/zero", O_RDONLY | O_CLOEXEC);
...@@ -36,7 +36,7 @@ static void silent_run(char * const args[]) { ...@@ -36,7 +36,7 @@ static void silent_run(char * const args[]) {
xdup2(null, 1); xdup2(null, 1);
xdup2(null, 2); xdup2(null, 2);
setenv("CLASSPATH", "/system/framework/am.jar", 1); setenv("CLASSPATH", "/system/framework/am.jar", 1);
execv(args[0], args); execv(args[0], (char **) args);
PLOGE("exec am"); PLOGE("exec am");
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
...@@ -71,7 +71,7 @@ void app_log(struct su_context *ctx) { ...@@ -71,7 +71,7 @@ void app_log(struct su_context *ctx) {
char policy[2]; char policy[2];
sprintf(policy, "%d", ctx->info->access.policy); sprintf(policy, "%d", ctx->info->access.policy);
char *cmd[] = { const char *cmd[] = {
AM_PATH, "broadcast", AM_PATH, "broadcast",
"-a", "android.intent.action.BOOT_COMPLETED", "-a", "android.intent.action.BOOT_COMPLETED",
"-p", DB_STR(ctx->info, SU_MANAGER), "-p", DB_STR(ctx->info, SU_MANAGER),
...@@ -84,7 +84,7 @@ void app_log(struct su_context *ctx) { ...@@ -84,7 +84,7 @@ void app_log(struct su_context *ctx) {
"--ei", "policy", policy, "--ei", "policy", policy,
"--es", "command", get_command(&ctx->req), "--es", "command", get_command(&ctx->req),
"--ez", "notify", ctx->info->access.notify ? "true" : "false", "--ez", "notify", ctx->info->access.notify ? "true" : "false",
NULL nullptr
}; };
silent_run(cmd); silent_run(cmd);
} }
...@@ -101,7 +101,7 @@ void app_notify(struct su_context *ctx) { ...@@ -101,7 +101,7 @@ void app_notify(struct su_context *ctx) {
char policy[2]; char policy[2];
sprintf(policy, "%d", ctx->info->access.policy); sprintf(policy, "%d", ctx->info->access.policy);
char *cmd[] = { const char *cmd[] = {
AM_PATH, "broadcast", AM_PATH, "broadcast",
"-a", "android.intent.action.BOOT_COMPLETED", "-a", "android.intent.action.BOOT_COMPLETED",
"-p", DB_STR(ctx->info, SU_MANAGER), "-p", DB_STR(ctx->info, SU_MANAGER),
...@@ -110,7 +110,7 @@ void app_notify(struct su_context *ctx) { ...@@ -110,7 +110,7 @@ void app_notify(struct su_context *ctx) {
"--es", "action", "notify", "--es", "action", "notify",
"--ei", "from.uid", fromUid, "--ei", "from.uid", fromUid,
"--ei", "policy", policy, "--ei", "policy", policy,
NULL nullptr
}; };
silent_run(cmd); silent_run(cmd);
} }
...@@ -118,15 +118,15 @@ void app_notify(struct su_context *ctx) { ...@@ -118,15 +118,15 @@ void app_notify(struct su_context *ctx) {
void app_connect(const char *socket, struct su_info *info) { void app_connect(const char *socket, struct su_info *info) {
char user[8]; char user[8];
setup_user(user, info); setup_user(user, info);
char *cmd[] = { const char *cmd[] = {
AM_PATH, "broadcast", AM_PATH, "broadcast",
"-a", "android.intent.action.BOOT_COMPLETED", "-a", "android.intent.action.BOOT_COMPLETED",
"-p", DB_STR(info, SU_MANAGER), "-p", DB_STR(info, SU_MANAGER),
"-f", "0x00000020", "-f", "0x00000020",
"--user", user, "--user", user,
"--es", "action", "request", "--es", "action", "request",
"--es", "socket", (char *) socket, "--es", "socket", socket,
NULL nullptr
}; };
silent_run(cmd); silent_run(cmd);
} }
...@@ -135,4 +135,3 @@ void socket_send_request(int fd, struct su_info *info) { ...@@ -135,4 +135,3 @@ void socket_send_request(int fd, struct su_info *info) {
write_key_token(fd, "uid", info->uid); write_key_token(fd, "uid", info->uid);
write_string_be(fd, "eof"); write_string_be(fd, "eof");
} }
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
* helper functions to handle raw input mode and terminal window resizing * helper functions to handle raw input mode and terminal window resizing
*/ */
#define _GNU_SOURCE
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
/* su.c - The main function running in the daemon /* su.c - The main function running in the daemon
*/ */
#define _GNU_SOURCE
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
...@@ -95,6 +94,12 @@ static void setup_sighandlers(void (*handler)(int)) { ...@@ -95,6 +94,12 @@ static void setup_sighandlers(void (*handler)(int)) {
} }
} }
// Default values
su_req_base::su_req_base()
: uid(UID_ROOT), login(false), keepenv(false), mount_master(false) {}
su_request::su_request()
: shell(DEFAULT_SHELL), command("") {}
/* /*
* Connect daemon, send argc, argv, cwd, pts slave * Connect daemon, send argc, argv, cwd, pts slave
*/ */
...@@ -112,15 +117,7 @@ int su_client_main(int argc, char *argv[]) { ...@@ -112,15 +117,7 @@ int su_client_main(int argc, char *argv[]) {
{ NULL, 0, NULL, 0 }, { NULL, 0, NULL, 0 },
}; };
struct su_request su_req = { su_request su_req;
.uid = UID_ROOT,
.login = 0,
.keepenv = 0,
.mount_master = 0,
.shell = DEFAULT_SHELL,
.command = "",
};
for (int i = 0; i < argc; i++) { for (int i = 0; i < argc; i++) {
// Replace -cn with -z, -mm with -M for supporting getopt_long // Replace -cn with -z, -mm with -M for supporting getopt_long
...@@ -140,11 +137,11 @@ int su_client_main(int argc, char *argv[]) { ...@@ -140,11 +137,11 @@ int su_client_main(int argc, char *argv[]) {
usage(EXIT_SUCCESS); usage(EXIT_SUCCESS);
break; break;
case 'l': case 'l':
su_req.login = 1; su_req.login = true;
break; break;
case 'm': case 'm':
case 'p': case 'p':
su_req.keepenv = 1; su_req.keepenv = true;
break; break;
case 's': case 's':
su_req.shell = optarg; su_req.shell = optarg;
...@@ -159,7 +156,7 @@ int su_client_main(int argc, char *argv[]) { ...@@ -159,7 +156,7 @@ int su_client_main(int argc, char *argv[]) {
// Do nothing, placed here for legacy support :) // Do nothing, placed here for legacy support :)
break; break;
case 'M': case 'M':
su_req.mount_master = 1; su_req.mount_master = true;
break; break;
default: default:
/* Bionic getopt_long doesn't terminate its error output by newline */ /* Bionic getopt_long doesn't terminate its error output by newline */
...@@ -169,7 +166,7 @@ int su_client_main(int argc, char *argv[]) { ...@@ -169,7 +166,7 @@ int su_client_main(int argc, char *argv[]) {
} }
if (optind < argc && strcmp(argv[optind], "-") == 0) { if (optind < argc && strcmp(argv[optind], "-") == 0) {
su_req.login = 1; su_req.login = true;
optind++; optind++;
} }
/* username or uid */ /* username or uid */
...@@ -200,7 +197,7 @@ int su_client_main(int argc, char *argv[]) { ...@@ -200,7 +197,7 @@ int su_client_main(int argc, char *argv[]) {
} }
// Send su_request // Send su_request
xwrite(fd, &su_req, 4 * sizeof(unsigned)); xwrite(fd, &su_req, sizeof(su_req_base));
write_string(fd, su_req.shell); write_string(fd, su_req.shell);
write_string(fd, su_req.command); write_string(fd, su_req.command);
...@@ -242,4 +239,4 @@ int su_client_main(int argc, char *argv[]) { ...@@ -242,4 +239,4 @@ int su_client_main(int argc, char *argv[]) {
close(fd); close(fd);
return code; return code;
} }
\ No newline at end of file
...@@ -17,9 +17,9 @@ ...@@ -17,9 +17,9 @@
#define ATTY_OUT 2 #define ATTY_OUT 2
#define ATTY_ERR 4 #define ATTY_ERR 4
struct su_info { class su_info {
public:
unsigned uid; /* Unique key to find su_info */ unsigned uid; /* Unique key to find su_info */
pthread_mutex_t lock; /* Internal lock */
int count; /* Just a count for debugging purpose */ int count; /* Just a count for debugging purpose */
/* These values should be guarded with internal lock */ /* These values should be guarded with internal lock */
...@@ -31,19 +31,33 @@ struct su_info { ...@@ -31,19 +31,33 @@ struct su_info {
/* These should be guarded with global cache lock */ /* These should be guarded with global cache lock */
int ref; int ref;
int life; int life;
su_info(unsigned uid);
~su_info();
void lock();
void unlock();
private:
pthread_mutex_t _lock; /* Internal lock */
}; };
#define DB_SET(i, e) (i)->dbs.v[e] #define DB_SET(i, e) (i)->dbs.v[e]
#define DB_STR(i, e) (i)->str.s[e] #define DB_STR(i, e) (i)->str.s[e]
struct su_request { struct su_req_base {
unsigned uid; unsigned uid;
unsigned login; bool login;
unsigned keepenv; bool keepenv;
unsigned mount_master; bool mount_master;
char *shell; protected:
char *command; su_req_base();
}; } __attribute__((packed));
struct su_request : public su_req_base {
const char *shell;
const char *command;
su_request();
} __attribute__((packed));
struct su_context { struct su_context {
struct su_info *info; struct su_info *info;
......
/* su_daemon.c - The entrypoint for su, connect to daemon and send correct info
*/
#define _GNU_SOURCE
#include <unistd.h> #include <unistd.h>
#include <pthread.h> #include <pthread.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -25,32 +20,45 @@ ...@@ -25,32 +20,45 @@
#define TIMEOUT 3 #define TIMEOUT 3
#define LOCK_CACHE() pthread_mutex_lock(&cache_lock) #define LOCK_CACHE() pthread_mutex_lock(&cache_lock)
#define LOCK_INFO() pthread_mutex_lock(&info->lock)
#define UNLOCK_CACHE() pthread_mutex_unlock(&cache_lock) #define UNLOCK_CACHE() pthread_mutex_unlock(&cache_lock)
#define UNLOCK_INFO() pthread_mutex_unlock(&info->lock)
static pthread_mutex_t cache_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t cache_lock = PTHREAD_MUTEX_INITIALIZER;
static struct su_info *cache; static su_info *cache;
su_info::su_info(unsigned uid) :
uid(uid), access(DEFAULT_SU_ACCESS), _lock(PTHREAD_MUTEX_INITIALIZER),
count(0), ref(0), life(0), mgr_st({}) {}
su_info::~su_info() {
pthread_mutex_destroy(&_lock);
}
void su_info::lock() {
pthread_mutex_lock(&_lock);
}
void su_info::unlock() {
pthread_mutex_unlock(&_lock);
}
static void *info_collector(void *node) { static void *info_collector(void *node) {
struct su_info *info = node; su_info *info = (su_info *) node;
while (1) { while (1) {
sleep(1); sleep(1);
if (info->life) { if (info->life) {
LOCK_CACHE(); LOCK_CACHE();
if (--info->life == 0 && cache && info->uid == cache->uid) if (--info->life == 0 && cache && info->uid == cache->uid)
cache = NULL; cache = nullptr;
UNLOCK_CACHE(); UNLOCK_CACHE();
} }
if (!info->life && !info->ref) { if (!info->life && !info->ref) {
pthread_mutex_destroy(&info->lock); delete info;
free(info); return nullptr;
return NULL;
} }
} }
} }
static void database_check(struct su_info *info) { static void database_check(su_info *info) {
int uid = info->uid; int uid = info->uid;
sqlite3 *db = get_magiskdb(); sqlite3 *db = get_magiskdb();
if (db) { if (db) {
...@@ -84,20 +92,16 @@ static void database_check(struct su_info *info) { ...@@ -84,20 +92,16 @@ static void database_check(struct su_info *info) {
} }
static struct su_info *get_su_info(unsigned uid) { static struct su_info *get_su_info(unsigned uid) {
struct su_info *info; su_info *info;
int cache_miss = 0; bool cache_miss = false;
LOCK_CACHE(); LOCK_CACHE();
if (cache && cache->uid == uid) { if (cache && cache->uid == uid) {
info = cache; info = cache;
} else { } else {
cache_miss = 1; cache_miss = true;
info = xcalloc(1, sizeof(*info)); info = new su_info(uid);
info->uid = uid;
info->dbs = DEFAULT_DB_SETTINGS;
info->access = DEFAULT_SU_ACCESS;
pthread_mutex_init(&info->lock, NULL);
cache = info; cache = info;
} }
...@@ -108,7 +112,7 @@ static struct su_info *get_su_info(unsigned uid) { ...@@ -108,7 +112,7 @@ static struct su_info *get_su_info(unsigned uid) {
// Start a thread to maintain the cache // Start a thread to maintain the cache
if (cache_miss) { if (cache_miss) {
pthread_t thread; pthread_t thread;
xpthread_create(&thread, NULL, info_collector, info); xpthread_create(&thread, nullptr, info_collector, info);
pthread_detach(thread); pthread_detach(thread);
} }
...@@ -117,7 +121,7 @@ static struct su_info *get_su_info(unsigned uid) { ...@@ -117,7 +121,7 @@ static struct su_info *get_su_info(unsigned uid) {
LOGD("su: request from uid=[%d] (#%d)\n", info->uid, ++info->count); LOGD("su: request from uid=[%d] (#%d)\n", info->uid, ++info->count);
// Lock before the policy is determined // Lock before the policy is determined
LOCK_INFO(); info->lock();
if (info->access.policy == QUERY) { if (info->access.policy == QUERY) {
// Not cached, get data from database // Not cached, get data from database
...@@ -173,14 +177,14 @@ static struct su_info *get_su_info(unsigned uid) { ...@@ -173,14 +177,14 @@ static struct su_info *get_su_info(unsigned uid) {
} else { } else {
socket_send_request(fd, info); socket_send_request(fd, info);
int ret = read_int_be(fd); int ret = read_int_be(fd);
info->access.policy = ret < 0 ? DENY : ret; info->access.policy = ret < 0 ? DENY : static_cast<policy_t>(ret);
close(fd); close(fd);
} }
close(sockfd); close(sockfd);
} }
// Unlock // Unlock
UNLOCK_INFO(); info->unlock();
return info; return info;
} }
...@@ -224,7 +228,7 @@ static void set_identity(unsigned uid) { ...@@ -224,7 +228,7 @@ static void set_identity(unsigned uid) {
void su_daemon_handler(int client, struct ucred *credential) { void su_daemon_handler(int client, struct ucred *credential) {
LOGD("su: request from client: %d\n", client); LOGD("su: request from client: %d\n", client);
struct su_info *info = get_su_info(credential->uid); su_info *info = get_su_info(credential->uid);
// Fail fast // Fail fast
if (info->access.policy == DENY && DB_STR(info, SU_MANAGER)[0] == '\0') { if (info->access.policy == DENY && DB_STR(info, SU_MANAGER)[0] == '\0') {
...@@ -289,7 +293,7 @@ void su_daemon_handler(int client, struct ucred *credential) { ...@@ -289,7 +293,7 @@ void su_daemon_handler(int client, struct ucred *credential) {
} }
// Read su_request // Read su_request
xxread(client, &ctx.req, 4 * sizeof(unsigned)); xxread(client, &ctx.req, sizeof(su_req_base));
ctx.req.shell = read_string(client); ctx.req.shell = read_string(client);
ctx.req.command = read_string(client); ctx.req.command = read_string(client);
...@@ -367,7 +371,7 @@ void su_daemon_handler(int client, struct ucred *credential) { ...@@ -367,7 +371,7 @@ void su_daemon_handler(int client, struct ucred *credential) {
app_notify(&ctx); app_notify(&ctx);
if (info->access.policy == ALLOW) { if (info->access.policy == ALLOW) {
char* argv[] = { NULL, NULL, NULL, NULL }; const char *argv[] = { nullptr, nullptr, nullptr, nullptr };
argv[0] = ctx.req.login ? "-" : ctx.req.shell; argv[0] = ctx.req.login ? "-" : ctx.req.shell;
...@@ -381,7 +385,7 @@ void su_daemon_handler(int client, struct ucred *credential) { ...@@ -381,7 +385,7 @@ void su_daemon_handler(int client, struct ucred *credential) {
populate_environment(&ctx.req); populate_environment(&ctx.req);
set_identity(ctx.req.uid); set_identity(ctx.req.uid);
execvp(ctx.req.shell, argv); execvp(ctx.req.shell, (char **) argv);
fprintf(stderr, "Cannot execute %s: %s\n", ctx.req.shell, strerror(errno)); fprintf(stderr, "Cannot execute %s: %s\n", ctx.req.shell, strerror(errno));
PLOGE("exec"); PLOGE("exec");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
...@@ -391,4 +395,3 @@ void su_daemon_handler(int client, struct ucred *credential) { ...@@ -391,4 +395,3 @@ void su_daemon_handler(int client, struct ucred *credential) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
...@@ -9,7 +9,6 @@ LOCAL_SRC_FILES := \ ...@@ -9,7 +9,6 @@ LOCAL_SRC_FILES := \
selinux.cpp \ selinux.cpp \
logging.cpp \ logging.cpp \
xwrap.cpp \ xwrap.cpp \
vector.c \ vector.c
legacy.c
include $(BUILD_STATIC_LIBRARY) include $(BUILD_STATIC_LIBRARY)
...@@ -66,6 +66,15 @@ public: ...@@ -66,6 +66,15 @@ public:
T* _node; T* _node;
}; };
T& operator = (const T& a) {
_size = a._size;
_capacity = a._capacity;
_data = new T[_capacity];
for(int i = 0; i < _size; ++i)
_data[i] = (T&&) a[i];
return *this;
}
iterator begin() const { return iterator(_data); } iterator begin() const { return iterator(_data); }
iterator end() const { return iterator(_data + _size); } iterator end() const { return iterator(_data + _size); }
...@@ -149,7 +158,8 @@ private: ...@@ -149,7 +158,8 @@ private:
_capacity *= 2; _capacity *= 2;
T* temp = _data; T* temp = _data;
_data = new T[_capacity]; _data = new T[_capacity];
for(int i = 0; i < _size; ++i) _data[i] = (T&&) temp[i]; for(int i = 0; i < _size; ++i)
_data[i] = (T&&) temp[i];
delete [] temp; delete [] temp;
} }
}; };
......
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
extern "C" { extern "C" {
#endif #endif
extern void (*freecon)(char * con); extern void (*freecon)(char * con);
extern int (*setcon)(const char * con); extern int (*setcon)(const char * con);
extern int (*getfilecon)(const char *path, char ** con); extern int (*getfilecon)(const char *path, char ** con);
......
...@@ -18,8 +18,6 @@ int file_to_array(const char* filename, Array<char *> &arr); ...@@ -18,8 +18,6 @@ int file_to_array(const char* filename, Array<char *> &arr);
extern "C" { extern "C" {
#endif #endif
#include "vector.h"
#define UID_SHELL (get_shell_uid()) #define UID_SHELL (get_shell_uid())
#define UID_ROOT 0 #define UID_ROOT 0
#define UID_SYSTEM (get_system_uid()) #define UID_SYSTEM (get_system_uid())
...@@ -86,8 +84,6 @@ int xpoll(struct pollfd *fds, nfds_t nfds, int timeout); ...@@ -86,8 +84,6 @@ int xpoll(struct pollfd *fds, nfds_t nfds, int timeout);
unsigned get_shell_uid(); unsigned get_shell_uid();
unsigned get_system_uid(); unsigned get_system_uid();
unsigned get_radio_uid(); unsigned get_radio_uid();
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); ssize_t fdgets(char *buf, size_t size, int fd);
int is_num(const char *s); int is_num(const char *s);
int exec_array(int err, int *fd, void (*cb)(void), const char *argv[]); int exec_array(int err, int *fd, void (*cb)(void), const char *argv[]);
......
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "utils.h"
#include "logging.h"
/* All the string should be freed manually!! */
int file_to_vector(const char* filename, struct vector *v) {
if (access(filename, R_OK) != 0)
return 1;
char *line = NULL;
size_t len = 0;
ssize_t read;
FILE *fp = xfopen(filename, "r");
if (fp == NULL)
return 1;
while ((read = getline(&line, &len, fp)) != -1) {
// Remove end newline
if (line[read - 1] == '\n')
line[read - 1] = '\0';
vec_push_back(v, line);
line = NULL;
}
fclose(fp);
return 0;
}
int vector_to_file(const char *filename, struct vector *v) {
FILE *fp = xfopen(filename, "w");
if (fp == NULL)
return 1;
char *line;
vec_for_each(v, line) {
fprintf(fp, "%s\n", line);
}
fclose(fp);
return 0;
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment