Significantly broaden sepolicy.rule compatibility

Previously, Magisk uses persist or cache for storing modules' custom
sepolicy rules. In this commit, we significantly broaden its
compatibility and also prevent mounting errors.

The persist partition is non-standard and also critical for Snapdragon
devices, so we prefer not to use it by default.

We will go through the following logic to find the best suitable
non-volatile, writable location to store and load sepolicy.rule files:

Unencrypted data -> FBE data unencrypted dir -> cache -> metadata -> persist

This should cover almost all possible cases: very old devices have
cache partitions; newer devices will use FBE; latest devices will use
metadata FBE (which guarantees a metadata parition); and finally,
all Snapdragon devices have the persist partition (as a last resort).

Fix #3179
This commit is contained in:
topjohnwu
2020-11-02 23:20:38 -08:00
parent cf47214ee4
commit 16e4c67992
9 changed files with 237 additions and 105 deletions

View File

@ -178,5 +178,8 @@ ui_print "- Repacking boot image"
# Sign chromeos boot
$CHROMEOS && sign_chromeos
# Copy existing rules for migration
$BOOTMODE && copy_sepolicy_rules
# Reset any error code
true

View File

@ -15,7 +15,6 @@ TMPDIR=/dev/tmp
INSTALLER=$TMPDIR/install
CHROMEDIR=$INSTALLER/chromeos
PERSISTDIR=/sbin/.magisk/mirror/persist
# Default permissions
umask 022
@ -36,7 +35,12 @@ setup_flashable
print_title "Magisk Uninstaller"
is_mounted /data || mount /data || abort "! Unable to mount /data, please uninstall with Magisk Manager"
is_mounted /cache || mount /cache 2>/dev/null
if ! $BOOTMODE; then
# Mounting stuffs in recovery (best effort)
mount_name metadata /metadata
mount_name "cache cac" /cache
mount_name persist /persist
fi
mount_partitions
api_level_arch_detect
@ -141,7 +145,8 @@ ui_print "- Removing Magisk files"
rm -rf \
/cache/*magisk* /cache/unblock /data/*magisk* /data/cache/*magisk* /data/property/*magisk* \
/data/Magisk.apk /data/busybox /data/custom_ramdisk_patch.sh /data/adb/*magisk* \
/data/adb/post-fs-data.d /data/adb/service.d /data/adb/modules* $PERSISTDIR/magisk 2>/dev/null
/data/adb/post-fs-data.d /data/adb/service.d /data/adb/modules* \
/data/unencrypted/magisk /metadata/magisk /persist/magisk /mnt/vendor/persist/magisk
if [ -f /system/addon.d/99-magisk.sh ]; then
blockdev --setrw /dev/block/mapper/system$SLOT 2>/dev/null
@ -158,7 +163,7 @@ if $BOOTMODE; then
ui_print "********************************************"
(sleep 8; /system/bin/reboot)&
else
rm -rf /data/user*/*/*magisk* /data/app/*magisk*
rm -rf /data/data/*magisk* /data/user*/*/*magisk* /data/app/*magisk* /data/app/*/*magisk*
recovery_cleanup
ui_print "- Done"
fi

View File

