Modernize database code

This commit is contained in:
topjohnwu 2018-11-04 18:24:08 -05:00
parent 5e4d2dedbe
commit 0742901cd2
7 changed files with 121 additions and 62 deletions

View File

@ -910,10 +910,9 @@ core_only:
// Check whether we have a valid manager installed // Check whether we have a valid manager installed
sqlite3 *db = get_magiskdb(); sqlite3 *db = get_magiskdb();
if (db) { if (db) {
struct db_strings str; db_strings str;
memset(&str, 0, sizeof(str)); get_db_strings(db, &str, SU_MANAGER);
get_db_strings(db, SU_MANAGER, &str); if (validate_manager(str[SU_MANAGER], 0, nullptr)) {
if (validate_manager(str.s[SU_MANAGER], 0, nullptr)) {
// There is no manager installed, install the stub // There is no manager installed, install the stub
exec_command_sync("/sbin/magiskinit", "-x", "manager", "/data/magisk.apk", nullptr); exec_command_sync("/sbin/magiskinit", "-x", "manager", "/data/magisk.apk", nullptr);
install_apk("/data/magisk.apk"); install_apk("/data/magisk.apk");

View File

@ -10,6 +10,66 @@
#define DB_VERSION 7 #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 **) { static int ver_cb(void *ver, int, char **data, char **) {
*((int *) ver) = atoi(data[0]); *((int *) ver) = atoi(data[0]);
return 0; return 0;
@ -111,26 +171,24 @@ 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) {
auto dbs = (db_settings *) v; auto &cfg = *(db_settings *) v;
int key = -1, value; int value = -1;
const char *key = "";
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) {
for (int k = 0; k < DB_SETTINGS_NUM; ++k) { key = data[i];
if (strcmp(data[i], DB_SETTING_KEYS[k]) == 0)
key = k;
}
} else if (strcmp(col_name[i], "value") == 0) { } else if (strcmp(col_name[i], "value") == 0) {
value = atoi(data[i]); value = atoi(data[i]);
} }
} }
if (key >= 0) { if (key[0] && value >= 0) {
dbs->v[key] = value; cfg[key] = value;
LOGD("magiskdb: query %s=[%d]\n", DB_SETTING_KEYS[key], value); LOGD("magiskdb: query %s=[%d]\n", key, value);
} }
return 0; 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) if (db == nullptr)
return 1; return 1;
char *err; 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) { static int strings_cb(void *v, int col_num, char **data, char **col_name) {
auto dbs = (db_strings *) v; auto &str = *(db_strings *) v;
int key = -1; const char *key = "", *value = "";
char *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) {
for (int k = 0; k < DB_STRING_NUM; ++k) { key = data[i];
if (strcmp(data[i], DB_STRING_KEYS[k]) == 0)
key = k;
}
} else if (strcmp(col_name[i], "value") == 0) { } else if (strcmp(col_name[i], "value") == 0) {
value = data[i]; value = data[i];
} }
} }
if (key >= 0) { if (key[0] && value[0]) {
strcpy(dbs->s[key], value); strcpy(str[key], value);
LOGD("magiskdb: query %s=[%s]\n", DB_STRING_KEYS[key], value); LOGD("magiskdb: query %s=[%s]\n", key, value);
} }
return 0; 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) if (db == nullptr)
return 1; return 1;
char *err; char *err;

View File

@ -4,6 +4,7 @@
#ifndef _DAEMON_H_ #ifndef _DAEMON_H_
#define _DAEMON_H_ #define _DAEMON_H_
#include <stdbool.h>
#include <pthread.h> #include <pthread.h>
#include <sys/un.h> #include <sys/un.h>
#include <sys/socket.h> #include <sys/socket.h>

View File

