mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-12-05 20:40:19 -08:00
Compare commits
3 Commits
363566d0d5
...
ccb264f33a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ccb264f33a | ||
|
|
84f7d75d30 | ||
|
|
9a776c22d9 |
@@ -30,4 +30,4 @@ android.nonFinalResIds=false
|
|||||||
|
|
||||||
# Magisk
|
# Magisk
|
||||||
magisk.stubVersion=40
|
magisk.stubVersion=40
|
||||||
magisk.versionCode=30500
|
magisk.versionCode=30600
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
# Magisk Changelog
|
# Magisk Changelog
|
||||||
|
|
||||||
|
### v30.6 (2025.12.1)
|
||||||
|
|
||||||
|
- [MagiskInit] Revert a change that could result in bootloops
|
||||||
|
|
||||||
### v30.5 (2025.12.1)
|
### v30.5 (2025.12.1)
|
||||||
|
|
||||||
- [General] Improve commandline argument parsing logic
|
- [General] Improve commandline argument parsing logic
|
||||||
|
|||||||
@@ -221,10 +221,7 @@ pub fn revert_unmount(pid: i32) {
|
|||||||
|
|
||||||
// Unmount Magisk tmpfs and mounts from module files
|
// Unmount Magisk tmpfs and mounts from module files
|
||||||
for info in parse_mount_info("self") {
|
for info in parse_mount_info("self") {
|
||||||
if info.source == "magisk"
|
if info.source == "magisk" || info.root.starts_with("/adb/modules") {
|
||||||
|| info.root.starts_with("/adb/modules")
|
|
||||||
|| (info.fs_type == "rootfs" && info.root.starts_with("/magisk"))
|
|
||||||
{
|
|
||||||
targets.push(info.target);
|
targets.push(info.target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
use crate::ffi::{BootConfig, MagiskInit, backup_init, magisk_proxy_main};
|
use crate::ffi::{BootConfig, MagiskInit, backup_init, magisk_proxy_main};
|
||||||
use crate::logging::setup_klog;
|
use crate::logging::setup_klog;
|
||||||
use crate::mount::{is_rootfs, occupy, unoccupy};
|
use crate::mount::is_rootfs;
|
||||||
use crate::twostage::hexpatch_init_for_second_stage;
|
use crate::twostage::hexpatch_init_for_second_stage;
|
||||||
use base::libc::{basename, getpid, mount, umask};
|
use base::libc::{basename, getpid, mount, umask};
|
||||||
use base::nix::mount::MsFlags;
|
use base::{LibcReturn, LoggedResult, ResultExt, cstr, info, raw_cstr};
|
||||||
use base::{LibcReturn, LoggedResult, ResultExt, Utf8CStr, cstr, info, nix, raw_cstr};
|
|
||||||
use std::ffi::{CStr, c_char};
|
use std::ffi::{CStr, c_char};
|
||||||
use std::ptr::null;
|
use std::ptr::null;
|
||||||
|
|
||||||
@@ -32,7 +31,7 @@ impl MagiskInit {
|
|||||||
|
|
||||||
fn first_stage(&self) {
|
fn first_stage(&self) {
|
||||||
info!("First Stage Init");
|
info!("First Stage Init");
|
||||||
let rootfs_magisktmp = self.prepare_data(true);
|
self.prepare_data();
|
||||||
|
|
||||||
if !cstr!("/sdcard").exists() && !cstr!("/first_stage_ramdisk/sdcard").exists() {
|
if !cstr!("/sdcard").exists() && !cstr!("/first_stage_ramdisk/sdcard").exists() {
|
||||||
self.hijack_init_with_switch_root();
|
self.hijack_init_with_switch_root();
|
||||||
@@ -42,28 +41,11 @@ impl MagiskInit {
|
|||||||
// Fallback to hexpatch if /sdcard exists
|
// Fallback to hexpatch if /sdcard exists
|
||||||
hexpatch_init_for_second_stage(true);
|
hexpatch_init_for_second_stage(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if rootfs_magisktmp {
|
|
||||||
info!("Occupy /data");
|
|
||||||
occupy(cstr!("/data"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn second_stage(&mut self) {
|
fn second_stage(&mut self) {
|
||||||
info!("Second Stage Init");
|
info!("Second Stage Init");
|
||||||
|
|
||||||
if unoccupy(cstr!("/data")) {
|
|
||||||
nix::mount::mount(
|
|
||||||
None::<&Utf8CStr>,
|
|
||||||
cstr!("/data"),
|
|
||||||
None::<&Utf8CStr>,
|
|
||||||
MsFlags::MS_REMOUNT,
|
|
||||||
Some(cstr!("size=100%")),
|
|
||||||
)
|
|
||||||
.check_os_err("mount", Some("/data"), Some("tmpfs"))
|
|
||||||
.log_ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
cstr!("/init").unmount().ok();
|
cstr!("/init").unmount().ok();
|
||||||
cstr!("/system/bin/init").unmount().ok(); // just in case
|
cstr!("/system/bin/init").unmount().ok(); // just in case
|
||||||
cstr!("/data/init").remove().ok();
|
cstr!("/data/init").remove().ok();
|
||||||
@@ -89,7 +71,7 @@ impl MagiskInit {
|
|||||||
|
|
||||||
fn legacy_system_as_root(&mut self) {
|
fn legacy_system_as_root(&mut self) {
|
||||||
info!("Legacy SAR Init");
|
info!("Legacy SAR Init");
|
||||||
self.prepare_data(false);
|
self.prepare_data();
|
||||||
let is_two_stage = self.mount_system_root();
|
let is_two_stage = self.mount_system_root();
|
||||||
if is_two_stage {
|
if is_two_stage {
|
||||||
hexpatch_init_for_second_stage(false);
|
hexpatch_init_for_second_stage(false);
|
||||||
@@ -100,7 +82,7 @@ impl MagiskInit {
|
|||||||
|
|
||||||
fn rootfs(&mut self) {
|
fn rootfs(&mut self) {
|
||||||
info!("RootFS Init");
|
info!("RootFS Init");
|
||||||
self.prepare_data(false);
|
self.prepare_data();
|
||||||
self.restore_ramdisk_init();
|
self.restore_ramdisk_init();
|
||||||
self.patch_rw_root();
|
self.patch_rw_root();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
use crate::ffi::MagiskInit;
|
use crate::ffi::MagiskInit;
|
||||||
use base::WalkResult::{Continue, Skip};
|
|
||||||
use base::nix::mount::{MntFlags, mount, umount2};
|
|
||||||
use base::{
|
use base::{
|
||||||
Directory, FsPathBuilder, LibcReturn, LoggedResult, ResultExt, Utf8CStr, cstr, debug, libc,
|
Directory, FsPathBuilder, LibcReturn, LoggedResult, ResultExt, Utf8CStr, cstr, debug, libc,
|
||||||
nix, parse_mount_info, raw_cstr,
|
nix, parse_mount_info, raw_cstr,
|
||||||
@@ -64,54 +62,6 @@ pub(crate) fn is_device_mounted(dev: u64, target: Pin<&mut CxxString>) -> bool {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn occupy(path: &Utf8CStr) {
|
|
||||||
Directory::open(path)
|
|
||||||
.map(|mut dir| {
|
|
||||||
dir.pre_order_walk(|entry| {
|
|
||||||
let mut path = cstr::buf::default();
|
|
||||||
entry.resolve_path(&mut path)?;
|
|
||||||
let path = path.as_utf8_cstr();
|
|
||||||
mount(
|
|
||||||
Some(path),
|
|
||||||
path,
|
|
||||||
None::<&Utf8CStr>,
|
|
||||||
MsFlags::MS_BIND | MsFlags::MS_RDONLY,
|
|
||||||
None::<&Utf8CStr>,
|
|
||||||
)
|
|
||||||
.check_os_err("occupy", Some(path), None)?;
|
|
||||||
Ok(Continue)
|
|
||||||
})
|
|
||||||
.log_ok();
|
|
||||||
})
|
|
||||||
.log_ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn unoccupy(path: &Utf8CStr) -> bool {
|
|
||||||
let mut ok = false;
|
|
||||||
Directory::open(path)
|
|
||||||
.map(|mut dir| {
|
|
||||||
ok = dir
|
|
||||||
.pre_order_walk(|entry| {
|
|
||||||
let mut path = cstr::buf::default();
|
|
||||||
entry.resolve_path(&mut path)?;
|
|
||||||
let path = path.as_utf8_cstr();
|
|
||||||
umount2(path, MntFlags::MNT_DETACH).check_os_err(
|
|
||||||
"unoccupy",
|
|
||||||
Some(path),
|
|
||||||
None,
|
|
||||||
)?;
|
|
||||||
if entry.is_dir() {
|
|
||||||
Ok(Skip)
|
|
||||||
} else {
|
|
||||||
Ok(Continue)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.is_ok();
|
|
||||||
})
|
|
||||||
.log_ok();
|
|
||||||
ok
|
|
||||||
}
|
|
||||||
|
|
||||||
const RAMFS_MAGIC: u32 = 0x858458f6;
|
const RAMFS_MAGIC: u32 = 0x858458f6;
|
||||||
|
|
||||||
pub(crate) fn is_rootfs() -> bool {
|
pub(crate) fn is_rootfs() -> bool {
|
||||||
@@ -123,44 +73,22 @@ pub(crate) fn is_rootfs() -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MagiskInit {
|
impl MagiskInit {
|
||||||
pub(crate) fn prepare_data(&self, use_rootfs: bool) -> bool {
|
pub(crate) fn prepare_data(&self) {
|
||||||
debug!("Setup data tmp");
|
debug!("Setup data tmp");
|
||||||
cstr!("/data").mkdir(0o755).log_ok();
|
cstr!("/data").mkdir(0o755).log_ok();
|
||||||
|
nix::mount::mount(
|
||||||
|
Some(cstr!("magisk")),
|
||||||
|
cstr!("/data"),
|
||||||
|
Some(cstr!("tmpfs")),
|
||||||
|
MsFlags::empty(),
|
||||||
|
Some(cstr!("mode=755")),
|
||||||
|
)
|
||||||
|
.check_os_err("mount", Some("/data"), Some("tmpfs"))
|
||||||
|
.log_ok();
|
||||||
|
|
||||||
let mut rootfs_magisktmp = false;
|
cstr!("/init").copy_to(cstr!("/data/magiskinit")).ok();
|
||||||
|
cstr!("/.backup").copy_to(cstr!("/data/.backup")).ok();
|
||||||
if use_rootfs {
|
cstr!("/overlay.d").copy_to(cstr!("/data/overlay.d")).ok();
|
||||||
cstr!("/magisk").mkdir(0o755).log_ok();
|
|
||||||
rootfs_magisktmp = cstr!("/magisk")
|
|
||||||
.bind_mount_to(cstr!("/data"), false)
|
|
||||||
.is_ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
if rootfs_magisktmp {
|
|
||||||
cstr!("/init")
|
|
||||||
.rename_to(cstr!("/magisk/magiskinit"))
|
|
||||||
.log_ok();
|
|
||||||
cstr!("/.backup").copy_to(cstr!("/magisk/.backup")).ok();
|
|
||||||
cstr!("/overlay.d")
|
|
||||||
.rename_to(cstr!("/magisk/overlay.d"))
|
|
||||||
.ok();
|
|
||||||
} else {
|
|
||||||
nix::mount::mount(
|
|
||||||
Some(cstr!("magisk")),
|
|
||||||
cstr!("/data"),
|
|
||||||
Some(cstr!("tmpfs")),
|
|
||||||
MsFlags::empty(),
|
|
||||||
Some(cstr!("mode=755")),
|
|
||||||
)
|
|
||||||
.check_os_err("mount", Some("/data"), Some("tmpfs"))
|
|
||||||
.log_ok();
|
|
||||||
|
|
||||||
cstr!("/init").copy_to(cstr!("/data/magiskinit")).ok();
|
|
||||||
cstr!("/.backup").copy_to(cstr!("/data/.backup")).ok();
|
|
||||||
cstr!("/overlay.d").copy_to(cstr!("/data/overlay.d")).ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
rootfs_magisktmp
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn exec_init(&mut self) {
|
pub(crate) fn exec_init(&mut self) {
|
||||||
|
|||||||
@@ -84,14 +84,20 @@ impl MagiskInit {
|
|||||||
.log_ok();
|
.log_ok();
|
||||||
debug!("Symlink /storage/self/primary -> /system/system/bin/init");
|
debug!("Symlink /storage/self/primary -> /system/system/bin/init");
|
||||||
}
|
}
|
||||||
|
cstr!("/init").rename_to(cstr!("/sdcard")).log_ok();
|
||||||
|
|
||||||
// Binding mounting from rootfs is not supported before Linux 3.12
|
// First try to mount magiskinit from rootfs to workaround Samsung RKP
|
||||||
cstr!("/sdcard")
|
if cstr!("/sdcard")
|
||||||
.create(OFlag::O_RDONLY | OFlag::O_CLOEXEC, 0)
|
|
||||||
.log_ok();
|
|
||||||
cstr!("/data/magiskinit")
|
|
||||||
.bind_mount_to(cstr!("/sdcard"), false)
|
.bind_mount_to(cstr!("/sdcard"), false)
|
||||||
.log_ok();
|
.is_ok()
|
||||||
debug!("Bind mount /data/magiskinit -> /sdcard");
|
{
|
||||||
|
debug!("Bind mount /sdcard -> /sdcard");
|
||||||
|
} else {
|
||||||
|
// Binding mounting from rootfs is not supported before Linux 3.12
|
||||||
|
cstr!("/data/magiskinit")
|
||||||
|
.bind_mount_to(cstr!("/sdcard"), false)
|
||||||
|
.log_ok();
|
||||||
|
debug!("Bind mount /data/magiskinit -> /sdcard");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ impl SePolicy {
|
|||||||
allow(["kernel"], ["rootfs", "tmpfs"], ["chr_file"], ["write"]);
|
allow(["kernel"], ["rootfs", "tmpfs"], ["chr_file"], ["write"]);
|
||||||
|
|
||||||
// Allow magiskinit daemon to handle mock selinuxfs
|
// Allow magiskinit daemon to handle mock selinuxfs
|
||||||
allow(["kernel"], ["rootfs", "tmpfs"], ["fifo_file"], ["open", "read", "write"]);
|
allow(["kernel"], ["tmpfs"], ["fifo_file"], ["open", "read", "write"]);
|
||||||
|
|
||||||
// For relabelling files
|
// For relabelling files
|
||||||
allow(["rootfs"], ["labeledfs", "tmpfs"], ["filesystem"], ["associate"]);
|
allow(["rootfs"], ["labeledfs", "tmpfs"], ["filesystem"], ["associate"]);
|
||||||
|
|||||||
@@ -36,25 +36,6 @@ disable_version_config() {
|
|||||||
sed -i "s:^version=:# version=:g" $CONFIG
|
sed -i "s:^version=:# version=:g" $CONFIG
|
||||||
}
|
}
|
||||||
|
|
||||||
bump_canary_version() {
|
|
||||||
# Update version code
|
|
||||||
local code=$(grep_prop magisk.versionCode $GCONFIG)
|
|
||||||
code=$((code + 1))
|
|
||||||
local tag="canary-$code"
|
|
||||||
sed -i "s:versionCode=.*:versionCode=${code}:g" $GCONFIG
|
|
||||||
|
|
||||||
# Commit version code changes
|
|
||||||
git add -u .
|
|
||||||
git status
|
|
||||||
git commit -m "Release new canary build" -m "[skip ci]"
|
|
||||||
git tag $tag
|
|
||||||
|
|
||||||
# Update version name
|
|
||||||
local ver=$(git rev-parse --short=8 HEAD)
|
|
||||||
sed -i "s:version=.*:version=${ver}:g" $CONFIG
|
|
||||||
sed -i "1s:.*:## Magisk (${ver}) (${code}):" $NOTES
|
|
||||||
}
|
|
||||||
|
|
||||||
# $1 = ver
|
# $1 = ver
|
||||||
set_version() {
|
set_version() {
|
||||||
local ver=$1
|
local ver=$1
|
||||||
@@ -69,89 +50,45 @@ set_version() {
|
|||||||
git add -u .
|
git add -u .
|
||||||
git status
|
git status
|
||||||
git commit -m "Release Magisk v$ver" -m "[skip ci]"
|
git commit -m "Release Magisk v$ver" -m "[skip ci]"
|
||||||
git tag $tag
|
|
||||||
}
|
}
|
||||||
|
|
||||||
build_apk() {
|
# $1 = ver
|
||||||
|
build() {
|
||||||
|
[ -z $1 ] && exit 1
|
||||||
|
local ver=$1
|
||||||
|
git pull
|
||||||
|
set_version $ver
|
||||||
$BUILDCMD clean
|
$BUILDCMD clean
|
||||||
$BUILDCMD all
|
$BUILDCMD all
|
||||||
$BUILDCMD -r all
|
$BUILDCMD -r all
|
||||||
}
|
}
|
||||||
|
|
||||||
build_canary() {
|
|
||||||
bump_canary_version
|
|
||||||
build_apk
|
|
||||||
}
|
|
||||||
|
|
||||||
# $1 = ver
|
|
||||||
build_public() {
|
|
||||||
[ -z $1 ] && exit 1
|
|
||||||
local ver=$1
|
|
||||||
set_version $ver
|
|
||||||
build_apk
|
|
||||||
}
|
|
||||||
|
|
||||||
upload() {
|
upload() {
|
||||||
# Verify pattern
|
|
||||||
[[ "$1" =~ canary|beta|stable ]]
|
|
||||||
local type=$1
|
|
||||||
|
|
||||||
gh auth status
|
gh auth status
|
||||||
|
|
||||||
local latest_tag=$(git describe --abbrev=0 --tags)
|
|
||||||
local ver=$(grep_prop version $CONFIG)
|
|
||||||
local code=$(grep_prop magisk.versionCode $GCONFIG)
|
local code=$(grep_prop magisk.versionCode $GCONFIG)
|
||||||
local out=$(grep_prop outdir $CONFIG)
|
local ver=$(echo - | awk "{ print $code / 1000 }")
|
||||||
local tag title
|
local tag="v$ver"
|
||||||
|
local title="Magisk v$ver"
|
||||||
|
|
||||||
|
local out=$(grep_prop outdir $CONFIG)
|
||||||
if [ -z $out ]; then
|
if [ -z $out ]; then
|
||||||
out=out
|
out=out
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
git tag $tag
|
||||||
git push origin master
|
git push origin master
|
||||||
git push --tags
|
git push --tags
|
||||||
|
|
||||||
# Prepare release notes
|
# Prepare release notes
|
||||||
tail -n +3 $NOTES > release.md
|
tail -n +3 $NOTES > release.md
|
||||||
|
|
||||||
case $type in
|
# Publish release
|
||||||
canary )
|
local release_apk="Magisk-v${ver}.apk"
|
||||||
tag="canary-$code"
|
cp $out/app-release.apk $release_apk
|
||||||
title="Magisk ($ver) ($code)"
|
gh release create --verify-tag $tag -p -t "$title" -F release.md $release_apk $out/app-debug.apk $NOTES
|
||||||
|
|
||||||
# Assert tag format
|
rm -f $release_apk release.md
|
||||||
[ $latest_tag = $tag ]
|
|
||||||
|
|
||||||
# Publish release
|
|
||||||
gh release create --verify-tag $tag -p -t "$title" -F release.md $out/app-release.apk $out/app-debug.apk $NOTES
|
|
||||||
;;
|
|
||||||
beta|stable )
|
|
||||||
tag="v$ver"
|
|
||||||
title="Magisk v$ver"
|
|
||||||
|
|
||||||
# Assert tag format
|
|
||||||
[ $latest_tag = $tag ]
|
|
||||||
|
|
||||||
# Publish release
|
|
||||||
local release_apk="Magisk-v${ver}.apk"
|
|
||||||
cp $out/app-release.apk $release_apk
|
|
||||||
gh release create --verify-tag $tag -p -t "$title" -F release.md $release_apk $out/app-debug.apk $NOTES
|
|
||||||
rm -f $release_apk
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# If publishing stable, make it not prerelease and explicitly latest
|
|
||||||
if [ $type = "stable" ]; then
|
|
||||||
gh release edit $tag --prerelease=false --latest
|
|
||||||
fi
|
|
||||||
|
|
||||||
rm -f release.md
|
|
||||||
}
|
|
||||||
|
|
||||||
revert() {
|
|
||||||
local latest_tag=$(git describe --abbrev=0 --tags)
|
|
||||||
git tag -d $latest_tag
|
|
||||||
git reset --hard HEAD~
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Use GNU sed on macOS
|
# Use GNU sed on macOS
|
||||||
@@ -160,14 +97,10 @@ if command -v gsed >/dev/null; then
|
|||||||
export -f sed
|
export -f sed
|
||||||
fi
|
fi
|
||||||
|
|
||||||
git pull
|
|
||||||
|
|
||||||
trap disable_version_config EXIT
|
trap disable_version_config EXIT
|
||||||
ensure_config
|
ensure_config
|
||||||
case $1 in
|
case $1 in
|
||||||
canary ) build_canary ;;
|
build ) build $2 ;;
|
||||||
public ) build_public $2 ;;
|
upload ) upload ;;
|
||||||
upload ) upload $2 ;;
|
|
||||||
revert ) revert ;;
|
|
||||||
* ) exit 1 ;;
|
* ) exit 1 ;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
Reference in New Issue
Block a user