Migrate uid_granted_root to Rust

This commit is contained in:
topjohnwu 2025-01-10 09:38:06 +08:00 committed by John Wu
parent 4d4195c02d
commit 82d1d19267
7 changed files with 83 additions and 62 deletions

View File

@ -41,6 +41,8 @@ impl BootStateFlags {
}
}
pub const AID_ROOT: i32 = 0;
pub const AID_SHELL: i32 = 2000;
pub const AID_APP_START: i32 = 10000;
pub const AID_APP_END: i32 = 19999;
pub const AID_USER_OFFSET: i32 = 100000;
@ -49,6 +51,10 @@ pub const fn to_app_id(uid: i32) -> i32 {
uid % AID_USER_OFFSET
}
pub const fn to_user_id(uid: i32) -> i32 {
uid / AID_USER_OFFSET
}
#[derive(Default)]
pub struct MagiskD {
pub sql_connection: Mutex<Option<Sqlite3>>,

View File

@ -25,14 +25,14 @@ fn sqlite_err_str(code: i32) -> &'static Utf8CStr {
#[error("sqlite3: {}", sqlite_err_str(self.0))]
pub struct SqliteError(i32);
pub type SqliteResult = Result<(), SqliteError>;
pub type SqliteResult<T> = Result<T, SqliteError>;
pub trait SqliteReturn {
fn sql_result(self) -> SqliteResult;
fn sql_result(self) -> SqliteResult<()>;
}
impl SqliteReturn for i32 {
fn sql_result(self) -> SqliteResult {
fn sql_result(self) -> SqliteResult<()> {
if self != 0 {
Err(SqliteError(self))
} else {
@ -217,7 +217,7 @@ impl MagiskD {
self.db_exec_impl(sql, args, None, ptr::null_mut())
}
pub fn set_db_setting(&self, key: DbEntryKey, value: i32) -> SqliteResult {
pub fn set_db_setting(&self, key: DbEntryKey, value: i32) -> SqliteResult<()> {
self.db_exec(
"INSERT OR REPLACE INTO settings (key,value) VALUES(?,?)",
&[Text(key.to_str()), Integer(value as i64)],
@ -250,10 +250,12 @@ impl MagiskD {
val
}
pub fn get_db_settings(&self, cfg: &mut DbSettings) -> SqliteResult {
pub fn get_db_settings(&self) -> SqliteResult<DbSettings> {
let mut cfg = DbSettings::default();
cfg.zygisk = self.is_emulator;
self.db_exec_with_rows("SELECT * FROM settings", &[], cfg)
.sql_result()
self.db_exec_with_rows("SELECT * FROM settings", &[], &mut cfg)
.sql_result()?;
Ok(cfg)
}
pub fn get_db_string(&self, key: DbEntryKey) -> String {
@ -272,7 +274,7 @@ impl MagiskD {
val
}
pub fn rm_db_string(&self, key: DbEntryKey) -> SqliteResult {
pub fn rm_db_string(&self, key: DbEntryKey) -> SqliteResult<()> {
self.db_exec("DELETE FROM strings WHERE key=?", &[Text(key.to_str())])
.sql_result()
}
@ -301,7 +303,11 @@ impl MagiskD {
impl MagiskD {
pub fn get_db_settings_for_cxx(&self, cfg: &mut DbSettings) -> bool {
self.get_db_settings(cfg).log().is_ok()
cfg.zygisk = self.is_emulator;
self.db_exec_with_rows("SELECT * FROM settings", &[], cfg)
.sql_result()
.log()
.is_ok()
}
pub fn set_db_setting_for_cxx(&self, key: DbEntryKey, value: i32) -> bool {

View File

@ -53,7 +53,6 @@ void init_thread_pool();
void exec_task(std::function<void()> &&task);
// Daemon handlers
void boot_stage_handler(int client, int code);
void denylist_handler(int client, const sock_cred *cred);
void su_daemon_handler(int client, const sock_cred *cred);
void zygisk_handler(int client, const sock_cred *cred);

View File

@ -182,6 +182,7 @@ pub mod ffi {
fn boot_stage_handler(&self, client: i32, code: i32);
fn preserve_stub_apk(&self);
fn prune_su_access(&self);
fn uid_granted_root(&self, mut uid: i32) -> bool;
#[cxx_name = "get_manager"]
unsafe fn get_manager_for_cxx(&self, user: i32, ptr: *mut CxxString, install: bool) -> i32;

View File

@ -1,7 +1,9 @@
use crate::daemon::{to_app_id, MagiskD, AID_APP_END, AID_APP_START};
use crate::daemon::{
to_app_id, to_user_id, MagiskD, AID_APP_END, AID_APP_START, AID_ROOT, AID_SHELL,
};
use crate::db::DbArg::Integer;
use crate::db::{SqlTable, SqliteResult, SqliteReturn};
use crate::ffi::{DbValues, RootSettings, SuPolicy};
use crate::ffi::{DbValues, MultiuserMode, RootAccess, RootSettings, SuPolicy};
use base::ResultExt;
impl Default for SuPolicy {
@ -44,7 +46,7 @@ impl SqlTable for UidList {
}
impl MagiskD {
fn get_root_settings(&self, uid: i32, settings: &mut RootSettings) -> SqliteResult {
fn get_root_settings(&self, uid: i32, settings: &mut RootSettings) -> SqliteResult<()> {
self.db_exec_with_rows(
"SELECT policy, logging, notification FROM policies \
WHERE uid=? AND (until=0 OR until>strftime('%s', 'now'))",
@ -87,6 +89,55 @@ impl MagiskD {
self.db_exec("DELETE FROM policies WHERE uid=?", &[Integer(uid as i64)]);
}
}
pub fn uid_granted_root(&self, mut uid: i32) -> bool {
if uid == AID_ROOT {
return true;
}
let cfg = match self.get_db_settings().log() {
Ok(cfg) => cfg,
Err(_) => return false,
};
// Check user root access settings
match cfg.root_access {
RootAccess::Disabled => return false,
RootAccess::AppsOnly => {
if uid == AID_SHELL {
return false;
}
}
RootAccess::AdbOnly => {
if uid != AID_SHELL {
return false;
}
}
_ => {}
}
// Check multiuser settings
match cfg.multiuser_mode {
MultiuserMode::OwnerOnly => {
if to_user_id(uid) != 0 {
return false;
}
}
MultiuserMode::OwnerManaged => uid = to_app_id(uid),
_ => {}
}
let mut granted = false;
let mut output_fn =
|_: &[String], values: &DbValues| granted = values.get_int(0) == SuPolicy::Allow.repr;
self.db_exec_with_rows(
"SELECT policy FROM policies WHERE uid=? AND (until=0 OR until>strftime('%s', 'now'))",
&[Integer(uid as i64)],
&mut output_fn,
);
granted
}
}
pub fn get_default_root_settings() -> RootSettings {

View File

@ -44,7 +44,8 @@ void su_info::refresh() {
void su_info::check_db() {
eval_uid = uid;
MagiskD().get_db_settings(cfg);
auto &daemon = MagiskD();
daemon.get_db_settings(cfg);
// Check multiuser settings
switch (cfg.multiuser_mode) {
@ -63,59 +64,16 @@ void su_info::check_db() {
}
if (eval_uid > 0) {
if (!MagiskD().get_root_settings(eval_uid, access))
if (!daemon.get_root_settings(eval_uid, access))
return;
}
// We need to check our manager
if (access.policy == SuPolicy::Query || access.log || access.notify) {
mgr_uid = MagiskD().get_manager(to_user_id(eval_uid), &mgr_pkg, true);
mgr_uid = daemon.get_manager(to_user_id(eval_uid), &mgr_pkg, true);
}
}
bool uid_granted_root(int uid) {
if (uid == AID_ROOT)
return true;
auto cfg = DbSettings();
MagiskD().get_db_settings(cfg);
// Check user root access settings
switch (cfg.root_access) {
case RootAccess::Disabled:
return false;
case RootAccess::AppsOnly:
if (uid == AID_SHELL)
return false;
break;
case RootAccess::AdbOnly:
if (uid != AID_SHELL)
return false;
break;
case RootAccess::AppsAndAdb:
break;
}
// Check multiuser settings
switch (cfg.multiuser_mode) {
case MultiuserMode::OwnerOnly:
if (to_user_id(uid) != 0)
return false;
break;
case MultiuserMode::OwnerManaged:
uid = to_app_id(uid);
break;
case MultiuserMode::User:
default:
break;
}
bool granted = false;
db_exec("SELECT policy FROM policies WHERE uid=? AND (until=0 OR until>strftime('%s', 'now'))",
{ uid }, [&](auto, const DbValues &v) { granted = v.get_int(0) == +SuPolicy::Allow; });
return granted;
}
static shared_ptr<su_info> get_su_info(unsigned uid) {
if (uid == AID_ROOT) {
auto info = make_shared<su_info>(uid);

View File

@ -122,23 +122,23 @@ static void connect_companion(int client, bool is_64_bit) {
send_fd(zygiskd_socket, client);
}
extern bool uid_granted_root(int uid);
static void get_process_info(int client, const sock_cred *cred) {
int uid = read_int(client);
string process = read_string(client);
auto &daemon = MagiskD();
uint32_t flags = 0;
if (is_deny_target(uid, process)) {
flags |= PROCESS_ON_DENYLIST;
}
if (MagiskD().get_manager(to_user_id(uid), nullptr, false) == uid) {
if (daemon.get_manager(to_user_id(uid), nullptr, false) == uid) {
flags |= PROCESS_IS_MAGISK_APP;
}
if (denylist_enforced) {
flags |= DENYLIST_ENFORCING;
}
if (uid_granted_root(uid)) {
if (daemon.uid_granted_root(uid)) {
flags |= PROCESS_GRANTED_ROOT;
}