From 82d1d192675388c07b9cb803e43cf103734a1ba7 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Fri, 10 Jan 2025 09:38:06 +0800 Subject: [PATCH] Migrate uid_granted_root to Rust --- native/src/core/daemon.rs | 6 ++++ native/src/core/db.rs | 24 +++++++++----- native/src/core/include/core.hpp | 1 - native/src/core/lib.rs | 1 + native/src/core/su/mod.rs | 57 ++++++++++++++++++++++++++++++-- native/src/core/su/su_daemon.cpp | 50 +++------------------------- native/src/core/zygisk/entry.cpp | 6 ++-- 7 files changed, 83 insertions(+), 62 deletions(-) diff --git a/native/src/core/daemon.rs b/native/src/core/daemon.rs index d0cae8a16..85d780201 100644 --- a/native/src/core/daemon.rs +++ b/native/src/core/daemon.rs @@ -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>, diff --git a/native/src/core/db.rs b/native/src/core/db.rs index 1f6ff64a5..e122c083c 100644 --- a/native/src/core/db.rs +++ b/native/src/core/db.rs @@ -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 = Result; 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 { + 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 { diff --git a/native/src/core/include/core.hpp b/native/src/core/include/core.hpp index 1282c0fb4..81f08ec1e 100644 --- a/native/src/core/include/core.hpp +++ b/native/src/core/include/core.hpp @@ -53,7 +53,6 @@ void init_thread_pool(); void exec_task(std::function &&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); diff --git a/native/src/core/lib.rs b/native/src/core/lib.rs index 42d100e0b..589752e96 100644 --- a/native/src/core/lib.rs +++ b/native/src/core/lib.rs @@ -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; diff --git a/native/src/core/su/mod.rs b/native/src/core/su/mod.rs index 40f9c4daf..c9aa15915 100644 --- a/native/src/core/su/mod.rs +++ b/native/src/core/su/mod.rs @@ -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 { diff --git a/native/src/core/su/su_daemon.cpp b/native/src/core/su/su_daemon.cpp index 9ef7eea7c..2964f23b4 100644 --- a/native/src/core/su/su_daemon.cpp +++ b/native/src/core/su/su_daemon.cpp @@ -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 get_su_info(unsigned uid) { if (uid == AID_ROOT) { auto info = make_shared(uid); diff --git a/native/src/core/zygisk/entry.cpp b/native/src/core/zygisk/entry.cpp index 60ed189b7..4d9d981f4 100644 --- a/native/src/core/zygisk/entry.cpp +++ b/native/src/core/zygisk/entry.cpp @@ -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; }