Add sepolicy.rule patching tests

This commit is contained in:
topjohnwu 2025-05-12 17:31:50 -07:00 committed by John Wu
parent 97901979dd
commit 4f4b1ff885
6 changed files with 31 additions and 21 deletions

View File

@ -7,6 +7,7 @@ import androidx.test.uiautomator.By
import androidx.test.uiautomator.Until import androidx.test.uiautomator.Until
import com.topjohnwu.magisk.core.model.module.LocalModule import com.topjohnwu.magisk.core.model.module.LocalModule
import com.topjohnwu.magisk.core.utils.RootUtils import com.topjohnwu.magisk.core.utils.RootUtils
import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import org.junit.After import org.junit.After
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
@ -96,6 +97,10 @@ class AdditionalTest : BaseTest {
"/system/app/EasterEgg should be empty", "/system/app/EasterEgg should be empty",
egg.isEmpty() egg.isEmpty()
) )
assertTrue(
"Module sepolicy.rule is not applied",
Shell.cmd("magiskpolicy --print-rules | grep -q magisk_test").exec().isSuccess
)
module!! module!!
assertTrue("test_01 should be zygisk unloaded", module.zygiskUnloaded) assertTrue("test_01 should be zygisk unloaded", module.zygiskUnloaded)
} }

View File

@ -28,6 +28,7 @@ import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import timber.log.Timber import timber.log.Timber
import java.io.File import java.io.File
import java.io.PrintStream
@Keep @Keep
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
@ -106,7 +107,15 @@ class Environment : BaseTest {
val module = LocalModule(path) val module = LocalModule(path)
assertTrue(error, module.zygiskFolder.mkdir()) assertTrue(error, module.zygiskFolder.mkdir())
assertTrue(error, Shell.cmd("set_default_perm $path").exec().isSuccess) // Add sepolicy patch
PrintStream(path.getChildFile("sepolicy.rule").newOutputStream()).use {
it.println("type magisk_test domain")
}
assertTrue(error, Shell.cmd(
"set_default_perm $path",
"copy_preinit_files"
).exec().isSuccess)
} }
private fun setupModule02(root: ExtendedFile) { private fun setupModule02(root: ExtendedFile) {

View File

@ -143,7 +143,7 @@ string resolve_preinit_dir(const char *base_dir) {
if (access((dir + "/unencrypted").data(), F_OK) == 0) { if (access((dir + "/unencrypted").data(), F_OK) == 0) {
dir += "/unencrypted/magisk"; dir += "/unencrypted/magisk";
} else if (access((dir + "/adb").data(), F_OK) == 0) { } else if (access((dir + "/adb").data(), F_OK) == 0) {
dir += "/adb/modules"; dir += "/adb";
} else if (access((dir + "/watchdog").data(), F_OK) == 0) { } else if (access((dir + "/watchdog").data(), F_OK) == 0) {
dir += "/watchdog/magisk"; dir += "/watchdog/magisk";
} else { } else {

View File

@ -5,7 +5,7 @@ use crate::ffi::{
exec_module_scripts, get_magisk_tmp, initialize_denylist, setup_magisk_env, exec_module_scripts, get_magisk_tmp, initialize_denylist, setup_magisk_env,
}; };
use crate::logging::{magisk_logging, setup_logfile, start_log_daemon}; use crate::logging::{magisk_logging, setup_logfile, start_log_daemon};
use crate::mount::{clean_mounts, setup_mounts}; use crate::mount::{clean_mounts, setup_module_mount, setup_preinit_dir};
use crate::package::ManagerInfo; use crate::package::ManagerInfo;
use crate::selinux::restore_tmpcon; use crate::selinux::restore_tmpcon;
use crate::su::SuInfo; use crate::su::SuInfo;
@ -144,7 +144,7 @@ impl MagiskD {
Ordering::Release, Ordering::Release,
); );
initialize_denylist(); initialize_denylist();
setup_mounts(); setup_module_mount();
let modules = self.handle_modules(); let modules = self.handle_modules();
self.module_list.set(modules).ok(); self.module_list.set(modules).ok();
clean_mounts(); clean_mounts();
@ -175,6 +175,7 @@ impl MagiskD {
secure_dir.mkdir(0o700).log_ok(); secure_dir.mkdir(0o700).log_ok();
} }
setup_preinit_dir();
self.ensure_manager(); self.ensure_manager();
self.zygisk_reset(true) self.zygisk_reset(true)
} }

