mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-28 04:25:27 +00:00
Prevent Magisk database race condition
The database should only be accessed by a single process, which is magiskd. This means 'magisk --sqlite [SQL]' has to be updated to pass the SQL command to the daemon. In addition, open the database connection with SQLITE_OPEN_FULLMUTEX to support multithread in magiskd.
This commit is contained in:
parent
ba70269398
commit
ab5fedda0b
@ -884,16 +884,12 @@ core_only:
|
|||||||
install_apk("/data/magisk.apk");
|
install_apk("/data/magisk.apk");
|
||||||
} else {
|
} else {
|
||||||
// Check whether we have a valid manager installed
|
// Check whether we have a valid manager installed
|
||||||
sqlite3 *db = get_magiskdb();
|
db_strings str;
|
||||||
if (db) {
|
get_db_strings(&str, SU_MANAGER);
|
||||||
db_strings str;
|
if (validate_manager(str[SU_MANAGER], 0, nullptr)) {
|
||||||
get_db_strings(db, &str, SU_MANAGER);
|
// There is no manager installed, install the stub
|
||||||
if (validate_manager(str[SU_MANAGER], 0, nullptr)) {
|
exec_command_sync("/sbin/magiskinit", "-x", "manager", "/data/magisk.apk", nullptr);
|
||||||
// There is no manager installed, install the stub
|
install_apk("/data/magisk.apk");
|
||||||
exec_command_sync("/sbin/magiskinit", "-x", "manager", "/data/magisk.apk", nullptr);
|
|
||||||
install_apk("/data/magisk.apk");
|
|
||||||
}
|
|
||||||
sqlite3_close_v2(db);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "daemon.h"
|
#include "daemon.h"
|
||||||
#include "selinux.h"
|
#include "selinux.h"
|
||||||
|
#include "db.h"
|
||||||
#include "flags.h"
|
#include "flags.h"
|
||||||
|
|
||||||
static void get_client_cred(int fd, struct ucred *cred) {
|
static void get_client_cred(int fd, struct ucred *cred) {
|
||||||
@ -39,6 +40,7 @@ static void *request_handler(void *args) {
|
|||||||
case POST_FS_DATA:
|
case POST_FS_DATA:
|
||||||
case LATE_START:
|
case LATE_START:
|
||||||
case BOOT_COMPLETE:
|
case BOOT_COMPLETE:
|
||||||
|
case SQLITE_CMD:
|
||||||
if (credential.uid != 0) {
|
if (credential.uid != 0) {
|
||||||
write_int(client, ROOT_REQUIRED);
|
write_int(client, ROOT_REQUIRED);
|
||||||
close(client);
|
close(client);
|
||||||
@ -75,6 +77,10 @@ static void *request_handler(void *args) {
|
|||||||
case HANDSHAKE:
|
case HANDSHAKE:
|
||||||
/* Do NOT close the client, make it hold */
|
/* Do NOT close the client, make it hold */
|
||||||
break;
|
break;
|
||||||
|
case SQLITE_CMD:
|
||||||
|
exec_sql(client);
|
||||||
|
close(client);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
close(client);
|
close(client);
|
||||||
break;
|
break;
|
||||||
|
@ -7,9 +7,12 @@
|
|||||||
|
|
||||||
#include "magisk.h"
|
#include "magisk.h"
|
||||||
#include "db.h"
|
#include "db.h"
|
||||||
|
#include "daemon.h"
|
||||||
|
|
||||||
#define DB_VERSION 7
|
#define DB_VERSION 7
|
||||||
|
|
||||||
|
static sqlite3 *mDB = nullptr;
|
||||||
|
|
||||||
db_strings::db_strings() {
|
db_strings::db_strings() {
|
||||||
memset(data, 0, sizeof(data));
|
memset(data, 0, sizeof(data));
|
||||||
}
|
}
|
||||||
@ -76,24 +79,17 @@ static int ver_cb(void *ver, int, char **data, char **) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define err_abort(err) \
|
#define err_ret(e) if (e) return e;
|
||||||
if (err) { \
|
|
||||||
LOGE("sqlite3_exec: %s\n", err); \
|
|
||||||
sqlite3_free(err); \
|
|
||||||
return nullptr; \
|
|
||||||
}
|
|
||||||
|
|
||||||
static sqlite3 *open_and_init_db() {
|
static char *open_and_init_db(sqlite3 *&db) {
|
||||||
sqlite3 *db;
|
int ret = sqlite3_open_v2(MAGISKDB, &db,
|
||||||
int ret = sqlite3_open(MAGISKDB, &db);
|
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, nullptr);
|
||||||
if (ret) {
|
if (ret)
|
||||||
LOGE("sqlite3 open failure: %s\n", sqlite3_errstr(ret));
|
return strdup(sqlite3_errstr(ret));
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
int ver, upgrade = 0;
|
int ver, upgrade = 0;
|
||||||
char *err;
|
char *err;
|
||||||
sqlite3_exec(db, "PRAGMA user_version", ver_cb, &ver, &err);
|
sqlite3_exec(db, "PRAGMA user_version", ver_cb, &ver, &err);
|
||||||
err_abort(err);
|
err_ret(err);
|
||||||
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);
|
||||||
@ -106,20 +102,20 @@ static sqlite3 *open_and_init_db() {
|
|||||||
"(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))",
|
||||||
nullptr, nullptr, &err);
|
nullptr, nullptr, &err);
|
||||||
err_abort(err);
|
err_ret(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)",
|
||||||
nullptr, nullptr, &err);
|
nullptr, nullptr, &err);
|
||||||
err_abort(err);
|
err_ret(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))",
|
||||||
nullptr, nullptr, &err);
|
nullptr, nullptr, &err);
|
||||||
err_abort(err);
|
err_ret(err);
|
||||||
ver = 3;
|
ver = 3;
|
||||||
upgrade = 1;
|
upgrade = 1;
|
||||||
}
|
}
|
||||||
@ -129,13 +125,13 @@ static sqlite3 *open_and_init_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))",
|
||||||
nullptr, nullptr, &err);
|
nullptr, nullptr, &err);
|
||||||
err_abort(err);
|
err_ret(err);
|
||||||
ver = 4;
|
ver = 4;
|
||||||
upgrade = 1;
|
upgrade = 1;
|
||||||
}
|
}
|
||||||
if (ver == 4) {
|
if (ver == 4) {
|
||||||
sqlite3_exec(db, "UPDATE policies SET uid=uid%100000", nullptr, nullptr, &err);
|
sqlite3_exec(db, "UPDATE policies SET uid=uid%100000", nullptr, nullptr, &err);
|
||||||
err_abort(err);
|
err_ret(err);
|
||||||
/* Skip version 5 */
|
/* Skip version 5 */
|
||||||
ver = 6;
|
ver = 6;
|
||||||
upgrade = 1;
|
upgrade = 1;
|
||||||
@ -146,7 +142,7 @@ static sqlite3 *open_and_init_db() {
|
|||||||
"CREATE TABLE IF NOT EXISTS hidelist "
|
"CREATE TABLE IF NOT EXISTS hidelist "
|
||||||
"(process TEXT, PRIMARY KEY(process))",
|
"(process TEXT, PRIMARY KEY(process))",
|
||||||
nullptr, nullptr, &err);
|
nullptr, nullptr, &err);
|
||||||
err_abort(err);
|
err_ret(err);
|
||||||
ver = 7;
|
ver = 7;
|
||||||
upgrade =1 ;
|
upgrade =1 ;
|
||||||
}
|
}
|
||||||
@ -156,19 +152,27 @@ static sqlite3 *open_and_init_db() {
|
|||||||
char query[32];
|
char query[32];
|
||||||
sprintf(query, "PRAGMA user_version=%d", ver);
|
sprintf(query, "PRAGMA user_version=%d", ver);
|
||||||
sqlite3_exec(db, query, nullptr, nullptr, &err);
|
sqlite3_exec(db, query, nullptr, nullptr, &err);
|
||||||
err_abort(err);
|
err_ret(err);
|
||||||
}
|
}
|
||||||
return db;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3 *get_magiskdb() {
|
char *db_exec(const char *sql, int (*cb)(void *, int, char**, char**), void *v) {
|
||||||
sqlite3 *db = open_and_init_db();
|
char *err;
|
||||||
if (db == nullptr) {
|
if (mDB == nullptr) {
|
||||||
// Open fails, remove and reconstruct
|
err = open_and_init_db(mDB);
|
||||||
unlink(MAGISKDB);
|
db_err_cmd(err,
|
||||||
db = open_and_init_db();
|
// Open fails, remove and reconstruct
|
||||||
|
unlink(MAGISKDB);
|
||||||
|
err = open_and_init_db(mDB);
|
||||||
|
err_ret(err);
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return db;
|
if (mDB) {
|
||||||
|
sqlite3_exec(mDB, sql, cb, v, &err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
@ -189,22 +193,16 @@ static int settings_cb(void *v, int col_num, char **data, char **col_name) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_db_settings(sqlite3 *db, db_settings *dbs, int key) {
|
int get_db_settings(db_settings *dbs, int key) {
|
||||||
if (db == nullptr)
|
|
||||||
return 1;
|
|
||||||
char *err;
|
char *err;
|
||||||
if (key > 0) {
|
if (key > 0) {
|
||||||
char query[128];
|
char query[128];
|
||||||
sprintf(query, "SELECT key, value FROM settings WHERE key='%s'", DB_SETTING_KEYS[key]);
|
sprintf(query, "SELECT key, value FROM settings WHERE key='%s'", DB_SETTING_KEYS[key]);
|
||||||
sqlite3_exec(db, query, settings_cb, dbs, &err);
|
err = db_exec(query, settings_cb, dbs);
|
||||||
} else {
|
} else {
|
||||||
sqlite3_exec(db, "SELECT key, value FROM settings", settings_cb, dbs, &err);
|
err = db_exec("SELECT key, value FROM settings", settings_cb, dbs);
|
||||||
}
|
|
||||||
if (err) {
|
|
||||||
LOGE("sqlite3_exec: %s\n", err);
|
|
||||||
sqlite3_free(err);
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
db_err_cmd(err, return 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,16 +223,14 @@ static int strings_cb(void *v, int col_num, char **data, char **col_name) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_db_strings(sqlite3 *db, db_strings *str, int key) {
|
int get_db_strings(db_strings *str, int key) {
|
||||||
if (db == nullptr)
|
|
||||||
return 1;
|
|
||||||
char *err;
|
char *err;
|
||||||
if (key > 0) {
|
if (key > 0) {
|
||||||
char query[128];
|
char query[128];
|
||||||
sprintf(query, "SELECT key, value FROM strings WHERE key='%s'", DB_STRING_KEYS[key]);
|
sprintf(query, "SELECT key, value FROM strings WHERE key='%s'", DB_STRING_KEYS[key]);
|
||||||
sqlite3_exec(db, query, strings_cb, str, &err);
|
err = db_exec(query, strings_cb, str);
|
||||||
} else {
|
} else {
|
||||||
sqlite3_exec(db, "SELECT key, value FROM strings", strings_cb, str, &err);
|
err = db_exec("SELECT key, value FROM strings", strings_cb, str);
|
||||||
}
|
}
|
||||||
if (err) {
|
if (err) {
|
||||||
LOGE("sqlite3_exec: %s\n", err);
|
LOGE("sqlite3_exec: %s\n", err);
|
||||||
@ -258,18 +254,12 @@ static int policy_cb(void *v, int col_num, char **data, char **col_name) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_uid_policy(sqlite3 *db, int uid, struct su_access *su) {
|
int get_uid_policy(int uid, struct su_access *su) {
|
||||||
if (db == nullptr)
|
|
||||||
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(nullptr));
|
"WHERE uid=%d AND (until=0 OR until>%li)", uid, time(nullptr));
|
||||||
sqlite3_exec(db, query, policy_cb, su, &err);
|
err = db_exec(query, policy_cb, su);
|
||||||
if (err) {
|
db_err_cmd(err, return 1);
|
||||||
LOGE("sqlite3_exec: %s\n", err);
|
|
||||||
sqlite3_free(err);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,26 +289,24 @@ int validate_manager(char *alt_pkg, int userid, struct stat *st) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int print_cb(void *v, int col_num, char **data, char **col_name) {
|
static int print_cb(void *v, int col_num, char **data, char **col_name) {
|
||||||
|
FILE *out = (FILE *) v;
|
||||||
for (int i = 0; i < col_num; ++i) {
|
for (int i = 0; i < col_num; ++i) {
|
||||||
if (i) printf("|");
|
if (i) fprintf(out, "|");
|
||||||
printf("%s=%s", col_name[i], data[i]);
|
fprintf(out, "%s=%s", col_name[i], data[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
fprintf(out, "\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int exec_sql(const char *sql) {
|
void exec_sql(int client) {
|
||||||
sqlite3 *db = get_magiskdb();
|
char *sql = read_string(client);
|
||||||
if (db) {
|
FILE *out = fdopen(recv_fd(client), "a");
|
||||||
char *err;
|
char *err = db_exec(sql, print_cb, out);
|
||||||
sqlite3_exec(db, sql, print_cb, nullptr, &err);
|
free(sql);
|
||||||
sqlite3_close_v2(db);
|
fclose(out);
|
||||||
if (err) {
|
db_err_cmd(err,
|
||||||
fprintf(stderr, "sql_err: %s\n", err);
|
write_int(client, 1);
|
||||||
sqlite3_free(err);
|
return;
|
||||||
return 1;
|
);
|
||||||
}
|
write_int(client, 0);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,11 @@ int magisk_main(int argc, char *argv[]) {
|
|||||||
write_int(fd, BOOT_COMPLETE);
|
write_int(fd, BOOT_COMPLETE);
|
||||||
return read_int(fd);
|
return read_int(fd);
|
||||||
} else if (strcmp(argv[1], "--sqlite") == 0) {
|
} else if (strcmp(argv[1], "--sqlite") == 0) {
|
||||||
return exec_sql(argv[2]);
|
int fd = connect_daemon();
|
||||||
|
write_int(fd, SQLITE_CMD);
|
||||||
|
write_string(fd, argv[2]);
|
||||||
|
send_fd(fd, STDOUT_FILENO);
|
||||||
|
return read_int(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
usage();
|
usage();
|
||||||
|
@ -20,7 +20,8 @@ enum {
|
|||||||
BOOT_COMPLETE,
|
BOOT_COMPLETE,
|
||||||
MAGISKHIDE,
|
MAGISKHIDE,
|
||||||
HIDE_CONNECT,
|
HIDE_CONNECT,
|
||||||
HANDSHAKE
|
HANDSHAKE,
|
||||||
|
SQLITE_CMD,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return codes for daemon
|
// Return codes for daemon
|
||||||
|
@ -4,6 +4,13 @@
|
|||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#define db_err(e) db_err_cmd(e, )
|
||||||
|
#define db_err_cmd(e, cmd) if (e) { \
|
||||||
|
LOGE("sqlite3_exec: %s\n", e); \
|
||||||
|
sqlite3_free(e); \
|
||||||
|
cmd;\
|
||||||
|
}
|
||||||
|
|
||||||
/***************
|
/***************
|
||||||
* DB Settings *
|
* DB Settings *
|
||||||
***************/
|
***************/
|
||||||
@ -128,11 +135,12 @@ struct su_access {
|
|||||||
* Public Functions *
|
* Public Functions *
|
||||||
********************/
|
********************/
|
||||||
|
|
||||||
sqlite3 *get_magiskdb();
|
sqlite3 *get_magiskdb(sqlite3 *&db);
|
||||||
int get_db_settings(sqlite3 *db, db_settings *dbs, int key = -1);
|
int get_db_settings(db_settings *dbs, int key);
|
||||||
int get_db_strings(sqlite3 *db, db_strings *str, int key = -1);
|
int get_db_strings(db_strings *str, int key);
|
||||||
int get_uid_policy(sqlite3 *db, int uid, struct su_access *su);
|
int get_uid_policy(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);
|
void exec_sql(int client);
|
||||||
|
char *db_exec(const char *sql, int (*cb)(void *, int, char**, char**) = nullptr, void *v = nullptr);
|
||||||
|
|
||||||
#endif //DB_H
|
#endif //DB_H
|
||||||
|
@ -140,7 +140,7 @@ void clean_magisk_props() {
|
|||||||
}, nullptr, false);
|
}, nullptr, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int add_list(sqlite3 *db, const char *proc) {
|
int add_list(const char *proc) {
|
||||||
for (auto &s : hide_list) {
|
for (auto &s : hide_list) {
|
||||||
// They should be unique
|
// They should be unique
|
||||||
if (s == proc)
|
if (s == proc)
|
||||||
@ -149,30 +149,21 @@ static int add_list(sqlite3 *db, const char *proc) {
|
|||||||
|
|
||||||
LOGI("hide_list add: [%s]\n", proc);
|
LOGI("hide_list add: [%s]\n", proc);
|
||||||
|
|
||||||
|
// Add to database
|
||||||
|
char sql[4096];
|
||||||
|
snprintf(sql, sizeof(sql), "INSERT INTO hidelist (process) VALUES('%s')", proc);
|
||||||
|
char *err = db_exec(sql);
|
||||||
|
db_err_cmd(err, return DAEMON_ERROR);
|
||||||
|
|
||||||
// Critical region
|
// Critical region
|
||||||
pthread_mutex_lock(&list_lock);
|
pthread_mutex_lock(&list_lock);
|
||||||
hide_list.push_back(proc);
|
hide_list.push_back(proc);
|
||||||
kill_process(proc);
|
kill_process(proc);
|
||||||
pthread_mutex_unlock(&list_lock);
|
pthread_mutex_unlock(&list_lock);
|
||||||
|
|
||||||
// Add to database
|
|
||||||
char sql[4096];
|
|
||||||
snprintf(sql, sizeof(sql), "INSERT INTO hidelist (process) VALUES('%s')", proc);
|
|
||||||
sqlite3_exec(db, sql, nullptr, nullptr, nullptr);
|
|
||||||
|
|
||||||
return DAEMON_SUCCESS;
|
return DAEMON_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int add_list(const char *proc) {
|
|
||||||
sqlite3 *db = get_magiskdb();
|
|
||||||
if (db) {
|
|
||||||
int ret = add_list(db, proc);
|
|
||||||
sqlite3_close_v2(db);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
return DAEMON_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int add_list(int client) {
|
int add_list(int client) {
|
||||||
char *proc = read_string(client);
|
char *proc = read_string(client);
|
||||||
int ret = add_list(proc);
|
int ret = add_list(proc);
|
||||||
@ -196,13 +187,10 @@ static int rm_list(const char *proc) {
|
|||||||
pthread_mutex_unlock(&list_lock);
|
pthread_mutex_unlock(&list_lock);
|
||||||
|
|
||||||
if (do_rm) {
|
if (do_rm) {
|
||||||
sqlite3 *db = get_magiskdb();
|
|
||||||
if (db == nullptr)
|
|
||||||
return DAEMON_ERROR;
|
|
||||||
char sql[4096];
|
char sql[4096];
|
||||||
snprintf(sql, sizeof(sql), "DELETE FROM hidelist WHERE process='%s'", proc);
|
snprintf(sql, sizeof(sql), "DELETE FROM hidelist WHERE process='%s'", proc);
|
||||||
sqlite3_exec(db, sql, nullptr, nullptr, nullptr);
|
char *err = db_exec(sql);
|
||||||
sqlite3_close_v2(db);
|
db_err(err);
|
||||||
return DAEMON_SUCCESS;
|
return DAEMON_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
return HIDE_ITEM_NOT_EXIST;
|
return HIDE_ITEM_NOT_EXIST;
|
||||||
@ -218,31 +206,27 @@ int rm_list(int client) {
|
|||||||
|
|
||||||
#define LEGACY_LIST MOUNTPOINT "/.core/hidelist"
|
#define LEGACY_LIST MOUNTPOINT "/.core/hidelist"
|
||||||
|
|
||||||
|
static int collect_list(void *, int, char **data, char**) {
|
||||||
|
LOGI("hide_list: [%s]\n", data[0]);
|
||||||
|
hide_list.push_back(data[0]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool init_list() {
|
bool init_list() {
|
||||||
LOGD("hide_list: initialize\n");
|
LOGD("hide_list: initialize\n");
|
||||||
|
|
||||||
sqlite3 *db = get_magiskdb();
|
char *err = db_exec("SELECT process FROM hidelist", collect_list);
|
||||||
if (db == nullptr)
|
db_err_cmd(err, return false);
|
||||||
return false;
|
|
||||||
|
|
||||||
sqlite3_exec(db, "SELECT process FROM hidelist",
|
|
||||||
[] (auto, auto, char **data, auto) -> int
|
|
||||||
{
|
|
||||||
LOGI("hide_list: [%s]\n", data[0]);
|
|
||||||
hide_list.push_back(data[0]);
|
|
||||||
return 0;
|
|
||||||
}, nullptr, nullptr);
|
|
||||||
|
|
||||||
// Migrate old hide list into database
|
// Migrate old hide list into database
|
||||||
if (access(LEGACY_LIST, R_OK) == 0) {
|
if (access(LEGACY_LIST, R_OK) == 0) {
|
||||||
Vector<CharArray> tmp;
|
Vector<CharArray> tmp;
|
||||||
file_to_vector(LEGACY_LIST, tmp);
|
file_to_vector(LEGACY_LIST, tmp);
|
||||||
for (auto &s : tmp)
|
for (auto &s : tmp)
|
||||||
add_list(db, s);
|
add_list(s);
|
||||||
unlink(LEGACY_LIST);
|
unlink(LEGACY_LIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3_close_v2(db);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,12 +240,11 @@ void ls_list(int client) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void set_hide_config() {
|
static void set_hide_config() {
|
||||||
sqlite3 *db = get_magiskdb();
|
|
||||||
char sql[64];
|
char sql[64];
|
||||||
sprintf(sql, "REPLACE INTO settings (key,value) VALUES('%s',%d)",
|
sprintf(sql, "REPLACE INTO settings (key,value) VALUES('%s',%d)",
|
||||||
DB_SETTING_KEYS[HIDE_CONFIG], hide_enabled);
|
DB_SETTING_KEYS[HIDE_CONFIG], hide_enabled);
|
||||||
sqlite3_exec(db, sql, nullptr, nullptr, nullptr);
|
char *err = db_exec(sql);
|
||||||
sqlite3_close_v2(db);
|
db_err(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
int launch_magiskhide(int client) {
|
int launch_magiskhide(int client) {
|
||||||
@ -314,10 +297,8 @@ int stop_magiskhide() {
|
|||||||
void auto_start_magiskhide() {
|
void auto_start_magiskhide() {
|
||||||
if (!start_log_daemon())
|
if (!start_log_daemon())
|
||||||
return;
|
return;
|
||||||
sqlite3 *db = get_magiskdb();
|
|
||||||
db_settings dbs;
|
db_settings dbs;
|
||||||
get_db_settings(db, &dbs, HIDE_CONFIG);
|
get_db_settings(&dbs, HIDE_CONFIG);
|
||||||
sqlite3_close_v2(db);
|
|
||||||
if (dbs[HIDE_CONFIG]) {
|
if (dbs[HIDE_CONFIG]) {
|
||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
xpthread_create(&thread, nullptr, [](void*) -> void* {
|
xpthread_create(&thread, nullptr, [](void*) -> void* {
|
||||||
|
@ -60,32 +60,28 @@ static void *info_collector(void *node) {
|
|||||||
|
|
||||||
static void database_check(su_info *info) {
|
static void database_check(su_info *info) {
|
||||||
int uid = info->uid;
|
int uid = info->uid;
|
||||||
sqlite3 *db = get_magiskdb();
|
get_db_settings(&info->cfg, 0);
|
||||||
if (db) {
|
get_db_strings(&info->str, 0);
|
||||||
get_db_settings(db, &info->cfg);
|
|
||||||
get_db_strings(db, &info->str);
|
|
||||||
|
|
||||||
// Check multiuser settings
|
// Check multiuser settings
|
||||||
switch (info->cfg[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;
|
||||||
info->access = NO_SU_ACCESS;
|
info->access = NO_SU_ACCESS;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MULTIUSER_MODE_OWNER_MANAGED:
|
case MULTIUSER_MODE_OWNER_MANAGED:
|
||||||
uid = info->uid % 100000;
|
uid = info->uid % 100000;
|
||||||
break;
|
break;
|
||||||
case MULTIUSER_MODE_USER:
|
case MULTIUSER_MODE_USER:
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
if (uid > 0)
|
|
||||||
get_uid_policy(db, uid, &info->access);
|
|
||||||
sqlite3_close_v2(db);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (uid > 0)
|
||||||
|
get_uid_policy(uid, &info->access);
|
||||||
|
|
||||||
// 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(info->str[SU_MANAGER], uid / 100000, &info->mgr_st);
|
validate_manager(info->str[SU_MANAGER], uid / 100000, &info->mgr_st);
|
||||||
|
Loading…
Reference in New Issue
Block a user