From 0742901cd2c2ae534102794c29b9bdaca6ec0cb7 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Sun, 4 Nov 2018 18:24:08 -0500 Subject: [PATCH] Modernize database code --- native/jni/daemon/bootstages.cpp | 7 +-- native/jni/daemon/db.cpp | 96 +++++++++++++++++++++++++------- native/jni/include/daemon.h | 1 + native/jni/include/db.h | 44 +++++++++------ native/jni/su/connect.cpp | 12 ++-- native/jni/su/su.h | 5 +- native/jni/su/su_daemon.cpp | 18 +++--- 7 files changed, 121 insertions(+), 62 deletions(-) diff --git a/native/jni/daemon/bootstages.cpp b/native/jni/daemon/bootstages.cpp index 01697c8e9..019e50c6b 100644 --- a/native/jni/daemon/bootstages.cpp +++ b/native/jni/daemon/bootstages.cpp @@ -910,10 +910,9 @@ core_only: // Check whether we have a valid manager installed sqlite3 *db = get_magiskdb(); if (db) { - struct db_strings str; - memset(&str, 0, sizeof(str)); - get_db_strings(db, SU_MANAGER, &str); - if (validate_manager(str.s[SU_MANAGER], 0, nullptr)) { + db_strings str; + get_db_strings(db, &str, SU_MANAGER); + if (validate_manager(str[SU_MANAGER], 0, nullptr)) { // There is no manager installed, install the stub exec_command_sync("/sbin/magiskinit", "-x", "manager", "/data/magisk.apk", nullptr); install_apk("/data/magisk.apk"); diff --git a/native/jni/daemon/db.cpp b/native/jni/daemon/db.cpp index 577c664cf..eb6ea9823 100644 --- a/native/jni/daemon/db.cpp +++ b/native/jni/daemon/db.cpp @@ -10,6 +10,66 @@ #define DB_VERSION 7 +db_strings::db_strings() { + memset(data, 0, sizeof(data)); +} + +char *db_strings::operator[](const char *key) { + return data[getKeyIdx(key)]; +} + +const char *db_strings::operator[](const char *key) const { + return data[getKeyIdx(key)]; +} + +char *db_strings::operator[](const int idx) { + return data[idx]; +} + +const char *db_strings::operator[](const int idx) const { + return data[idx]; +} + +int db_strings::getKeyIdx(const char *key) const { + int idx = DB_STRING_NUM; + for (int i = 0; i < DB_STRING_NUM; ++i) { + if (strcmp(key, DB_STRING_KEYS[i]) == 0) + idx = i; + } + return idx; +} + +db_settings::db_settings() : data { + ROOT_ACCESS_APPS_AND_ADB, + MULTIUSER_MODE_OWNER_ONLY, + NAMESPACE_MODE_REQUESTER +} {} + +int &db_settings::operator[](const int idx) { + return data[idx]; +} + +const int &db_settings::operator[](const int idx) const { + return data[idx]; +} + +int &db_settings::operator[](const char *key) { + return data[getKeyIdx(key)]; +} + +const int &db_settings::operator[](const char *key) const { + return data[getKeyIdx(key)]; +} + +int db_settings::getKeyIdx(const char *key) const { + int idx = DB_SETTINGS_NUM; + for (int i = 0; i < DB_SETTINGS_NUM; ++i) { + if (strcmp(key, DB_SETTING_KEYS[i]) == 0) + idx = i; + } + return idx; +} + static int ver_cb(void *ver, int, char **data, char **) { *((int *) ver) = atoi(data[0]); return 0; @@ -111,26 +171,24 @@ sqlite3 *get_magiskdb() { } static int settings_cb(void *v, int col_num, char **data, char **col_name) { - auto dbs = (db_settings *) v; - int key = -1, value; + auto &cfg = *(db_settings *) v; + int value = -1; + const char *key = ""; for (int i = 0; i < col_num; ++i) { if (strcmp(col_name[i], "key") == 0) { - for (int k = 0; k < DB_SETTINGS_NUM; ++k) { - if (strcmp(data[i], DB_SETTING_KEYS[k]) == 0) - key = k; - } + key = data[i]; } else if (strcmp(col_name[i], "value") == 0) { value = atoi(data[i]); } } - if (key >= 0) { - dbs->v[key] = value; - LOGD("magiskdb: query %s=[%d]\n", DB_SETTING_KEYS[key], value); + if (key[0] && value >= 0) { + cfg[key] = value; + LOGD("magiskdb: query %s=[%d]\n", key, value); } return 0; } -int get_db_settings(sqlite3 *db, int key, struct db_settings *dbs) { +int get_db_settings(sqlite3 *db, struct db_settings *dbs, int key) { if (db == nullptr) return 1; char *err; @@ -150,27 +208,23 @@ 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) { - auto dbs = (db_strings *) v; - int key = -1; - char *value; + auto &str = *(db_strings *) v; + const char *key = "", *value = ""; for (int i = 0; i < col_num; ++i) { if (strcmp(col_name[i], "key") == 0) { - for (int k = 0; k < DB_STRING_NUM; ++k) { - if (strcmp(data[i], DB_STRING_KEYS[k]) == 0) - key = k; - } + key = data[i]; } else if (strcmp(col_name[i], "value") == 0) { value = data[i]; } } - if (key >= 0) { - strcpy(dbs->s[key], value); - LOGD("magiskdb: query %s=[%s]\n", DB_STRING_KEYS[key], value); + if (key[0] && value[0]) { + strcpy(str[key], value); + LOGD("magiskdb: query %s=[%s]\n", key, value); } return 0; } -int get_db_strings(sqlite3 *db, int key, struct db_strings *str) { +int get_db_strings(sqlite3 *db, struct db_strings *str, int key) { if (db == nullptr) return 1; char *err; diff --git a/native/jni/include/daemon.h b/native/jni/include/daemon.h index d9d9caf09..866309062 100644 --- a/native/jni/include/daemon.h +++ b/native/jni/include/daemon.h @@ -4,6 +4,7 @@ #ifndef _DAEMON_H_ #define _DAEMON_H_ +#include #include #include #include diff --git a/native/jni/include/db.h b/native/jni/include/db.h index b2ef566fb..a5e6fa952 100644 --- a/native/jni/include/db.h +++ b/native/jni/include/db.h @@ -17,7 +17,7 @@ #define DB_SETTINGS_NUM 3 -// Settings indices +// Settings keys enum { ROOT_ACCESS = 0, SU_MULTIUSER_MODE, @@ -46,14 +46,17 @@ enum { NAMESPACE_MODE_ISOLATE }; -struct db_settings { - int v[DB_SETTINGS_NUM]; - db_settings() - : v { - ROOT_ACCESS_APPS_AND_ADB, - MULTIUSER_MODE_OWNER_ONLY, - NAMESPACE_MODE_REQUESTER - } {} +class db_settings { +public: + db_settings(); + int& operator [](const char *); + const int& operator [](const char *) const; + int& operator [](const int); + const int& operator [](const int) const; + +private: + int data[DB_SETTINGS_NUM + 1]; + int getKeyIdx(const char *) const; }; /************** @@ -67,17 +70,22 @@ struct db_settings { #define DB_STRING_NUM 1 -// Strings indices +// Strings keys enum { SU_MANAGER = 0 }; -struct db_strings { - char s[DB_STRING_NUM][128]; - db_strings() { - for (int i = 0; i < DB_STRING_NUM; ++i) - s[i][0] = '\0'; - } +class db_strings { +public: + db_strings(); + char * operator [](const char *); + const char * operator [](const char *) const; + char * operator [](const int); + const char * operator [](const int) const; + +private: + char data[DB_STRING_NUM + 1][128]; + int getKeyIdx(const char *) const; }; /************* @@ -119,8 +127,8 @@ struct su_access { ********************/ sqlite3 *get_magiskdb(); -int get_db_settings(sqlite3 *db, int key, struct db_settings *dbs); -int get_db_strings(sqlite3 *db, int key, struct db_strings *str); +int get_db_settings(sqlite3 *db, struct db_settings *dbs, int key = -1); +int get_db_strings(sqlite3 *db, struct db_strings *str, int key = -1); int get_uid_policy(sqlite3 *db, int uid, struct su_access *su); int validate_manager(char *alt_pkg, int userid, struct stat *st); int exec_sql(const char *sql); diff --git a/native/jni/su/connect.cpp b/native/jni/su/connect.cpp index 6bdb5a3ff..c29875c2e 100644 --- a/native/jni/su/connect.cpp +++ b/native/jni/su/connect.cpp @@ -42,7 +42,7 @@ static void silent_run(const char *args[]) { } static void setup_user(char *user, struct su_info *info) { - switch (DB_SET(info, SU_MULTIUSER_MODE)) { + switch (info->cfg[SU_MULTIUSER_MODE]) { case MULTIUSER_MODE_OWNER_ONLY: case MULTIUSER_MODE_OWNER_MANAGED: sprintf(user, "%d", 0); @@ -59,7 +59,7 @@ void app_log(struct su_context *ctx) { char fromUid[8]; sprintf(fromUid, "%d", - DB_SET(ctx->info, SU_MULTIUSER_MODE) == MULTIUSER_MODE_OWNER_MANAGED ? + ctx->info->cfg[SU_MULTIUSER_MODE] == MULTIUSER_MODE_OWNER_MANAGED ? ctx->info->uid % 100000 : ctx->info->uid); char toUid[8]; @@ -74,7 +74,7 @@ void app_log(struct su_context *ctx) { const char *cmd[] = { AM_PATH, "broadcast", "-a", "android.intent.action.BOOT_COMPLETED", - "-p", DB_STR(ctx->info, SU_MANAGER), + "-p", ctx->info->str[SU_MANAGER], "-f", "0x00000020", "--user", user, "--es", "action", "log", @@ -95,7 +95,7 @@ void app_notify(struct su_context *ctx) { char fromUid[8]; sprintf(fromUid, "%d", - DB_SET(ctx->info, SU_MULTIUSER_MODE) == MULTIUSER_MODE_OWNER_MANAGED ? + ctx->info->cfg[SU_MULTIUSER_MODE] == MULTIUSER_MODE_OWNER_MANAGED ? ctx->info->uid % 100000 : ctx->info->uid); char policy[2]; @@ -104,7 +104,7 @@ void app_notify(struct su_context *ctx) { const char *cmd[] = { AM_PATH, "broadcast", "-a", "android.intent.action.BOOT_COMPLETED", - "-p", DB_STR(ctx->info, SU_MANAGER), + "-p", ctx->info->str[SU_MANAGER], "-f", "0x00000020", "--user", user, "--es", "action", "notify", @@ -121,7 +121,7 @@ void app_connect(const char *socket, struct su_info *info) { const char *cmd[] = { AM_PATH, "broadcast", "-a", "android.intent.action.BOOT_COMPLETED", - "-p", DB_STR(info, SU_MANAGER), + "-p", info->str[SU_MANAGER], "-f", "0x00000020", "--user", user, "--es", "action", "request", diff --git a/native/jni/su/su.h b/native/jni/su/su.h index c829d8662..686400856 100644 --- a/native/jni/su/su.h +++ b/native/jni/su/su.h @@ -23,7 +23,7 @@ public: int count; /* Just a count for debugging purpose */ /* These values should be guarded with internal lock */ - struct db_settings dbs; + struct db_settings cfg; struct db_strings str; struct su_access access; struct stat mgr_st; @@ -41,9 +41,6 @@ private: pthread_mutex_t _lock; /* Internal lock */ }; -#define DB_SET(i, e) (i)->dbs.v[e] -#define DB_STR(i, e) (i)->str.s[e] - struct su_req_base { unsigned uid; bool login; diff --git a/native/jni/su/su_daemon.cpp b/native/jni/su/su_daemon.cpp index 685c3bb44..6a2a47490 100644 --- a/native/jni/su/su_daemon.cpp +++ b/native/jni/su/su_daemon.cpp @@ -62,11 +62,11 @@ static void database_check(su_info *info) { int uid = info->uid; sqlite3 *db = get_magiskdb(); if (db) { - get_db_settings(db, -1, &info->dbs); - get_db_strings(db, -1, &info->str); + get_db_settings(db, &info->cfg); + get_db_strings(db, &info->str); // Check multiuser settings - switch (DB_SET(info, SU_MULTIUSER_MODE)) { + switch (info->cfg[SU_MULTIUSER_MODE]) { case MULTIUSER_MODE_OWNER_ONLY: if (info->uid / 100000) { uid = -1; @@ -88,7 +88,7 @@ static void database_check(su_info *info) { // We need to check our manager if (info->access.log || info->access.notify) - validate_manager(DB_STR(info, SU_MANAGER), uid / 100000, &info->mgr_st); + validate_manager(info->str[SU_MANAGER], uid / 100000, &info->mgr_st); } static struct su_info *get_su_info(unsigned uid) { @@ -128,7 +128,7 @@ static struct su_info *get_su_info(unsigned uid) { database_check(info); // Check su access settings - switch (DB_SET(info, ROOT_ACCESS)) { + switch (info->cfg[ROOT_ACCESS]) { case ROOT_ACCESS_DISABLED: LOGW("Root access is disabled!\n"); info->access = NO_SU_ACCESS; @@ -159,7 +159,7 @@ static struct su_info *get_su_info(unsigned uid) { info->access = SILENT_SU_ACCESS; // If still not determined, check if manager exists - if (info->access.policy == QUERY && DB_STR(info, SU_MANAGER)[0] == '\0') + if (info->access.policy == QUERY && info->str[SU_MANAGER][0] == '\0') info->access = NO_SU_ACCESS; } @@ -231,7 +231,7 @@ void su_daemon_handler(int client, struct ucred *credential) { su_info *info = get_su_info(credential->uid); // Fail fast - if (info->access.policy == DENY && DB_STR(info, SU_MANAGER)[0] == '\0') { + if (info->access.policy == DENY && info->str[SU_MANAGER][0] == '\0') { LOGD("su: fast deny\n"); write_int(client, DENY); close(client); @@ -347,8 +347,8 @@ void su_daemon_handler(int client, struct ucred *credential) { // Handle namespaces if (ctx.req.mount_master) - DB_SET(info, SU_MNT_NS) = NAMESPACE_MODE_GLOBAL; - switch (DB_SET(info, SU_MNT_NS)) { + info->cfg[SU_MNT_NS] = NAMESPACE_MODE_GLOBAL; + switch (info->cfg[SU_MNT_NS]) { case NAMESPACE_MODE_GLOBAL: LOGD("su: use global namespace\n"); break;