1
1
use std:: env:: set_var;
2
2
use std:: fs;
3
3
use std:: os:: unix:: fs:: symlink;
4
- use std:: path:: Path ; // For working with files
5
- use std :: process :: Command ;
4
+ use std:: path:: { Path , PathBuf } ;
5
+ use sys_mount :: { unmount , Mount , MountFlags , UnmountFlags } ;
6
6
mod utils;
7
- use utils:: { executev , extract_file , mount } ;
7
+ use utils:: { extract_file , remount_root , switch_init } ;
8
8
9
9
pub fn job ( ) {
10
10
// Export some possibly required env vars for magisk
11
11
set_var ( "FIRST_STAGE" , "1" ) ;
12
12
set_var ( "ASH_STANDALONE" , "1" ) ;
13
13
14
14
// Initialize vars
15
- let init_real = "/init.real" ;
16
- let bin_dir = if Path :: new ( "/sbin" ) . exists ( ) {
17
- "/sbin"
18
- } else {
19
- "/system/bin"
20
- } ;
15
+ let bin_dir = "/sbin" ;
21
16
22
17
let superuser_config = "/init.superuser.rc" ;
23
18
let magisk_config = & format ! ( "{}{}" , bin_dir, "/.magisk/config" ) ;
@@ -34,49 +29,112 @@ pub fn job() {
34
29
} ;
35
30
36
31
//// Initialize bin_dir
37
- if bin_dir != "/sbin" {
38
- for dir in [ "/dev/magisk/upper" , "/dev/magisk/work" ] . iter ( ) {
39
- fs:: create_dir_all ( dir) . expect ( "Error: Failed to setup bin_dir at /dev" ) ;
40
- extract_file ( "/dev/magisk_bin" , magisk_bin_data, 0o755 ) ;
41
- Command :: new ( "/dev/magisk_bin" )
42
- . args ( & [ "--clone-attr" , "/system/bin" , "/dev/magisk/upper" ] )
43
- . spawn ( )
44
- . expect ( "Error: Failed to clone attrs at /dev/magisk/upper" ) ;
32
+ if Path :: new ( bin_dir) . exists ( ) {
33
+ // When empty
34
+ if PathBuf :: from ( bin_dir)
35
+ . read_dir ( )
36
+ . map ( |mut i| i. next ( ) . is_none ( ) )
37
+ . unwrap_or ( false )
38
+ {
39
+ match Mount :: new ( bin_dir, bin_dir, "tmpfs" , MountFlags :: empty ( ) , None ) {
40
+ Ok ( _) => { }
41
+ Err ( why) => {
42
+ println ! (
43
+ "rusty-magisk: Failed to setup tmpfs at {}: {}" ,
44
+ bin_dir, why
45
+ ) ;
46
+ switch_init ( ) ;
47
+ }
48
+ }
49
+ } else {
50
+ // When not empty
51
+ remount_root ( ) ;
52
+ match fs:: write ( format ! ( "{}/{}" , bin_dir, ".rwfs" ) , "" ) {
53
+ Ok ( _) => match fs:: remove_file ( format ! ( "{}/{}" , bin_dir, ".rwfs" ) ) {
54
+ Ok ( _) => { }
55
+ Err ( _) => { }
56
+ } ,
57
+ Err ( why) => {
58
+ println ! ( "rusty-magisk: {} is not writable: {}" , bin_dir, why) ;
59
+ switch_init ( ) ;
60
+ }
61
+ }
45
62
}
46
63
} else {
47
- // Remount required mountpoints as rw
48
- mount ( & [ & "-o" , "remount,rw" , "/" ] ) ;
49
- if Path :: new ( bin_dir) . exists ( ) {
50
- mount ( & [ & "-o" , "remount,rw" , bin_dir] ) ;
64
+ match fs:: create_dir ( bin_dir) {
65
+ Ok ( _) => match Mount :: new ( bin_dir, bin_dir, "tmpfs" , MountFlags :: empty ( ) , None ) {
66
+ Ok ( _) => { }
67
+ Err ( why) => {
68
+ println ! (
69
+ "rusty-magisk: Failed to setup tmpfs at {}: {}" ,
70
+ bin_dir, why
71
+ ) ;
72
+ switch_init ( ) ;
73
+ }
74
+ } ,
75
+ Err ( why) => {
76
+ println ! (
77
+ "rusty-magisk: Root(/) is not writable, failed to initialize {}: {}" ,
78
+ bin_dir, why
79
+ ) ;
80
+ switch_init ( ) ;
81
+ }
82
+ }
83
+ }
84
+
85
+ // Initialize procfs
86
+ if !Path :: new ( "/proc/cpuinfo" ) . exists ( ) {
87
+ match Mount :: new ( "/proc" , "/proc" , "proc" , MountFlags :: empty ( ) , None ) {
88
+ Ok ( _) => { }
89
+ Err ( _) => {
90
+ println ! ( "rusty-magisk: Failed to initialize procfs" ) ;
91
+ switch_init ( ) ;
92
+ }
51
93
}
52
94
}
53
95
54
96
// Create required dirs in bin_dir
55
97
let mirror_dir = [
98
+ format ! ( "{}{}" , bin_dir, "/.magisk/modules" ) ,
56
99
format ! ( "{}{}" , bin_dir, "/.magisk/mirror/data" ) ,
57
100
format ! ( "{}{}" , bin_dir, "/.magisk/mirror/system" ) ,
58
- format ! ( "{}{}" , bin_dir, "/.magisk/modules" ) ,
59
- // format!("{}{}", bin_dir, "/.magisk/block"),
60
101
] ;
61
102
62
103
for dir in mirror_dir. iter ( ) {
63
- fs:: create_dir_all ( dir) . expect ( & format ! ( "Failed to create {} dir" , dir) ) ;
104
+ match fs:: create_dir_all ( dir) {
105
+ Ok ( _) => { }
106
+ Err ( why) => {
107
+ println ! ( "rusty-magisk: Failed to create {} dir: {}" , dir, why) ;
108
+ }
109
+ }
64
110
}
65
111
66
112
//// Bind data and system mirrors in bin_dir
67
- let mut mirror_count = 1 ;
68
- for mirror_source in [ "/data" , "/system" ] . iter ( ) {
69
- mount ( & [ & "-o" , "bind" , mirror_source, & mirror_dir[ mirror_count] ] ) ;
70
- mirror_count += 1 ;
113
+ let mut mirror_count = 2 ;
114
+
115
+ for mirror_source in [ "/system" , "/data" ] . iter ( ) {
116
+ match Mount :: new (
117
+ mirror_source,
118
+ & mirror_dir[ mirror_count] ,
119
+ "" ,
120
+ MountFlags :: BIND ,
121
+ None ,
122
+ ) {
123
+ Ok ( _) => { }
124
+ Err ( why) => {
125
+ eprintln ! (
126
+ "rusty-magisk: Failed to bind mount {} into {}: {}" ,
127
+ mirror_source, & mirror_dir[ mirror_count] , why
128
+ ) ;
129
+ }
130
+ }
131
+ mirror_count -= 1 ;
71
132
}
72
133
73
- // Double remount bin_dir
74
- mount ( & [ & "-o" , "remount,rw" , bin_dir] ) ;
75
-
76
134
///////////////////////////
77
135
//// Initialize magisk ////
78
136
// Extract magisk and set it up
79
-
137
+ remount_root ( ) ;
80
138
extract_file ( superuser_config, include_bytes ! ( "config/su" ) , 0o755 ) ;
81
139
extract_file ( magisk_config, include_bytes ! ( "config/magisk" ) , 0o755 ) ;
82
140
extract_file ( magisk_bin, magisk_bin_data, 0o755 ) ;
@@ -87,7 +145,11 @@ pub fn job() {
87
145
match symlink ( magisk_bin, format ! ( "{}/{}" , bin_dir, file) ) {
88
146
Ok ( _) => { }
89
147
Err ( why) => {
90
- eprintln ! ( "Error: Failed to symlink for {}: {}" , file, why) ;
148
+ println ! (
149
+ "rusty-magisk: Failed to create symlink for {}: {}" ,
150
+ file, why
151
+ ) ;
152
+ switch_init ( ) ;
91
153
}
92
154
}
93
155
}
@@ -103,7 +165,7 @@ pub fn job() {
103
165
match fs:: create_dir_all ( dir) {
104
166
Ok ( _) => { }
105
167
Err ( why) => {
106
- eprintln ! ( "Error : Failed to create {} dir: {}" , dir, why) ;
168
+ println ! ( "rusty-magisk : Failed to create {} dir: {}" , dir, why) ;
107
169
}
108
170
}
109
171
}
@@ -117,39 +179,25 @@ pub fn job() {
117
179
0o644 ,
118
180
) ,
119
181
Err ( why) => {
120
- eprintln ! ( "Error : Failed to create MagiskApkDir dir: {}" , why) ;
182
+ println ! ( "rusty-magisk : Failed to create MagiskApkDir dir: {}" , why) ;
121
183
}
122
184
}
123
185
}
124
186
125
- for su_bin in [ "/system/bin/su" , "/system/xbin/su" ] . iter ( ) {
126
- if Path :: new ( su_bin) . exists ( ) {
127
- match fs:: remove_file ( su_bin) {
128
- Ok ( _) => { }
129
-
130
- Err ( why) => {
131
- eprintln ! (
132
- "Error: Failed to remove existing {} binary: {}" ,
133
- su_bin, why
134
- ) ;
135
- }
136
- }
137
- }
138
-
139
- /*
140
- match symlink("/sbin/su", su_bin) {
141
- Ok(_) => {}
142
- Err(why) => {
143
- eprintln!("Error: Failed to symlink for {}: {}", su_bin, why);
144
- }
145
- }
146
- */
147
- }
148
-
149
187
//// Swtitch process to OS init.
150
- if Path :: new ( init_real) . exists ( ) {
151
- executev ( & [ init_real] ) ;
188
+ // Unmount our /proc to ensure real android init doesn't panic
189
+ match unmount ( "/proc" , UnmountFlags :: DETACH ) {
190
+ Ok ( _) => { }
191
+ Err ( why) => {
192
+ println ! (
193
+ "rusty-magisk: Failed to detach /proc, trying to switch init anyway: {}" ,
194
+ why
195
+ ) ;
196
+ }
152
197
}
198
+ switch_init ( ) ;
153
199
}
154
200
155
- fn main ( ) { }
201
+ fn main ( ) {
202
+ job ( ) ;
203
+ }
0 commit comments