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 } ;
22use crate :: db:: Sqlite3 ;
33use 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;
87use crate :: logging:: { magisk_logging, setup_logfile, start_log_daemon} ;
98use crate :: mount:: { clean_mounts, setup_mounts} ;
109use crate :: package:: ManagerInfo ;
1110use crate :: selinux:: restore_tmpcon;
1211use 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 } ;
1619use std:: os:: unix:: net:: UnixStream ;
1720use std:: sync:: atomic:: { AtomicBool , AtomicU32 , Ordering } ;
1821use std:: sync:: { Mutex , OnceLock } ;
@@ -217,6 +220,14 @@ impl MagiskD {
217220}
218221
219222pub 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+
275336fn check_data ( ) -> bool {
276337 if let Ok ( file) = cstr ! ( "/proc/mounts" ) . open ( O_RDONLY | O_CLOEXEC ) {
277338 let mut mnt = false ;
0 commit comments