Skip to content

Commit 2da68f7

Browse files
Howard20181topjohnwu
authored andcommitted
RIIR, support inject rc
1 parent a2896be commit 2da68f7

5 files changed

Lines changed: 105 additions & 51 deletions

File tree

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
@@ -7,7 +7,7 @@ use logging::setup_klog;
77
// Has to be pub so all symbols in that crate is included
88
pub use magiskpolicy;
99
use mount::{is_device_mounted, switch_root};
10-
use rootdir::{OverlayAttr, inject_magisk_rc};
10+
use rootdir::{OverlayAttr, inject_magisk_rc, inject_custom_rc};
1111

1212
#[path = "../include/consts.rs"]
1313
mod consts;
@@ -43,6 +43,7 @@ pub mod ffi {
4343
struct MagiskInit {
4444
preinit_dev: String,
4545
mount_list: Vec<String>,
46+
rc_list: Vec<String>,
4647
argv: *mut *mut c_char,
4748
config: BootConfig,
4849
overlay_con: Vec<OverlayAttr>,
@@ -68,6 +69,7 @@ pub mod ffi {
6869
#[namespace = "rust"]
6970
extern "Rust" {
7071
fn setup_klog();
72+
fn inject_custom_rc(mut rc_list: Vec<String>, fd: i32, tmp_dir: Utf8CStrRef);
7173
fn inject_magisk_rc(fd: i32, tmp_dir: Utf8CStrRef);
7274
fn switch_root(path: Utf8CStrRef);
7375
fn is_device_mounted(dev: u64, target: Pin<&mut CxxString>) -> bool;
@@ -90,6 +92,8 @@ pub mod ffi {
9092
fn mount_overlay(self: &mut MagiskInit, dest: Utf8CStrRef);
9193
fn handle_sepolicy(self: &mut MagiskInit);
9294
fn restore_overlay_contexts(self: &MagiskInit);
95+
fn load_overlay_rc(self: &mut MagiskInit, overlay: &Utf8CStrRef);
96+
fn handle_modules_rc(self: &mut MagiskInit, root_dir: &Utf8CStrRef);
9397
}
9498
unsafe extern "C++" {
9599
// Used in Rust
@@ -102,6 +106,7 @@ pub mod ffi {
102106
fn collect_devices(self: &MagiskInit);
103107
fn mount_preinit_dir(self: &MagiskInit);
104108
unsafe fn find_block(self: &MagiskInit, partname: *const c_char) -> u64;
109+
unsafe fn patch_rc_scripts(self: &MagiskInit, src_path: *const c_char, tmp_path: *const c_char, writable: bool) -> bool;
105110
unsafe fn patch_fissiond(self: &mut MagiskInit, tmp_path: *const c_char);
106111
}
107112
}

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: 75 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
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};
43
use base::{
54
BufReadExt, Directory, FsPathBuilder, LoggedResult, ResultExt, Utf8CStr, Utf8CString,
6-
clone_attr, cstr, debug,
7-
};
8-
use std::io::BufReader;
9-
use std::{
10-
fs::File,
11-
io::Write,
12-
mem,
13-
os::fd::{FromRawFd, RawFd},
5+
clone_attr,
6+
const_format::concatcp,
7+
cstr, debug,
8+
libc::{O_CLOEXEC, O_CREAT, O_RDONLY, O_WRONLY},
149
};
10+
use std::{fs::File, io::BufReader, io::Read, io::Write, mem, os::fd::FromRawFd, os::fd::RawFd};
1511

1612
pub fn inject_magisk_rc(fd: RawFd, tmp_dir: &Utf8CStr) {
1713
debug!("Injecting magisk rc");
@@ -43,6 +39,17 @@ on property:init.svc.zygote=stopped
4339
mem::forget(file)
4440
}
4541

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

4855
impl MagiskInit {
@@ -59,6 +66,64 @@ impl MagiskInit {
5966
}
6067
}
6168

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