@ -152,6 +152,7 @@ recovery_cleanup() {
fi
umount -l /vendor
umount -l /persist
umount -l /metadata
for DIR in /apex /system /system_root; do
if [ -L "${DIR}_link" ]; then
rmdir $DIR
@ -217,13 +218,13 @@ mount_name() {
local FLAG=$3
setup_mntpoint $POINT
is_mounted $POINT && return
ui_print "- Mounting $POINT"
# First try mounting with fstab
mount $FLAG $POINT 2>/dev/null
if ! is_mounted $POINT; then
local BLOCK=`find_block $PART`
mount $FLAG $BLOCK $POINT
local BLOCK=$(find_block $PART)
mount $FLAG $BLOCK $POINT || return
fi
ui_print "- Mounting $POINT"
}
# mount_ro_ensure <partname(s)> <mountpoint>
@ -266,18 +267,6 @@ mount_partitions() {
# Allow /system/bin commands (dalvikvm) on Android 10+ in recovery
$BOOTMODE || mount_apex
# Mount persist partition in recovery
if ! $BOOTMODE && [ ! -z $PERSISTDIR ]; then
# Try to mount persist
PERSISTDIR=/persist
mount_name persist /persist
if ! is_mounted /persist; then
# Fallback to cache
mount_name "cache cac" /cache
is_mounted /cache && PERSISTDIR=/cache || PERSISTDIR=
fi
fi
}
# loop_setup <ext4_img>, sets LOOPDEV
@ -575,6 +564,41 @@ run_migrations() {
done
}
copy_sepolicy_rules() {
# Remove all existing rule folders
rm -rf /data/unencrypted/magisk /metadata/magisk /persist/magisk /mnt/vendor/persist/magisk
# Find current active RULESDIR
local RULESDIR
local active_dir=$(magisk --path)/.magisk/mirror/sepolicy.rules
if [ -e $active_dir ]; then
RULESDIR=$(readlink -f $active_dir)
elif [ -d /data/unencrypted ] && ! grep ' /data ' /proc/mounts | grep -q 'dm-'; then
RULESDIR=/data/unencrypted/magisk
elif grep -q ' /cache ' /proc/mounts; then
RULESDIR=/cache/magisk
elif grep -q ' /metadata ' /proc/mounts; then
RULESDIR=/metadata/magisk
elif grep -q ' /persist ' /proc/mounts; then
RULESDIR=/persist/magisk
elif grep -q ' /mnt/vendor/persist ' /proc/mounts; then
RULESDIR=/mnt/vendor/persist/magisk
else
return
fi
# Copy all enabled sepolicy.rule
for r in /data/adb/modules*/*/sepolicy.rule; do
[ -f "$r" ] || continue
local MODDIR=${r%/*}
[ -f $MODDIR/disable ] && continue
[ -f $MODDIR/remove ] && continue
local MODNAME=${MODDIR##*/}
mkdir -p $RULESDIR/$MODNAME
cp -f $r $RULESDIR/$MODNAME/sepolicy.rule
done
}
#################
# Module Related
#################
@ -620,9 +644,6 @@ is_legacy_script() {
# Require OUTFD, ZIPFILE to be set
install_module() {
local PERSISTDIR
command -v magisk >/dev/null && PERSISTDIR=$(magisk --path)/mirror/persist
rm -rf $TMPDIR
mkdir -p $TMPDIR
@ -646,7 +667,7 @@ install_module() {
MODPATH=$MODULEROOT/$MODID
# Create mod paths
rm -rf $MODPATH 2>/dev/null
rm -rf $MODPATH
mkdir -p $MODPATH
if is_legacy_script; then
@ -699,19 +720,15 @@ install_module() {
fi
# Copy over custom sepolicy rules
if [ -f $MODPATH/sepolicy.rule -a -e "$PERSISTDIR" ]; then
ui_print "- Installing custom sepolicy patch"
# Remove old recovery logs (which may be filling partition) to make room
rm -f $PERSISTDIR/cache/recovery/*
PERSISTMOD=$PERSISTDIR/magisk/$MODID
mkdir -p $PERSISTMOD
cp -af $MODPATH/sepolicy.rule $PERSISTMOD/sepolicy.rule || abort "! Insufficient partition size"
if [ -f $MODPATH/sepolicy.rule ]; then
ui_print "- Installing custom sepolicy rules"
copy_sepolicy_rules
fi
# Remove stuffs that don't belong to modules
rm -rf \
$MODPATH/system/placeholder $MODPATH/customize.sh \
$MODPATH/README.md $MODPATH/.git* 2>/dev/null
$MODPATH/README.md $MODPATH/.git*
cd /
$BOOTMODE || recovery_cleanup