Remove old ffi data structure

This commit is contained in:
topjohnwu
2025-08-08 18:23:43 -07:00
committed by John Wu
parent cd0eca20b0
commit 251c3c3e0e
3 changed files with 97 additions and 93 deletions

View File

@@ -125,15 +125,6 @@ pub mod ffi {
gids: Vec<u32>, gids: Vec<u32>,
} }
struct SuAppRequest<'a> {
uid: i32,
pid: i32,
eval_uid: i32,
mgr_pkg: &'a str,
mgr_uid: i32,
request: &'a SuRequest,
}
unsafe extern "C++" { unsafe extern "C++" {
#[namespace = "rust"] #[namespace = "rust"]
#[cxx_name = "Utf8CStr"] #[cxx_name = "Utf8CStr"]

View File

@@ -1,10 +1,12 @@
use super::SuInfo;
use super::db::RootSettings;
use crate::consts::{INTERNAL_DIR, MAGISK_FILE_CON}; use crate::consts::{INTERNAL_DIR, MAGISK_FILE_CON};
use crate::daemon::{MagiskD, to_user_id}; use crate::daemon::to_user_id;
use crate::ffi::{SuAppRequest, SuPolicy, get_magisk_tmp}; use crate::ffi::{SuPolicy, SuRequest, get_magisk_tmp};
use crate::socket::IpcRead;
use ExtraVal::{Bool, Int, IntList, Str}; use ExtraVal::{Bool, Int, IntList, Str};
use base::{ use base::{
BytesExt, FileAttr, LibcReturn, LoggedResult, OsError, ResultExt, cstr, fork_dont_care, info, BytesExt, FileAttr, LibcReturn, LoggedResult, OsError, ResultExt, cstr, fork_dont_care, libc,
libc,
}; };
use libc::pollfd as PollFd; use libc::pollfd as PollFd;
use num_traits::AsPrimitive; use num_traits::AsPrimitive;
@@ -79,19 +81,21 @@ impl Extra {
} }
} }
impl MagiskD { pub(super) struct SuAppContext<'a> {
fn exec_cmd( pub(super) cred: libc::ucred,
&self, pub(super) request: &'a SuRequest,
action: &'static str, pub(super) info: &'a SuInfo,
extras: &[Extra], pub(super) settings: &'a mut RootSettings,
info: &SuAppRequest, pub(super) sdk_int: i32,
use_provider: bool, }
) {
let user = to_user_id(info.eval_uid); impl SuAppContext<'_> {
fn exec_cmd(&self, action: &'static str, extras: &[Extra], use_provider: bool) {
let user = to_user_id(self.info.eval_uid);
let user = user.to_string(); let user = user.to_string();
if use_provider { if use_provider {
let provider = format!("content://{}.provider", info.mgr_pkg); let provider = format!("content://{}.provider", self.info.mgr_pkg);
let mut cmd = Command::new("/system/bin/app_process"); let mut cmd = Command::new("/system/bin/app_process");
cmd.args([ cmd.args([
"/system/bin", "/system/bin",
@@ -104,7 +108,7 @@ impl MagiskD {
"--method", "--method",
action, action,
]); ]);
if self.sdk_int() >= 30 { if self.sdk_int >= 30 {
extras.iter().for_each(|e| e.add_bind(&mut cmd)) extras.iter().for_each(|e| e.add_bind(&mut cmd))
} else { } else {
extras.iter().for_each(|e| e.add_bind_legacy(&mut cmd)) extras.iter().for_each(|e| e.add_bind_legacy(&mut cmd))
@@ -126,7 +130,7 @@ impl MagiskD {
"com.android.commands.am.Am", "com.android.commands.am.Am",
"start", "start",
"-p", "-p",
info.mgr_pkg, &self.info.mgr_pkg,
"--user", "--user",
&user, &user,
"-a", "-a",
@@ -152,21 +156,21 @@ impl MagiskD {
} }
} }
pub fn app_request(&self, info: &SuAppRequest) -> LoggedResult<File> { fn app_request(&mut self) {
let mut fifo = cstr::buf::new::<64>(); let mut fifo = cstr::buf::new::<64>();
fifo.write_fmt(format_args!( fifo.write_fmt(format_args!(
"{}/{}/su_request_{}", "{}/{}/su_request_{}",
get_magisk_tmp(), get_magisk_tmp(),
INTERNAL_DIR, INTERNAL_DIR,
info.pid self.cred.pid
)) ))
.ok(); .ok();
let fd: LoggedResult<File> = try { let fd: LoggedResult<File> = try {
let mut attr = FileAttr::new(); let mut attr = FileAttr::new();
attr.st.st_mode = 0o600; attr.st.st_mode = 0o600;
attr.st.st_uid = info.mgr_uid.as_(); attr.st.st_uid = self.info.mgr_uid.as_();
attr.st.st_gid = info.mgr_uid.as_(); attr.st.st_gid = self.info.mgr_uid.as_();
attr.con.write_str(MAGISK_FILE_CON).ok(); attr.con.write_str(MAGISK_FILE_CON).ok();
fifo.mkfifo(0o600)?; fifo.mkfifo(0o600)?;
@@ -179,14 +183,14 @@ impl MagiskD {
}, },
Extra { Extra {
key: "uid", key: "uid",
value: Int(info.eval_uid), value: Int(self.info.eval_uid),
}, },
Extra { Extra {
key: "pid", key: "pid",
value: Int(info.pid), value: Int(self.cred.pid),
}, },
]; ];
self.exec_cmd("request", &extras, info, false); self.exec_cmd("request", &extras, false);
// Open with O_RDWR to prevent FIFO open block // Open with O_RDWR to prevent FIFO open block
let fd = fifo.open(libc::O_RDWR | libc::O_CLOEXEC)?; let fd = fifo.open(libc::O_RDWR | libc::O_CLOEXEC)?;
@@ -206,68 +210,72 @@ impl MagiskD {
}; };
fifo.remove().log_ok(); fifo.remove().log_ok();
fd
if let Ok(mut fd) = fd {
self.settings.policy = SuPolicy {
repr: fd
.read_decodable::<i32>()
.log()
.map(i32::from_be)
.unwrap_or(SuPolicy::Deny.repr),
};
} else {
self.settings.policy = SuPolicy::Deny;
};
} }
pub fn app_notify(&self, info: &SuAppRequest, policy: SuPolicy) { fn app_notify(&self) {
if fork_dont_care() != 0 {
return;
}
let extras = [ let extras = [
Extra { Extra {
key: "from.uid", key: "from.uid",
value: Int(info.uid), value: Int(self.cred.uid.as_()),
}, },
Extra { Extra {
key: "pid", key: "pid",
value: Int(info.pid), value: Int(self.cred.pid.as_()),
}, },
Extra { Extra {
key: "policy", key: "policy",
value: Int(policy.repr), value: Int(self.settings.policy.repr),
}, },
]; ];
self.exec_cmd("notify", &extras, info, true); self.exec_cmd("notify", &extras, true);
exit(0);
} }
pub fn app_log(&self, info: &SuAppRequest, policy: SuPolicy, notify: bool) { fn app_log(&self) {
if fork_dont_care() != 0 { let command = if self.request.command.is_empty() {
return; &self.request.shell
}
let command = if info.request.command.is_empty() {
&info.request.shell
} else { } else {
&info.request.command &self.request.command
}; };
let extras = [ let extras = [
Extra { Extra {
key: "from.uid", key: "from.uid",
value: Int(info.uid), value: Int(self.cred.uid.as_()),
}, },
Extra { Extra {
key: "to.uid", key: "to.uid",
value: Int(info.request.target_uid), value: Int(self.request.target_uid),
}, },
Extra { Extra {
key: "pid", key: "pid",
value: Int(info.pid), value: Int(self.cred.pid.as_()),
}, },
Extra { Extra {
key: "policy", key: "policy",
value: Int(policy.repr), value: Int(self.settings.policy.repr),
}, },
Extra { Extra {
key: "target", key: "target",
value: Int(info.request.target_pid), value: Int(self.request.target_pid),
}, },
Extra { Extra {
key: "context", key: "context",
value: Str(info.request.context.clone()), value: Str(self.request.context.clone()),
}, },
Extra { Extra {
key: "gids", key: "gids",
value: IntList(info.request.gids.clone()), value: IntList(self.request.gids.clone()),
}, },
Extra { Extra {
key: "command", key: "command",
@@ -275,10 +283,33 @@ impl MagiskD {
}, },
Extra { Extra {
key: "notify", key: "notify",
value: Bool(notify), value: Bool(self.settings.notify),
}, },
]; ];
self.exec_cmd("log", &extras, info, true); self.exec_cmd("log", &extras, true);
}
pub(super) fn connect_app(&mut self) {
// If policy is undetermined, show dialog for user consent
if self.settings.policy == SuPolicy::Query {
self.app_request();
}
if !self.settings.log && !self.settings.notify {
return;
}
if fork_dont_care() != 0 {
return;
}
// Notify su usage to application
if self.settings.log {
self.app_log();
} else if self.settings.notify {
self.app_notify();
}
exit(0); exit(0);
} }
} }

View File

@@ -1,9 +1,10 @@
use super::connect::SuAppContext;
use super::db::RootSettings;
use crate::UCred; use crate::UCred;
use crate::daemon::{AID_ROOT, AID_SHELL, MagiskD, to_app_id, to_user_id}; use crate::daemon::{AID_ROOT, AID_SHELL, MagiskD, to_app_id, to_user_id};
use crate::db::{DbSettings, MultiuserMode, RootAccess}; use crate::db::{DbSettings, MultiuserMode, RootAccess};
use crate::ffi::{SuAppRequest, SuPolicy, SuRequest, exec_root_shell}; use crate::ffi::{SuPolicy, SuRequest, exec_root_shell};
use crate::socket::IpcRead; use crate::socket::IpcRead;
use crate::su::db::RootSettings;
use base::{LoggedResult, ResultExt, WriteExt, debug, error, exit_on_error, libc, warn}; use base::{LoggedResult, ResultExt, WriteExt, debug, error, exit_on_error, libc, warn};
use std::os::fd::{FromRawFd, IntoRawFd}; use std::os::fd::{FromRawFd, IntoRawFd};
use std::os::unix::net::UnixStream; use std::os::unix::net::UnixStream;
@@ -29,11 +30,11 @@ impl Default for SuRequest {
} }
pub struct SuInfo { pub struct SuInfo {
uid: i32, pub(super) uid: i32,
eval_uid: i32, pub(super) eval_uid: i32,
pub(super) mgr_pkg: String,
pub(super) mgr_uid: i32,
cfg: DbSettings, cfg: DbSettings,
mgr_pkg: String,
mgr_uid: i32,
access: Mutex<AccessInfo>, access: Mutex<AccessInfo>,
} }
@@ -129,37 +130,18 @@ impl MagiskD {
}; };
let info = self.get_su_info(cred.uid as i32); let info = self.get_su_info(cred.uid as i32);
let app_req = SuAppRequest {
uid: cred.uid as i32,
pid: cred.pid,
eval_uid: info.eval_uid,
mgr_pkg: &info.mgr_pkg,
mgr_uid: info.mgr_uid,
request: &req,
};
{ {
let mut access = info.access.lock().unwrap(); let mut access = info.access.lock().unwrap();
if access.settings.policy == SuPolicy::Query { // Talk to su manager
if let Ok(mut fd) = self.app_request(&app_req) { let mut app = SuAppContext {
access.settings.policy = SuPolicy { cred,
repr: fd request: &req,
.read_decodable::<i32>() info: &info,
.log() settings: &mut access.settings,
.map(i32::from_be) sdk_int: self.sdk_int(),
.unwrap_or(SuPolicy::Deny.repr),
}; };
} else { app.connect_app();
access.settings.policy = SuPolicy::Deny;
}
}
if access.settings.log {
self.app_log(&app_req, access.settings.policy, access.settings.notify);
} else if access.settings.notify {
self.app_notify(&app_req, access.settings.policy);
}
// Before unlocking, refresh the timestamp // Before unlocking, refresh the timestamp
access.refresh(); access.refresh();
@@ -286,9 +268,9 @@ impl MagiskD {
Arc::new(SuInfo { Arc::new(SuInfo {
uid, uid,
eval_uid, eval_uid,
cfg,
mgr_pkg, mgr_pkg,
mgr_uid, mgr_uid,
cfg,
access: Mutex::new(AccessInfo::new(access)), access: Mutex::new(AccessInfo::new(access)),
}) })
}; };