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>,
}
struct SuAppRequest<'a> {
uid: i32,
pid: i32,
eval_uid: i32,
mgr_pkg: &'a str,
mgr_uid: i32,
request: &'a SuRequest,
}
unsafe extern "C++" {
#[namespace = "rust"]
#[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::daemon::{MagiskD, to_user_id};
use crate::ffi::{SuAppRequest, SuPolicy, get_magisk_tmp};
use crate::daemon::to_user_id;
use crate::ffi::{SuPolicy, SuRequest, get_magisk_tmp};
use crate::socket::IpcRead;
use ExtraVal::{Bool, Int, IntList, Str};
use base::{
BytesExt, FileAttr, LibcReturn, LoggedResult, OsError, ResultExt, cstr, fork_dont_care, info,
libc,
BytesExt, FileAttr, LibcReturn, LoggedResult, OsError, ResultExt, cstr, fork_dont_care, libc,
};
use libc::pollfd as PollFd;
use num_traits::AsPrimitive;
@@ -79,19 +81,21 @@ impl Extra {
}
}
impl MagiskD {
fn exec_cmd(
&self,
action: &'static str,
extras: &[Extra],
info: &SuAppRequest,
use_provider: bool,
) {
let user = to_user_id(info.eval_uid);
pub(super) struct SuAppContext<'a> {
pub(super) cred: libc::ucred,
pub(super) request: &'a SuRequest,
pub(super) info: &'a SuInfo,
pub(super) settings: &'a mut RootSettings,
pub(super) sdk_int: i32,
}
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();
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");
cmd.args([
"/system/bin",
@@ -104,7 +108,7 @@ impl MagiskD {
"--method",
action,
]);
if self.sdk_int() >= 30 {
if self.sdk_int >= 30 {
extras.iter().for_each(|e| e.add_bind(&mut cmd))
} else {
extras.iter().for_each(|e| e.add_bind_legacy(&mut cmd))
@@ -126,7 +130,7 @@ impl MagiskD {
"com.android.commands.am.Am",
"start",
"-p",
info.mgr_pkg,
&self.info.mgr_pkg,
"--user",
&user,
"-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>();
fifo.write_fmt(format_args!(
"{}/{}/su_request_{}",
get_magisk_tmp(),
INTERNAL_DIR,
info.pid
self.cred.pid
))
.ok();
let fd: LoggedResult<File> = try {
let mut attr = FileAttr::new();
attr.st.st_mode = 0o600;
attr.st.st_uid = info.mgr_uid.as_();
attr.st.st_gid = info.mgr_uid.as_();
attr.st.st_uid = self.info.mgr_uid.as_();
attr.st.st_gid = self.info.mgr_uid.as_();
attr.con.write_str(MAGISK_FILE_CON).ok();
fifo.mkfifo(0o600)?;
@@ -179,14 +183,14 @@ impl MagiskD {
},
Extra {
key: "uid",
value: Int(info.eval_uid),
value: Int(self.info.eval_uid),
},
Extra {
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
let fd = fifo.open(libc::O_RDWR | libc::O_CLOEXEC)?;
@@ -206,68 +210,72 @@ impl MagiskD {
};
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) {
if fork_dont_care() != 0 {
return;
}
fn app_notify(&self) {
let extras = [
Extra {
key: "from.uid",
value: Int(info.uid),
value: Int(self.cred.uid.as_()),
},
Extra {
key: "pid",
value: Int(info.pid),
value: Int(self.cred.pid.as_()),
},
Extra {
key: "policy",
value: Int(policy.repr),
value: Int(self.settings.policy.repr),
},
];
self.exec_cmd("notify", &extras, info, true);
exit(0);
self.exec_cmd("notify", &extras, true);
}
pub fn app_log(&self, info: &SuAppRequest, policy: SuPolicy, notify: bool) {
if fork_dont_care() != 0 {
return;
}
let command = if info.request.command.is_empty() {
&info.request.shell
fn app_log(&self) {
let command = if self.request.command.is_empty() {
&self.request.shell
} else {
&info.request.command
&self.request.command
};
let extras = [
Extra {
key: "from.uid",
value: Int(info.uid),
value: Int(self.cred.uid.as_()),
},
Extra {
key: "to.uid",
value: Int(info.request.target_uid),
value: Int(self.request.target_uid),
},
Extra {
key: "pid",
value: Int(info.pid),
value: Int(self.cred.pid.as_()),
},
Extra {
key: "policy",
value: Int(policy.repr),
value: Int(self.settings.policy.repr),
},
Extra {
key: "target",
value: Int(info.request.target_pid),
value: Int(self.request.target_pid),
},
Extra {
key: "context",
value: Str(info.request.context.clone()),
value: Str(self.request.context.clone()),
},
Extra {
key: "gids",
value: IntList(info.request.gids.clone()),
value: IntList(self.request.gids.clone()),
},
Extra {
key: "command",
@@ -275,10 +283,33 @@ impl MagiskD {
},
Extra {
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);
}
}

View File

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