Skip to content

Commit

Permalink
Fetch policy table from Rust
Browse files Browse the repository at this point in the history
  • Loading branch information
topjohnwu committed Jan 5, 2025
1 parent a4671b4 commit b782e7d
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 92 deletions.
49 changes: 26 additions & 23 deletions native/src/core/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub struct SqliteError(i32);

pub type SqliteResult = Result<(), SqliteError>;

trait SqliteReturn {
pub trait SqliteReturn {
fn sql_result(self) -> SqliteResult;
}

Expand All @@ -41,7 +41,7 @@ impl SqliteReturn for i32 {
}
}

trait SqlTable {
pub trait SqlTable {
fn on_row(&mut self, columns: &[String], values: &DbValues);
}

Expand Down Expand Up @@ -132,7 +132,7 @@ extern "C" {
) -> i32;
}

enum DbArg<'a> {
pub enum DbArg<'a> {
Text(&'a str),
Integer(i64),
}
Expand Down Expand Up @@ -178,40 +178,43 @@ impl MagiskD {
}
}

fn db_exec_with_output<T: SqlTable>(&self, sql: &str, args: &[DbArg], out: &mut T) -> i32 {
fn db_exec_impl(
&self,
sql: &str,
args: &[DbArg],
exec_callback: SqlExecCallback,
exec_cookie: *mut c_void,
) -> i32 {
let mut bind_callback: SqlBindCallback = None;
let mut bind_cookie: *mut c_void = ptr::null_mut();
let mut db_args = DbArgs { args, curr: 0 };
if !args.is_empty() {
bind_callback = Some(bind_arguments);
bind_cookie = (&mut db_args) as *mut DbArgs as *mut c_void;
}
let out_ptr: *mut T = out;

self.with_db(|db| unsafe {
sql_exec_impl(
db,
sql,
bind_callback,
bind_cookie,
Some(read_db_row::<T>),
out_ptr.cast(),
exec_callback,
exec_cookie,
)
})
}

fn db_exec(&self, sql: &str, args: &[DbArg]) -> i32 {
let mut bind_callback: SqlBindCallback = None;
let mut bind_cookie: *mut c_void = ptr::null_mut();
let mut db_args = DbArgs { args, curr: 0 };
if !args.is_empty() {
bind_callback = Some(bind_arguments);
bind_cookie = (&mut db_args) as *mut DbArgs as *mut c_void;
}
pub fn db_exec_with_rows<T: SqlTable>(&self, sql: &str, args: &[DbArg], out: &mut T) -> i32 {
self.db_exec_impl(
sql,
args,
Some(read_db_row::<T>),
out as *mut T as *mut c_void,
)
}

self.with_db(|db| unsafe {
sql_exec_impl(db, sql, bind_callback, bind_cookie, None, ptr::null_mut())
})
fn db_exec(&self, sql: &str, args: &[DbArg]) -> i32 {
self.db_exec_impl(sql, args, None, ptr::null_mut())
}

pub fn set_db_setting(&self, key: DbEntryKey, value: i32) -> SqliteResult {
Expand All @@ -236,7 +239,7 @@ impl MagiskD {
let mut func = |_: &[String], values: &DbValues| {
val = values.get_int(0);
};
self.db_exec_with_output(
self.db_exec_with_rows(
"SELECT value FROM settings WHERE key=?",
&[Text(key.to_str())],
&mut func,
Expand All @@ -249,7 +252,7 @@ impl MagiskD {

pub fn get_db_settings(&self, cfg: &mut DbSettings) -> SqliteResult {
cfg.zygisk = self.is_emulator();
self.db_exec_with_output("SELECT * FROM settings", &[], cfg)
self.db_exec_with_rows("SELECT * FROM settings", &[], cfg)
.sql_result()
}

Expand All @@ -258,7 +261,7 @@ impl MagiskD {
let mut func = |_: &[String], values: &DbValues| {
val.push_str(values.get_text(0));
};
self.db_exec_with_output(
self.db_exec_with_rows(
"SELECT value FROM strings WHERE key=?",
&[Text(key.to_str())],
&mut func,
Expand Down Expand Up @@ -291,7 +294,7 @@ impl MagiskD {
}
writer.ipc_write_string(&out).log().ok();
};
self.db_exec_with_output(&sql, &[], &mut output_fn);
self.db_exec_with_rows(&sql, &[], &mut output_fn);
writer.ipc_write_string("").log()
}
}
Expand Down
29 changes: 24 additions & 5 deletions native/src/core/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use logging::{
};
use mount::{clean_mounts, find_preinit_device, revert_unmount, setup_mounts};
use resetprop::{persist_delete_prop, persist_get_prop, persist_get_props, persist_set_prop};
use su::get_default_root_settings;

mod cert;
#[path = "../include/consts.rs"]
Expand All @@ -22,6 +23,7 @@ mod db;
mod logging;
mod mount;
mod resetprop;
mod su;

#[cxx::bridge]
pub mod ffi {
Expand Down Expand Up @@ -121,6 +123,19 @@ pub mod ffi {
zygisk: bool,
}

#[repr(i32)]
enum SuPolicy {
Query,
Deny,
Allow,
}

struct RootSettings {
policy: SuPolicy,
log: bool,
notify: bool,
}

unsafe extern "C++" {
include!("include/sqlite.hpp");

Expand Down Expand Up @@ -165,12 +180,12 @@ pub mod ffi {
// FFI for MagiskD
extern "Rust" {
type MagiskD;
fn setup_logfile(self: &MagiskD);
fn is_recovery(self: &MagiskD) -> bool;
fn boot_stage_handler(self: &MagiskD, client: i32, code: i32);
fn setup_logfile(&self);
fn is_recovery(&self) -> bool;
fn boot_stage_handler(&self, client: i32, code: i32);

#[cxx_name = "get_db_settings"]
fn get_db_settings_for_cxx(self: &MagiskD, cfg: &mut DbSettings) -> bool;
fn get_db_settings_for_cxx(&self, cfg: &mut DbSettings) -> bool;
fn get_db_setting(&self, key: DbEntryKey) -> i32;
#[cxx_name = "set_db_setting"]
fn set_db_setting_for_cxx(&self, key: DbEntryKey, value: i32) -> bool;
Expand All @@ -179,9 +194,13 @@ pub mod ffi {
fn rm_db_string_for_cxx(&self, key: DbEntryKey) -> bool;
#[cxx_name = "db_exec"]
fn db_exec_for_cxx(&self, client_fd: i32);
#[cxx_name = "get_root_settings"]
fn get_root_settings_for_cxx(&self, uid: i32, settings: &mut RootSettings) -> bool;

#[cxx_name = "DbSettings"]
fn get_default_db_settings() -> DbSettings;

#[cxx_name = "RootSettings"]
fn get_default_root_settings() -> RootSettings;
#[cxx_name = "MagiskD"]
fn get_magiskd() -> &'static MagiskD;
}
Expand Down
4 changes: 2 additions & 2 deletions native/src/core/su/connect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ void app_log(const su_context &ctx) {
extras.emplace_back("from.uid", ctx.info->uid);
extras.emplace_back("to.uid", static_cast<int>(ctx.req.uid));
extras.emplace_back("pid", ctx.pid);
extras.emplace_back("policy", ctx.info->access.policy);
extras.emplace_back("policy", +ctx.info->access.policy);
extras.emplace_back("target", ctx.req.target);
extras.emplace_back("context", ctx.req.context.data());
extras.emplace_back("gids", &ctx.req.gids);
Expand All @@ -193,7 +193,7 @@ void app_notify(const su_context &ctx) {
extras.reserve(3);
extras.emplace_back("from.uid", ctx.info->uid);
extras.emplace_back("pid", ctx.pid);
extras.emplace_back("policy", ctx.info->access.policy);
extras.emplace_back("policy", +ctx.info->access.policy);

exec_cmd("notify", extras, ctx.info);
exit(0);
Expand Down
60 changes: 60 additions & 0 deletions native/src/core/su/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
use crate::daemon::MagiskD;
use crate::db::DbArg::Integer;
use crate::db::{SqlTable, SqliteResult, SqliteReturn};
use crate::ffi::{DbValues, RootSettings, SuPolicy};
use base::{libc, ResultExt};
use std::ptr;

impl Default for SuPolicy {
fn default() -> Self {
SuPolicy::Query
}
}

impl Default for RootSettings {
fn default() -> Self {
RootSettings {
policy: Default::default(),
log: true,
notify: true,
}
}
}

impl SqlTable for RootSettings {
fn on_row(&mut self, columns: &[String], values: &DbValues) {
for (i, column) in columns.iter().enumerate() {
let val = values.get_int(i as i32);
if column == "policy" {
self.policy.repr = val;
} else if column == "logging" {
self.log = val != 0;
} else if column == "notify" {
self.notify = val != 0;
}
}
}
}

impl MagiskD {
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>?)",
&[
Integer(uid as i64),
Integer(unsafe { libc::time(ptr::null_mut()).into() }),
],
settings,
)
.sql_result()
}

pub fn get_root_settings_for_cxx(&self, uid: i32, settings: &mut RootSettings) -> bool {
self.get_root_settings(uid, settings).log().is_ok()
}
}

pub fn get_default_root_settings() -> RootSettings {
RootSettings::default()
}
29 changes: 3 additions & 26 deletions native/src/core/su/su.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,8 @@
#define ATTY_OUT (1 << 1)
#define ATTY_ERR (1 << 2)

typedef enum {
QUERY = 0,
DENY = 1,
ALLOW = 2,
} policy_t;

struct su_access {
policy_t policy;
int log;
int notify;

su_access() : policy(QUERY), log(1), notify(1) {}

void operator()(StringSlice columns, const DbValues &data);
void silent_deny() {
policy = DENY;
log = 0;
notify = 0;
}
void silent_allow() {
policy = ALLOW;
log = 0;
notify = 0;
}
};
#define SILENT_ALLOW { SuPolicy::Allow, false, false }
#define SILENT_DENY { SuPolicy::Deny, false, false }

class su_info {
public:
Expand All @@ -48,7 +25,7 @@ class su_info {
// These should be guarded with internal lock
int eval_uid; // The effective UID, taking multiuser settings into consideration
struct DbSettings cfg;
su_access access;
struct RootSettings access;
std::string mgr_pkg;
int mgr_uid;
void check_db();
Expand Down
Loading

0 comments on commit b782e7d

Please sign in to comment.