Skip to content

Commit d182930

Browse files
committed
Move more daemon_start code into Rust
1 parent 73840f8 commit d182930

File tree

7 files changed

+97
-77
lines changed

7 files changed

+97
-77
lines changed

native/src/base/mount.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ impl Utf8CStr {
1616
}
1717
}
1818

19-
pub fn remount_with_flags(&self, flags: c_ulong) -> OsResult<()> {
19+
pub fn remount_mount_point_flags(&self, flags: c_ulong) -> OsResult<()> {
2020
unsafe {
2121
libc::mount(
2222
ptr::null(),
@@ -29,6 +29,19 @@ impl Utf8CStr {
2929
}
3030
}
3131

32+
pub fn remount_mount_flags(&self, flags: c_ulong) -> OsResult<()> {
33+
unsafe {
34+
libc::mount(
35+
ptr::null(),
36+
self.as_ptr(),
37+
ptr::null(),
38+
libc::MS_REMOUNT | flags,
39+
ptr::null(),
40+
)
41+
.check_os_err("remount", Some(self), None)
42+
}
43+
}
44+
3245
pub fn remount_with_data(&self, data: &Utf8CStr) -> OsResult<()> {
3346
unsafe {
3447
libc::mount(

native/src/core/daemon.cpp

Lines changed: 1 addition & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -325,29 +325,6 @@ static void handle_request(pollfd *pfd) {
325325
}
326326
}
327327

328-
static void switch_cgroup(const char *cgroup, int pid) {
329-
char buf[32];
330-
ssprintf(buf, sizeof(buf), "%s/cgroup.procs", cgroup);
331-
if (access(buf, F_OK) != 0)
332-
return;
333-
int fd = xopen(buf, O_WRONLY | O_APPEND | O_CLOEXEC);
334-
if (fd == -1)
335-
return;
336-
ssprintf(buf, sizeof(buf), "%d\n", pid);
337-
xwrite(fd, buf, strlen(buf));
338-
close(fd);
339-
}
340-
341-
static int setcon(const char *con) {
342-
int fd = open("/proc/self/attr/current", O_WRONLY | O_CLOEXEC);
343-
if (fd < 0)
344-
return fd;
345-
size_t len = strlen(con) + 1;
346-
int rc = write(fd, con, len);
347-
close(fd);
348-
return rc != len;
349-
}
350-
351328
static void daemon_entry() {
352329
android_logging();
353330

@@ -369,49 +346,15 @@ static void daemon_entry() {
369346
if (fd > STDERR_FILENO)
370347
close(fd);
371348

372-
setsid();
373-
setcon(MAGISK_PROC_CON);
374-
375349
rust::daemon_entry();
376350
SDK_INT = MagiskD::Get().sdk_int();
377351

378-
// Escape from cgroup
379-
int pid = getpid();
380-
switch_cgroup("/acct", pid);
381-
switch_cgroup("/dev/cg2_bpf", pid);
382-
switch_cgroup("/sys/fs/cgroup", pid);
383-
if (get_prop("ro.config.per_app_memcg") != "false") {
384-
switch_cgroup("/dev/memcg/apps", pid);
385-
}
386-
387352
// Get self stat
388353
xstat("/proc/self/exe", &self_st);
389354

390-
// Samsung workaround #7887
391-
if (access("/system_ext/app/mediatek-res/mediatek-res.apk", F_OK) == 0) {
392-
set_prop("ro.vendor.mtk_model", "0");
393-
}
394-
395-
// Cleanups
396-
const char *tmp = get_magisk_tmp();
397-
char path[64];
398-
ssprintf(path, sizeof(path), "%s/" ROOTMNT, tmp);
399-
if (access(path, F_OK) == 0) {
400-
file_readline(true, path, [](string_view line) -> bool {
401-
umount2(line.data(), MNT_DETACH);
402-
return true;
403-
});
404-
}
405-
if (getenv("REMOUNT_ROOT")) {
406-
xmount(nullptr, "/", nullptr, MS_REMOUNT | MS_RDONLY, nullptr);
407-
unsetenv("REMOUNT_ROOT");
408-
}
409-
ssprintf(path, sizeof(path), "%s/" ROOTOVL, tmp);
410-
rm_rf(path);
411-
412355
fd = xsocket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
413356
sockaddr_un addr = {.sun_family = AF_LOCAL};
414-
ssprintf(addr.sun_path, sizeof(addr.sun_path), "%s/" MAIN_SOCKET, tmp);
357+
ssprintf(addr.sun_path, sizeof(addr.sun_path), "%s/" MAIN_SOCKET, get_magisk_tmp());
415358
unlink(addr.sun_path);
416359
if (xbind(fd, (sockaddr *) &addr, sizeof(addr)))
417360
exit(1);

native/src/core/daemon.rs

Lines changed: 74 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
1-
use crate::consts::{MAGISK_FULL_VER, MAIN_CONFIG, SECURE_DIR};
1+
use crate::consts::{MAGISK_FULL_VER, MAGISK_PROC_CON, MAIN_CONFIG, ROOTMNT, ROOTOVL, SECURE_DIR};
22
use crate::db::Sqlite3;
33
use crate::ffi::{
44
DbEntryKey, ModuleInfo, RequestCode, check_key_combo, disable_modules, exec_common_scripts,
55
exec_module_scripts, get_magisk_tmp, initialize_denylist, setup_magisk_env,
66
};
7-
use crate::get_prop;
87
use crate::logging::{magisk_logging, setup_logfile, start_log_daemon};
98
use crate::mount::{clean_mounts, setup_mounts};
109
use crate::package::ManagerInfo;
1110
use crate::selinux::restore_tmpcon;
1211
use crate::su::SuInfo;
13-
use base::libc::{O_CLOEXEC, O_RDONLY};
14-
use base::{AtomicArc, BufReadExt, FsPathBuilder, ResultExt, Utf8CStr, cstr, error, info, libc};
15-
use std::io::BufReader;
12+
use crate::{get_prop, set_prop};
13+
use base::libc::{O_APPEND, O_CLOEXEC, O_RDONLY, O_WRONLY};
14+
use base::{
15+
AtomicArc, BufReadExt, FsPathBuilder, ResultExt, Utf8CStr, Utf8CStrBuf, cstr, error, info, libc,
16+
};
17+
use std::fmt::Write as FmtWrite;
18+
use std::io::{BufReader, Write};
1619
use std::os::unix::net::UnixStream;
1720
use std::sync::atomic::{AtomicBool, AtomicU32, Ordering};
1821
use std::sync::{Mutex, OnceLock};
@@ -217,6 +220,14 @@ impl MagiskD {
217220
}
218221

219222
pub fn daemon_entry() {
223+
unsafe { libc::setsid() };
224+
225+
// Make sure the current context is magisk
226+
if let Ok(mut current) = cstr!("/proc/self/attr/current").open(O_WRONLY | O_CLOEXEC) {
227+
let con = cstr!(MAGISK_PROC_CON);
228+
current.write_all(con.as_bytes_with_nul()).log_ok();
229+
}
230+
220231
start_log_daemon();
221232
magisk_logging();
222233
info!("Magisk {} daemon started", MAGISK_FULL_VER);
@@ -226,25 +237,25 @@ pub fn daemon_entry() {
226237
|| get_prop(cstr!("ro.product.device"), false).contains("vsoc");
227238

228239
// Load config status
229-
let path = cstr::buf::new::<64>()
230-
.join_path(get_magisk_tmp())
240+
let magisk_tmp = get_magisk_tmp();
241+
let mut tmp_path = cstr::buf::new::<64>()
242+
.join_path(magisk_tmp)
231243
.join_path(MAIN_CONFIG);
232244
let mut is_recovery = false;
233-
if let Ok(file) = path.open(O_RDONLY | O_CLOEXEC) {
234-
let mut file = BufReader::new(file);
235-
file.foreach_props(|key, val| {
245+
if let Ok(main_config) = tmp_path.open(O_RDONLY | O_CLOEXEC) {
246+
BufReader::new(main_config).foreach_props(|key, val| {
236247
if key == "RECOVERYMODE" {
237248
is_recovery = val == "true";
238249
return false;
239250
}
240251
true
241252
});
242253
}
254+
tmp_path.truncate(magisk_tmp.len());
243255

244256
let mut sdk_int = -1;
245-
if let Ok(file) = cstr!("/system/build.prop").open(O_RDONLY | O_CLOEXEC) {
246-
let mut file = BufReader::new(file);
247-
file.foreach_props(|key, val| {
257+
if let Ok(build_prop) = cstr!("/system/build.prop").open(O_RDONLY | O_CLOEXEC) {
258+
BufReader::new(build_prop).foreach_props(|key, val| {
248259
if key == "ro.build.version.sdk" {
249260
sdk_int = val.parse::<i32>().unwrap_or(-1);
250261
return false;
@@ -262,6 +273,42 @@ pub fn daemon_entry() {
262273

263274
restore_tmpcon().log_ok();
264275

276+
// Escape from cgroup
277+
let pid = unsafe { libc::getpid() };
278+
switch_cgroup("/acct", pid);
279+
switch_cgroup("/dev/cg2_bpf", pid);
280+
switch_cgroup("/sys/fs/cgroup", pid);
281+
if get_prop(cstr!("ro.config.per_app_memcg"), false) != "false" {
282+
switch_cgroup("/dev/memcg/apps", pid);
283+
}
284+
285+
// Samsung workaround #7887
286+
if cstr!("/system_ext/app/mediatek-res/mediatek-res.apk").exists() {
287+
set_prop(cstr!("ro.vendor.mtk_model"), cstr!("0"), false);
288+
}
289+
290+
// Cleanup pre-init mounts
291+
tmp_path.append_path(ROOTMNT);
292+
if let Ok(mount_list) = tmp_path.open(O_RDONLY | O_CLOEXEC) {
293+
BufReader::new(mount_list).foreach_lines(|line| {
294+
let item = Utf8CStr::from_string(line);
295+
item.unmount().log_ok();
296+
true
297+
})
298+
}
299+
tmp_path.truncate(magisk_tmp.len());
300+
301+
// Remount rootfs as read-only if requested
302+
if std::env::var_os("REMOUNT_ROOT").is_some() {
303+
cstr!("/").remount_mount_flags(libc::MS_RDONLY).log_ok();
304+
unsafe { std::env::remove_var("REMOUNT_ROOT") };
305+
}
306+
307+
// Remove all pre-init overlay files to free-up memory
308+
tmp_path.append_path(ROOTOVL);
309+
tmp_path.remove_all().log_ok();
310+
tmp_path.truncate(magisk_tmp.len());
311+
265312
let magiskd = MagiskD {
266313
sdk_int,
267314
is_emulator,
@@ -272,6 +319,20 @@ pub fn daemon_entry() {
272319
MAGISKD.set(magiskd).ok();
273320
}
274321

322+
fn switch_cgroup(cgroup: &str, pid: i32) {
323+
let mut buf = cstr::buf::new::<64>()
324+
.join_path(cgroup)
325+
.join_path("cgroup.procs");
326+
if !buf.exists() {
327+
return;
328+
}
329+
if let Ok(mut file) = buf.open(O_WRONLY | O_APPEND | O_CLOEXEC) {
330+
buf.clear();
331+
buf.write_fmt(format_args!("{}", pid)).ok();
332+
file.write_all(buf.as_bytes()).log_ok();
333+
}
334+
}
335+
275336
fn check_data() -> bool {
276337
if let Ok(file) = cstr!("/proc/mounts").open(O_RDONLY | O_CLOEXEC) {
277338
let mut mnt = false;

native/src/core/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ pub mod ffi {
137137
#[cxx_name = "prop_cb"]
138138
type PropCb;
139139
unsafe fn get_prop_rs(name: *const c_char, persist: bool) -> String;
140+
#[cxx_name = "set_prop"]
141+
unsafe fn set_prop_rs(name: *const c_char, value: *const c_char, skip_svc: bool) -> i32;
140142
unsafe fn prop_cb_exec(
141143
cb: Pin<&mut PropCb>,
142144
name: *const c_char,
@@ -277,3 +279,7 @@ impl SuRequest {
277279
pub fn get_prop(name: &Utf8CStr, persist: bool) -> String {
278280
unsafe { ffi::get_prop_rs(name.as_ptr(), persist) }
279281
}
282+
283+
pub fn set_prop(name: &Utf8CStr, value: &Utf8CStr, skip_svc: bool) -> bool {
284+
unsafe { ffi::set_prop_rs(name.as_ptr(), value.as_ptr(), skip_svc) == 0 }
285+
}

native/src/core/mount.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ pub fn setup_mounts() {
7474
let _: LoggedResult<()> = try {
7575
module_mnt.mkdir(0o755)?;
7676
cstr!(MODULEROOT).bind_mount_to(&module_mnt)?;
77-
module_mnt.remount_with_flags(libc::MS_RDONLY)?;
77+
module_mnt.remount_mount_point_flags(libc::MS_RDONLY)?;
7878
};
7979
}
8080

native/src/include/consts.hpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,8 @@
2020
#define BBPATH INTLROOT "/busybox"
2121
#define ROOTOVL INTLROOT "/rootdir"
2222
#define SHELLPTS INTLROOT "/pts"
23-
#define ROOTMNT ROOTOVL "/.mount_list"
24-
#define SELINUXMOCK INTLROOT "/selinux"
2523
#define MAIN_CONFIG INTLROOT "/config"
2624
#define MAIN_SOCKET DEVICEDIR "/socket"
27-
#define LOG_PIPE DEVICEDIR "/log"
2825

2926
constexpr const char *applet_names[] = { "su", "resetprop", nullptr };
3027

@@ -39,7 +36,6 @@ constexpr const char *applet_names[] = { "su", "resetprop", nullptr };
3936
#define MAGISK_FILE_CON "u:object_r:" SEPOL_FILE_TYPE ":s0"
4037
// Log pipe that only root and zygote can open
4138
#define SEPOL_LOG_TYPE "magisk_log_file"
42-
#define MAGISK_LOG_CON "u:object_r:" SEPOL_LOG_TYPE ":s0"
4339

4440
extern int SDK_INT;
4541
#define APP_DATA_DIR (SDK_INT >= 24 ? "/data/user_de" : "/data/user")

native/src/include/consts.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ pub const SELINUXMOCK: &str = concatcp!(INTERNAL_DIR, "/selinux");
3232

3333
// Unconstrained domain the daemon and root processes run in
3434
pub const SEPOL_PROC_DOMAIN: &str = "magisk";
35+
pub const MAGISK_PROC_CON: &str = concatcp!("u:r:", SEPOL_PROC_DOMAIN, ":s0");
3536
// Unconstrained file type that anyone can access
3637
pub const SEPOL_FILE_TYPE: &str = "magisk_file";
3738
// Log pipe that only root and zygote can open

0 commit comments

Comments
 (0)