Skip to content

Commit 0c92e9f

Browse files
committed
RIIR, support inject rc
1 parent c8a16b0 commit 0c92e9f

File tree

5 files changed

+104
-44
lines changed

5 files changed

+104
-44
lines changed

native/src/init/init.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ impl MagiskInit {
2020
Self {
2121
preinit_dev: String::new(),
2222
mount_list: Vec::new(),
23+
rc_list: Vec::new(),
2324
overlay_con: Vec::new(),
2425
argv,
2526
config: BootConfig {

native/src/init/lib.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use logging::setup_klog;
88
// Has to be pub so all symbols in that crate is included
99
pub use magiskpolicy;
1010
use mount::{is_device_mounted, switch_root};
11-
use rootdir::{OverlayAttr, inject_magisk_rc};
11+
use rootdir::{OverlayAttr, inject_magisk_rc, inject_custom_rc};
1212

1313
#[path = "../include/consts.rs"]
1414
mod consts;
@@ -44,6 +44,7 @@ pub mod ffi {
4444
struct MagiskInit {
4545
preinit_dev: String,
4646
mount_list: Vec<String>,
47+
rc_list: Vec<String>,
4748
argv: *mut *mut c_char,
4849
config: BootConfig,
4950
overlay_con: Vec<OverlayAttr>,
@@ -69,6 +70,7 @@ pub mod ffi {
6970
#[namespace = "rust"]
7071
extern "Rust" {
7172
fn setup_klog();
73+
fn inject_custom_rc(mut rc_list: Vec<String>, fd: i32, tmp_dir: Utf8CStrRef);
7274
fn inject_magisk_rc(fd: i32, tmp_dir: Utf8CStrRef);
7375
fn switch_root(path: Utf8CStrRef);
7476
fn is_device_mounted(dev: u64, target: Pin<&mut CxxString>) -> bool;
@@ -91,6 +93,8 @@ pub mod ffi {
9193
fn mount_overlay(self: &mut MagiskInit, dest: Utf8CStrRef);
9294
fn handle_sepolicy(self: &mut MagiskInit);
9395
fn restore_overlay_contexts(self: &MagiskInit);
96+
fn load_overlay_rc(self: &mut MagiskInit, overlay: &Utf8CStrRef);
97+
fn handle_modules_rc(self: &mut MagiskInit, root_dir: &Utf8CStrRef);
9498
}
9599
unsafe extern "C++" {
96100
// Used in Rust
@@ -103,6 +107,7 @@ pub mod ffi {
103107
fn collect_devices(self: &MagiskInit);
104108
fn mount_preinit_dir(self: &MagiskInit);
105109
unsafe fn find_block(self: &MagiskInit, partname: *const c_char) -> u64;
110+
unsafe fn patch_rc_scripts(self: &MagiskInit, src_path: *const c_char, tmp_path: *const c_char, writable: bool) -> bool;
106111
unsafe fn patch_fissiond(self: &mut MagiskInit, tmp_path: *const c_char);
107112
}
108113
}

native/src/init/rootdir.cpp

Lines changed: 6 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212

1313
using namespace std;
1414

15-
static vector<string> rc_list;
16-
1715
#define NEW_INITRC_DIR "/system/etc/init/hw"
1816
#define INIT_RC "init.rc"
1917

@@ -43,7 +41,7 @@ static bool unxz(out_stream &strm, rust::Slice<const uint8_t> bytes) {
4341
}
4442

4543
// When return true, run patch_fissiond
46-
static bool patch_rc_scripts(const char *src_path, const char *tmp_path, bool writable) {
44+
bool MagiskInit::patch_rc_scripts(const char *src_path, const char *tmp_path, bool writable) const noexcept {
4745
auto src_dir = xopen_dir(src_path);
4846
if (!src_dir) return false;
4947
int src_fd = dirfd(src_dir.get());
@@ -95,12 +93,7 @@ static bool patch_rc_scripts(const char *src_path, const char *tmp_path, bool wr
9593
fprintf(dest.get(), "\n");
9694

9795
// Inject custom rc scripts
98-
for (auto &script : rc_list) {
99-
// Replace template arguments of rc scripts with dynamic paths
100-
replace_all(script, "${MAGISKTMP}", tmp_path);
101-
fprintf(dest.get(), "\n%s\n", script.data());
102-
}
103-
rc_list.clear();
96+
rust::inject_custom_rc(rc_list, fileno(dest.get()), tmp_path);
10497

10598
// Inject Magisk rc scripts
10699
rust::inject_magisk_rc(fileno(dest.get()), tmp_path);
@@ -175,34 +168,6 @@ void MagiskInit::patch_fissiond(const char *tmp_path) noexcept {
175168
}
176169
}
177170

178-
static void load_overlay_rc(const char *overlay) {
179-
auto dir = open_dir(overlay);
180-
if (!dir) return;
181-
182-
int dfd = dirfd(dir.get());
183-
// Do not allow overwrite init.rc
184-
unlinkat(dfd, INIT_RC, 0);
185-
186-
// '/' + name + '\0'
187-
char buf[NAME_MAX + 2];
188-
buf[0] = '/';
189-
for (dirent *entry; (entry = xreaddir(dir.get()));) {
190-
if (!str_ends(entry->d_name, ".rc")) {
191-
continue;
192-
}
193-
strscpy(buf + 1, entry->d_name, sizeof(buf) - 1);
194-
if (access(buf, F_OK) == 0) {
195-
LOGD("Replace rc script [%s]\n", entry->d_name);
196-
} else {
197-
LOGD("Found rc script [%s]\n", entry->d_name);
198-
int rc = xopenat(dfd, entry->d_name, O_RDONLY | O_CLOEXEC);
199-
rc_list.push_back(full_read(rc));
200-
close(rc);
201-
unlinkat(dfd, entry->d_name, 0);
202-
}
203-
}
204-
}
205-
206171
static void recreate_sbin(const char *mirror, bool use_bind_mount) {
207172
auto dp = xopen_dir(mirror);
208173
int src = dirfd(dp.get());
@@ -316,6 +281,8 @@ void MagiskInit::patch_ro_root() noexcept {
316281
mv_path(ROOTOVL "/sbin", ".");
317282
}
318283

284+
handle_modules_rc(ROOTOVL);
285+
319286
// Patch init.rc
320287
bool p;
321288
if (access(NEW_INITRC_DIR "/" INIT_RC, F_OK) == 0) {
@@ -356,6 +323,8 @@ void MagiskInit::patch_rw_root() noexcept {
356323
rm_rf("/data/overlay.d");
357324
rm_rf("/.backup");
358325

326+
handle_modules_rc("/");
327+
359328
// Patch init.rc
360329
if (patch_rc_scripts("/", "/sbin", true))
361330
patch_fissiond("/sbin");

native/src/init/rootdir.rs

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
use crate::consts::{ROOTMNT, ROOTOVL};
1+
use crate::consts::{PREINITMIRR, ROOTMNT, ROOTOVL};
22
use crate::ffi::MagiskInit;
3-
use base::libc::{O_CREAT, O_RDONLY, O_WRONLY};
3+
use base::libc::{O_CLOEXEC, O_CREAT, O_RDONLY, O_WRONLY};
44
use base::{
55
BufReadExt, Directory, FsPath, FsPathBuf, LoggedResult, ResultExt, Utf8CStr, Utf8CString,
6-
clone_attr, cstr, cstr_buf, debug, path,
6+
clone_attr, const_format::concatcp, cstr, cstr_buf, debug, path,
77
};
88
use std::io::BufReader;
99
use std::{
1010
fs::File,
11+
io::Read,
1112
io::Write,
1213
mem,
1314
os::fd::{FromRawFd, RawFd},
@@ -43,6 +44,17 @@ on property:init.svc.zygote=stopped
4344
mem::forget(file)
4445
}
4546

47+
pub fn inject_custom_rc(mut rc_list: Vec<String>, fd: RawFd, tmp_dir: &Utf8CStr) {
48+
let mut file = unsafe { File::from_raw_fd(fd) };
49+
rc_list.iter().for_each(|rc| {
50+
// Replace template arguments of rc scripts with dynamic paths
51+
let rc = rc.replace("${MAGISKTMP}", tmp_dir.as_str());
52+
write!(file, "\n{}\n", rc).ok();
53+
});
54+
mem::forget(file);
55+
rc_list.clear();
56+
}
57+
4658
pub struct OverlayAttr(Utf8CString, Utf8CString);
4759

4860
impl MagiskInit {
@@ -59,6 +71,65 @@ impl MagiskInit {
5971
}
6072
}
6173

74+
pub(crate) fn load_overlay_rc(&mut self, overlay: &Utf8CStr) {
75+
if let Ok(mut dir) = Directory::open(overlay) {
76+
let init_rc = FsPathBuf::from(cstr_buf::dynamic(256))
77+
.join(overlay)
78+
.join("init.rc");
79+
if init_rc.exists() {
80+
// Do not allow overwrite init.rc
81+
init_rc.remove().log_ok();
82+
}
83+
loop {
84+
match dir.read() {
85+
Ok(None) => break,
86+
Ok(Some(e)) if (e.is_file() && e.name().ends_with(".rc")) => {
87+
let name = e.name();
88+
let mut path = FsPathBuf::from(cstr_buf::dynamic(256)).join("/").join(name);
89+
if path.exists() {
90+
debug!("Replace rc script [{}]", name);
91+
} else {
92+
debug!("Found rc script [{}]", name);
93+
path = FsPathBuf::from(cstr_buf::dynamic(256))
94+
.join(overlay)
95+
.join(name);
96+
let mut rc_content = String::new();
97+
if let Ok(mut file) = path.open(O_RDONLY | O_CLOEXEC) {
98+
file.read_to_string(&mut rc_content).log_ok();
99+
self.rc_list.push(rc_content);
100+
drop(file);
101+
path.remove().log_ok();
102+
}
103+
}
104+
}
105+
Ok(_) => continue,
106+
Err(_) => break,
107+
}
108+
}
109+
}
110+
}
111+
112+
pub(crate) fn handle_modules_rc(&mut self, root_dir: &Utf8CStr) {
113+
if let Ok(mut dir) = Directory::open(path!(concatcp!("/data/", PREINITMIRR))) {
114+
loop {
115+
match dir.read() {
116+
Ok(None) => break,
117+
Ok(Some(e)) if e.is_dir() => {
118+
let name = e.name();
119+
let path = FsPathBuf::from(cstr_buf::dynamic(256))
120+
.join(concatcp!("/data/", PREINITMIRR))
121+
.join(name);
122+
self.load_overlay_rc(&path);
123+
let desc_path = FsPathBuf::from(cstr_buf::dynamic(256)).join(root_dir);
124+
path.copy_to(&desc_path).log_ok();
125+
}
126+
Ok(_) => continue,
127+
Err(_) => break,
128+
}
129+
}
130+
}
131+
}
132+
62133
fn mount_impl(
63134
&mut self,
64135
src_dir: &Utf8CStr,

scripts/util_functions.sh

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,19 @@ copy_preinit_files() {
584584
cat $r
585585
echo
586586
done > $PREINITDIR/sepolicy.rule
587+
588+
# Copy all enabled rc
589+
find "$PREINITDIR/" -mindepth 1 -maxdepth 1 -type d -exec rm -rf {} \;
590+
find /data/adb/modules* -mindepth 1 -maxdepth 1 -type d 2>/dev/null | while read -r MODDIR; do
591+
local MODID=$(basename "$MODDIR")
592+
[ -f "$MODDIR"/disable ] && continue
593+
[ -f "$MODDIR"/remove ] && continue
594+
[ -f "$MODDIR"/update ] && continue
595+
find "$MODDIR" -mindepth 1 -type f -name "*.rc" | while read -r file; do
596+
mkdir -p "$PREINITDIR/$MODID"
597+
cp "$file" "$PREINITDIR/$MODID/"
598+
done
599+
done
587600
}
588601

589602
#################
@@ -719,9 +732,10 @@ install_module() {
719732
cp -af $MODPATH/module.prop /data/adb/modules/$MODID/module.prop
720733
fi
721734

722-
# Copy over custom sepolicy rules
723-
if [ -f $MODPATH/sepolicy.rule ]; then
724-
ui_print "- Installing custom sepolicy rules"
735+
rc=$(find "$MODPATH" -mindepth 1 -type f -name "*.rc" -print -quit)
736+
# Copy over custom sepolicy rules and rc
737+
if [ -f $MODPATH/sepolicy.rule ] || [ -n "$rc" ]; then
738+
ui_print "- Installing custom sepolicy rules or rc script"
725739
copy_preinit_files
726740
fi
727741

0 commit comments

Comments
 (0)