View File

@ -15,16 +15,13 @@ use crate::consts::{MODULEMNT, MODULEROOT, PREINITDEV, PREINITMIRR, WORKERDIR};
use crate::ffi::{get_magisk_tmp, resolve_preinit_dir, switch_mnt_ns}; use crate::ffi::{get_magisk_tmp, resolve_preinit_dir, switch_mnt_ns};
use crate::get_prop; use crate::get_prop;
pub fn setup_mounts() { pub fn setup_preinit_dir() {
info!("* Setup internal mounts");
let magisk_tmp = get_magisk_tmp(); let magisk_tmp = get_magisk_tmp();
// Mount preinit directory // Mount preinit directory
let dev_path = cstr::buf::new::<64>() let dev_path = cstr::buf::new::<64>()
.join_path(magisk_tmp) .join_path(magisk_tmp)
.join_path(PREINITDEV); .join_path(PREINITDEV);
let mut linked = false;
if let Ok(attr) = dev_path.get_attr() { if let Ok(attr) = dev_path.get_attr() {
if attr.st.st_mode & libc::S_IFMT as c_uint == libc::S_IFBLK.as_() { if attr.st.st_mode & libc::S_IFMT as c_uint == libc::S_IFBLK.as_() {
// DO NOT mount the block device directly, as we do not know the flags and configs // DO NOT mount the block device directly, as we do not know the flags and configs
@ -53,23 +50,21 @@ pub fn setup_mounts() {
mnt_path.create_symlink_to(preinit_dir)?; mnt_path.create_symlink_to(preinit_dir)?;
}; };
if r.is_ok() { if r.is_ok() {
linked = true; info!("* Found preinit dir: {}", preinit_dir);
break; return;
} }
} }
} }
} }
} }
if !linked {
warn!("mount: preinit dir not found");
dev_path.remove().ok();
} else {
debug!("mount: preinit dir found");
}
warn!("mount: preinit dir not found");
}
pub fn setup_module_mount() {
// Bind remount module root to clear nosuid // Bind remount module root to clear nosuid
let module_mnt = cstr::buf::default() let module_mnt = cstr::buf::default()
.join_path(magisk_tmp) .join_path(get_magisk_tmp())
.join_path(MODULEMNT); .join_path(MODULEMNT);
let _: LoggedResult<()> = try { let _: LoggedResult<()> = try {
module_mnt.mkdir(0o755)?; module_mnt.mkdir(0o755)?;

View File

@ -123,8 +123,7 @@ void MagiskInit::mount_preinit_dir() noexcept {
// Since we are mounting the block device directly, make sure to ONLY mount the partitions // Since we are mounting the block device directly, make sure to ONLY mount the partitions
// as read-only, or else the kernel might crash due to crappy drivers. // as read-only, or else the kernel might crash due to crappy drivers.
// After the device boots up, magiskd will properly bind mount the correct partition // After the device boots up, magiskd will properly symlink the correct path at PREINITMIRR as writable.
// on to PREINITMIRR as writable. For more details, check bootstages.cpp
if (mounted || mount(PREINITDEV, MIRRDIR, "ext4", MS_RDONLY, nullptr) == 0 || if (mounted || mount(PREINITDEV, MIRRDIR, "ext4", MS_RDONLY, nullptr) == 0 ||
mount(PREINITDEV, MIRRDIR, "f2fs", MS_RDONLY, nullptr) == 0) { mount(PREINITDEV, MIRRDIR, "f2fs", MS_RDONLY, nullptr) == 0) {
string preinit_dir = resolve_preinit_dir(MIRRDIR); string preinit_dir = resolve_preinit_dir(MIRRDIR);
@ -138,8 +137,9 @@ void MagiskInit::mount_preinit_dir() noexcept {
} }
xumount2(MIRRDIR, MNT_DETACH); xumount2(MIRRDIR, MNT_DETACH);
} else { } else {
PLOGE("Failed to mount preinit %s\n", preinit_dev.c_str()); PLOGE("Mount preinit %s", preinit_dev.c_str());
unlink(PREINITDEV); // Do NOT delete the block device. Even though we cannot mount it here,
// it might get formatted later in the boot process.
} }
} }