Magisk/scripts/boot_patch.sh
topjohnwu 16e4c67992 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
2020-11-02 23:20:38 -08:00

186 lines
4.7 KiB
Bash

#!/system/bin/sh
###########################################################################################
#
# Magisk Boot Image Patcher
# by topjohnwu
#
# Usage: boot_patch.sh <bootimage>
#
# The following flags can be set in environment variables:
# KEEPVERITY, KEEPFORCEENCRYPT, RECOVERYMODE
#
# This script should be placed in a directory with the following files:
#
# File name Type Description
#
# boot_patch.sh script A script to patch boot image for Magisk.
# (this file) The script will use binaries and files in its same directory
# to complete the patching process
# util_functions.sh script A script which hosts all functions required for this script
# to work properly
# magiskinit binary The binary to replace /init; magisk binary embedded
# magiskboot binary A tool to manipulate boot images
# chromeos folder This folder includes all the utilities and keys to sign
# (optional) chromeos boot images. Currently only used for Pixel C
#
###########################################################################################
############
# Functions
############
# Pure bash dirname implementation
getdir() {
case "$1" in
*/*) dir=${1%/*}; [ -z $dir ] && echo "/" || echo $dir ;;
*) echo "." ;;
esac
}
#################
# Initialization
#################
if [ -z $SOURCEDMODE ]; then
# Switch to the location of the script file
cd "`getdir "${BASH_SOURCE:-$0}"`"
# Load utility functions
. ./util_functions.sh
fi
BOOTIMAGE="$1"
[ -e "$BOOTIMAGE" ] || abort "$BOOTIMAGE does not exist!"
# Flags
[ -z $KEEPVERITY ] && KEEPVERITY=false
[ -z $KEEPFORCEENCRYPT ] && KEEPFORCEENCRYPT=false
[ -z $RECOVERYMODE ] && RECOVERYMODE=false
export KEEPVERITY
export KEEPFORCEENCRYPT
chmod -R 755 .
# Extract magisk if doesn't exist
[ -e magisk ] || ./magiskinit -x magisk magisk
#########
# Unpack
#########
CHROMEOS=false
ui_print "- Unpacking boot image"
./magiskboot unpack "$BOOTIMAGE"
case $? in
1 )
abort "! Unsupported/Unknown image format"
;;
2 )
ui_print "- ChromeOS boot image detected"
CHROMEOS=true
;;
esac
[ -f recovery_dtbo ] && RECOVERYMODE=true
###################
# Ramdisk Restores
###################
# Test patch status and do restore
ui_print "- Checking ramdisk status"
if [ -e ramdisk.cpio ]; then
./magiskboot cpio ramdisk.cpio test
STATUS=$?
else
# Stock A only system-as-root
STATUS=0
fi
case $((STATUS & 3)) in
0 ) # Stock boot
ui_print "- Stock boot image detected"
SHA1=`./magiskboot sha1 "$BOOTIMAGE" 2>/dev/null`
cat $BOOTIMAGE > stock_boot.img
cp -af ramdisk.cpio ramdisk.cpio.orig 2>/dev/null
;;
1 ) # Magisk patched
ui_print "- Magisk patched boot image detected"
# Find SHA1 of stock boot image
[ -z $SHA1 ] && SHA1=`./magiskboot cpio ramdisk.cpio sha1 2>/dev/null`
./magiskboot cpio ramdisk.cpio restore
cp -af ramdisk.cpio ramdisk.cpio.orig
;;
2 ) # Unsupported
ui_print "! Boot image patched by unsupported programs"
abort "! Please restore back to stock boot image"
;;
esac
##################
# Ramdisk Patches
##################
ui_print "- Patching ramdisk"
echo "KEEPVERITY=$KEEPVERITY" > config
echo "KEEPFORCEENCRYPT=$KEEPFORCEENCRYPT" >> config
echo "RECOVERYMODE=$RECOVERYMODE" >> config
[ ! -z $SHA1 ] && echo "SHA1=$SHA1" >> config
./magiskboot cpio ramdisk.cpio \
"add 750 init magiskinit" \
"patch" \
"backup ramdisk.cpio.orig" \
"mkdir 000 .backup" \
"add 000 .backup/.magisk config"
if [ $((STATUS & 4)) -ne 0 ]; then
ui_print "- Compressing ramdisk"
./magiskboot cpio ramdisk.cpio compress
fi
rm -f ramdisk.cpio.orig config
#################
# Binary Patches
#################
for dt in dtb kernel_dtb extra recovery_dtbo; do
[ -f $dt ] && ./magiskboot dtb $dt patch && ui_print "- Patch fstab in $dt"
done
if [ -f kernel ]; then
# Remove Samsung RKP
./magiskboot hexpatch kernel \
49010054011440B93FA00F71E9000054010840B93FA00F7189000054001840B91FA00F7188010054 \
A1020054011440B93FA00F7140020054010840B93FA00F71E0010054001840B91FA00F7181010054
# Remove Samsung defex
# Before: [mov w2, #-221] (-__NR_execve)
# After: [mov w2, #-32768]
./magiskboot hexpatch kernel 821B8012 E2FF8F12
# Force kernel to load rootfs
# skip_initramfs -> want_initramfs
./magiskboot hexpatch kernel \
736B69705F696E697472616D667300 \
77616E745F696E697472616D667300
fi
#################
# Repack & Flash
#################
ui_print "- Repacking boot image"
./magiskboot repack "$BOOTIMAGE" || abort "! Unable to repack boot image!"
# Sign chromeos boot
$CHROMEOS && sign_chromeos
# Copy existing rules for migration
$BOOTMODE && copy_sepolicy_rules
# Reset any error code
true