@ -17,7 +17,7 @@
#define DB_SETTINGS_NUM 3 #define DB_SETTINGS_NUM 3
// Settings indices // Settings keys
enum { enum {
ROOT_ACCESS = 0, ROOT_ACCESS = 0,
SU_MULTIUSER_MODE, SU_MULTIUSER_MODE,
@ -46,14 +46,17 @@ enum {
NAMESPACE_MODE_ISOLATE NAMESPACE_MODE_ISOLATE
}; };
struct db_settings { class db_settings {
int v[DB_SETTINGS_NUM]; public:
db_settings() db_settings();
: v { int& operator [](const char *);
ROOT_ACCESS_APPS_AND_ADB, const int& operator [](const char *) const;
MULTIUSER_MODE_OWNER_ONLY, int& operator [](const int);
NAMESPACE_MODE_REQUESTER 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 #define DB_STRING_NUM 1
// Strings indices // Strings keys
enum { enum {
SU_MANAGER = 0 SU_MANAGER = 0
}; };
struct db_strings { class db_strings {
char s[DB_STRING_NUM][128]; public:
db_strings() { db_strings();
for (int i = 0; i < DB_STRING_NUM; ++i) char * operator [](const char *);
s[i][0] = '\0'; 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(); sqlite3 *get_magiskdb();
int get_db_settings(sqlite3 *db, int key, struct db_settings *dbs); int get_db_settings(sqlite3 *db, struct db_settings *dbs, int key = -1);
int get_db_strings(sqlite3 *db, int key, struct db_strings *str); 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 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);

View File

@ -42,7 +42,7 @@ static void silent_run(const char *args[]) {
} }
static void setup_user(char *user, struct su_info *info) { 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_ONLY:
case MULTIUSER_MODE_OWNER_MANAGED: case MULTIUSER_MODE_OWNER_MANAGED:
sprintf(user, "%d", 0); sprintf(user, "%d", 0);
@ -59,7 +59,7 @@ void app_log(struct su_context *ctx) {
char fromUid[8]; char fromUid[8];
sprintf(fromUid, "%d", 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); ctx->info->uid % 100000 : ctx->info->uid);
char toUid[8]; char toUid[8];
@ -74,7 +74,7 @@ void app_log(struct su_context *ctx) {
const 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", ctx->info->str[SU_MANAGER],
"-f", "0x00000020", "-f", "0x00000020",
"--user", user, "--user", user,
"--es", "action", "log", "--es", "action", "log",
@ -95,7 +95,7 @@ void app_notify(struct su_context *ctx) {
char fromUid[8]; char fromUid[8];
sprintf(fromUid, "%d", 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); ctx->info->uid % 100000 : ctx->info->uid);
char policy[2]; char policy[2];
@ -104,7 +104,7 @@ void app_notify(struct su_context *ctx) {
const 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", ctx->info->str[SU_MANAGER],
"-f", "0x00000020", "-f", "0x00000020",
"--user", user, "--user", user,
"--es", "action", "notify", "--es", "action", "notify",
@ -121,7 +121,7 @@ void app_connect(const char *socket, struct su_info *info) {
const 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", info->str[SU_MANAGER],
"-f", "0x00000020", "-f", "0x00000020",
"--user", user, "--user", user,
"--es", "action", "request", "--es", "action", "request",

View File

@ -23,7 +23,7 @@ public:
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 */
struct db_settings dbs; struct db_settings cfg;
struct db_strings str; struct db_strings str;
struct su_access access; struct su_access access;
struct stat mgr_st; struct stat mgr_st;
@ -41,9 +41,6 @@ private:
pthread_mutex_t _lock; /* Internal lock */ 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 { struct su_req_base {
unsigned uid; unsigned uid;
bool login; bool login;

View File

@ -62,11 +62,11 @@ 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) {
get_db_settings(db, -1, &info->dbs); get_db_settings(db, &info->cfg);
get_db_strings(db, -1, &info->str); get_db_strings(db, &info->str);
// Check multiuser settings // Check multiuser settings
switch (DB_SET(info, SU_MULTIUSER_MODE)) { switch (info->cfg[SU_MULTIUSER_MODE]) {
case MULTIUSER_MODE_OWNER_ONLY: case MULTIUSER_MODE_OWNER_ONLY:
if (info->uid / 100000) { if (info->uid / 100000) {
uid = -1; uid = -1;
@ -88,7 +88,7 @@ static void database_check(su_info *info) {
// We need to check our manager // We need to check our manager
if (info->access.log || info->access.notify) 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) { 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); database_check(info);
// Check su access settings // Check su access settings
switch (DB_SET(info, ROOT_ACCESS)) { switch (info->cfg[ROOT_ACCESS]) {
case ROOT_ACCESS_DISABLED: case ROOT_ACCESS_DISABLED:
LOGW("Root access is disabled!\n"); LOGW("Root access is disabled!\n");
info->access = NO_SU_ACCESS; info->access = NO_SU_ACCESS;
@ -159,7 +159,7 @@ static struct su_info *get_su_info(unsigned uid) {
info->access = SILENT_SU_ACCESS; info->access = SILENT_SU_ACCESS;
// If still not determined, check if manager exists // 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; 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); 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 && info->str[SU_MANAGER][0] == '\0') {
LOGD("su: fast deny\n"); LOGD("su: fast deny\n");
write_int(client, DENY); write_int(client, DENY);
close(client); close(client);
@ -347,8 +347,8 @@ void su_daemon_handler(int client, struct ucred *credential) {
// Handle namespaces // Handle namespaces
if (ctx.req.mount_master) if (ctx.req.mount_master)
DB_SET(info, SU_MNT_NS) = NAMESPACE_MODE_GLOBAL; info->cfg[SU_MNT_NS] = NAMESPACE_MODE_GLOBAL;
switch (DB_SET(info, SU_MNT_NS)) { switch (info->cfg[SU_MNT_NS]) {
case NAMESPACE_MODE_GLOBAL: case NAMESPACE_MODE_GLOBAL:
LOGD("su: use global namespace\n"); LOGD("su: use global namespace\n");
break; break;