Modernize database code
This commit is contained in:
parent
5e4d2dedbe
commit
0742901cd2
@ -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");
|
||||||
|
@ -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;
|
||||||
|
@ -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>
|
||||||
|
@ -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);
|
||||||
|
@ -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",
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user