Skip to content

Commit 1c8586a

Browse files
committed
Use /metadata if /metadata/watchdog not exist
1 parent 8efa16d commit 1c8586a

5 files changed

Lines changed: 61 additions & 19 deletions

File tree

kernel/runtime/ksud_integration.c

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -183,18 +183,35 @@ static struct file_operations fops_proxy;
183183
static ssize_t ksu_rc_pos = 0;
184184
const size_t ksu_rc_len = sizeof(KERNEL_SU_RC) - 1;
185185

186-
// Dynamic rc content from /metadata/watchdog/ksu/modules.rc, populated lazily at
187-
// the first read/fstat of /system/etc/init/hw/init.rc.
188-
#define MODULE_RC_PATH "/metadata/watchdog/ksu/modules.rc"
189-
#define MODULE_RC_MAX (1u << 20) /* 1 MiB safety cap */
186+
// Prefer /metadata/watchdog/ when present, else /metadata.
187+
#define MODULE_RC_PATH_WATCHDOG "/metadata/watchdog/ksu/modules.rc"
188+
#define MODULE_RC_PATH_DEFAULT "/metadata/ksu/modules.rc"
189+
#define MODULE_RC_MAX (1u << 20) /* 1 MiB cap */
190190
static char *module_rc_buf;
191191
static size_t module_rc_len;
192192
static ssize_t module_rc_pos;
193193

194+
static struct file *open_module_rc(const char **chosen_path)
195+
{
196+
struct file *f = filp_open(MODULE_RC_PATH_WATCHDOG, O_RDONLY, 0);
197+
if (!IS_ERR(f)) {
198+
*chosen_path = MODULE_RC_PATH_WATCHDOG;
199+
return f;
200+
}
201+
f = filp_open(MODULE_RC_PATH_DEFAULT, O_RDONLY, 0);
202+
if (!IS_ERR(f)) {
203+
*chosen_path = MODULE_RC_PATH_DEFAULT;
204+
return f;
205+
}
206+
*chosen_path = MODULE_RC_PATH_DEFAULT;
207+
return f;
208+
}
209+
194210
static void load_module_rc_once(void)
195211
{
196212
static bool loaded = false;
197213
struct file *f;
214+
const char *path = NULL;
198215
loff_t pos = 0;
199216
ssize_t r;
200217
size_t fsize;
@@ -203,14 +220,14 @@ static void load_module_rc_once(void)
203220
return;
204221
loaded = true;
205222

206-
f = filp_open(MODULE_RC_PATH, O_RDONLY, 0);
223+
f = open_module_rc(&path);
207224
if (IS_ERR(f)) {
208-
pr_info("module rc: open %s failed: %ld\n", MODULE_RC_PATH, PTR_ERR(f));
225+
pr_info("module rc: open failed: %ld\n", PTR_ERR(f));
209226
return;
210227
}
211228

212229
if (!S_ISREG(file_inode(f)->i_mode)) {
213-
pr_warn("module rc: %s is not a regular file\n", MODULE_RC_PATH);
230+
pr_warn("module rc: %s is not a regular file\n", path);
214231
filp_close(f, NULL);
215232
return;
216233
}
@@ -221,7 +238,7 @@ static void load_module_rc_once(void)
221238
return;
222239
}
223240
if (fsize > MODULE_RC_MAX) {
224-
pr_warn("module rc: %s too large (%zu), truncating to %u\n", MODULE_RC_PATH, fsize, MODULE_RC_MAX);
241+
pr_warn("module rc: %s too large (%zu), truncating to %u\n", path, fsize, MODULE_RC_MAX);
225242
fsize = MODULE_RC_MAX;
226243
}
227244

@@ -243,7 +260,7 @@ static void load_module_rc_once(void)
243260
}
244261

245262
module_rc_len = r;
246-
pr_info("module rc: loaded %zu bytes from %s\n", module_rc_len, MODULE_RC_PATH);
263+
pr_info("module rc: loaded %zu bytes from %s\n", module_rc_len, path);
247264
}
248265

249266
// https://cs.android.com/android/platform/superproject/main/+/main:system/core/init/parser.cpp;l=144;drc=61197364367c9e404c7da6900658f1b16c42d0da

userspace/ksud/src/defs.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@ mod android {
2424
pub const MODULE_UPDATE_DIR: &str = concatcp!(ADB_DIR, "modules_update/");
2525
pub const METAMODULE_DIR: &str = concatcp!(ADB_DIR, "metamodule/");
2626

27-
pub const PREINIT_DIR: &str = "/metadata/watchdog/ksu/";
28-
pub const MODULES_RC_PATH: &str = concatcp!(PREINIT_DIR, "modules.rc");
29-
pub const MODULES_RC_TMP_PATH: &str = concatcp!(PREINIT_DIR, ".modules.rc.tmp");
27+
// Prefer /metadata/watchdog/ when present, else /metadata
28+
pub const PREINIT_DIR_WATCHDOG: &str = "/metadata/watchdog/ksu/";
29+
pub const PREINIT_DIR_DEFAULT: &str = "/metadata/ksu/";
30+
pub const MODULES_RC_FILE: &str = "modules.rc";
31+
pub const MODULES_RC_TMP_FILE: &str = ".modules.rc.tmp";
3032

3133
pub const MODULE_WEB_DIR: &str = "webroot";
3234
pub const MODULE_ACTION_SH: &str = "action.sh";

userspace/ksud/src/installer.sh

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -327,12 +327,14 @@ boot_actions() { return; }
327327
# /metadata/watchdog/ksu/modules.rc so the kernel-side read hook can splice them
328328
# into /system/etc/init/hw/init.rc on the next boot.
329329
copy_preinit_files() {
330-
local PREINITDIR=/metadata/watchdog/ksu
330+
[ -d /metadata ] || return 0
331+
332+
# Prefer /metadata/watchdog/ when present, else /metadata.
333+
local PREINITDIR=/metadata/ksu
334+
[ -d /metadata/watchdog ] && PREINITDIR=/metadata/watchdog/ksu
331335
local OUT="$PREINITDIR/modules.rc"
332336
local TMP="$PREINITDIR/.modules.rc.tmp"
333337

334-
[ -d /metadata ] || return 0
335-
336338
mkdir -p "$PREINITDIR" 2>/dev/null
337339
: > "$TMP"
338340

userspace/ksud/src/module.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,15 @@ pub fn prune_modules() -> Result<()> {
358358

359359
const METADATA_FILE_CON: &str = "u:object_r:metadata_file:s0";
360360

361+
// Prefer /metadata/watchdog/ when present, else /metadata.
362+
fn preinit_ksu_dir() -> &'static str {
363+
if Path::new("/metadata/watchdog").is_dir() {
364+
defs::PREINIT_DIR_WATCHDOG
365+
} else {
366+
defs::PREINIT_DIR_DEFAULT
367+
}
368+
}
369+
361370
fn collect_module_rc(root: &Path, dir: &Path, mod_id: &str, out: &mut File) -> Result<()> {
362371
use std::io::Write;
363372
let Ok(entries) = std::fs::read_dir(dir) else {
@@ -389,17 +398,19 @@ fn collect_module_rc(root: &Path, dir: &Path, mod_id: &str, out: &mut File) -> R
389398
pub fn regenerate_preinit_rc() -> Result<()> {
390399
use std::collections::HashSet;
391400

392-
let preinit_dir = Path::new(defs::PREINIT_DIR);
393401
if !Path::new("/metadata").is_dir() {
394-
debug!("/metadata not present, skip preinit rc regen");
395402
return Ok(());
396403
}
397404

405+
let preinit_str = preinit_ksu_dir();
406+
let preinit_dir = Path::new(preinit_str);
398407
std::fs::create_dir_all(preinit_dir)
399408
.with_context(|| format!("Failed to create {}", preinit_dir.display()))?;
400409

401-
let tmp_path = Path::new(defs::MODULES_RC_TMP_PATH);
402-
let out_path = Path::new(defs::MODULES_RC_PATH);
410+
let tmp_path_buf = preinit_dir.join(defs::MODULES_RC_TMP_FILE);
411+
let out_path_buf = preinit_dir.join(defs::MODULES_RC_FILE);
412+
let tmp_path = tmp_path_buf.as_path();
413+
let out_path = out_path_buf.as_path();
403414

404415
{
405416
let mut tmp = File::create(tmp_path)
@@ -446,6 +457,14 @@ pub fn regenerate_preinit_rc() -> Result<()> {
446457
debug!("set context on {} failed: {e}", out_path.display());
447458
}
448459

460+
// Clear stale file at the other candidate path.
461+
let stale_dir = if preinit_str == defs::PREINIT_DIR_WATCHDOG {
462+
defs::PREINIT_DIR_DEFAULT
463+
} else {
464+
defs::PREINIT_DIR_WATCHDOG
465+
};
466+
std::fs::remove_file(Path::new(stale_dir).join(defs::MODULES_RC_FILE)).ok();
467+
449468
Ok(())
450469
}
451470

userspace/ksud/src/utils.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,8 @@ pub fn uninstall(magiskboot_path: Option<PathBuf>, package_name: &str) -> Result
227227
std::fs::remove_dir_all(defs::WORKING_DIR).ok();
228228
std::fs::remove_file(defs::DAEMON_PATH).ok();
229229
std::fs::remove_dir_all(defs::MODULE_DIR).ok();
230+
std::fs::remove_dir_all(defs::PREINIT_DIR_WATCHDOG).ok();
231+
std::fs::remove_dir_all(defs::PREINIT_DIR_DEFAULT).ok();
230232
println!("- Restore boot image..");
231233
boot_patch::restore(BootRestoreArgs {
232234
boot: None,

0 commit comments

Comments
 (0)