#!/sbin/sh # # SuperSU installer ZIP # Copyright (c) 2012-2017 - Chainfire, CCMT # # ----- GENERIC INFO ------ # # The following su binary versions are included in the full package. Each # should be installed only if the system has the same or newer API level # as listed. The script may fall back to a different binary on older API # levels. supolicy are all ndk/pie/19+ for 32 bit, ndk/pie/20+ for 64 bit. # # binary ARCH/path build type API # # arm-v5te arm ndk non-pie 7+ # x86 x86 ndk non-pie 7+ # # x86 x86 ndk pie 17+ (su.pie, naming exception) # arm-v7a armv7 ndk pie 17+ # mips mips ndk pie 17+ # # arm64-v8a arm64 ndk pie 20+ # mips64 mips64 ndk pie 20+ # x86_64 x64 ndk pie 20+ # # Non-static binaries are supported to be PIE (Position Independent # Executable) from API level 16, and required from API level 20 (which will # refuse to execute non-static non-PIE). # # The script performs several actions in various ways, sometimes # multiple times, due to different recoveries and firmwares behaving # differently, and it thus being required for the correct result. # # Overridable variables (shell): # BIN - Location of architecture specific files (native folder) # BINTOOLS - Location of architecture specific files (native, oldest 32-bit) # COM - Location of common files (APK folder) # LESSLOGGING - Reduce ui_print logging (true/false) # NOOVERRIDE - Do not read variables from /system/.supersu or # /data/.supersu # # Overridable variables (shell, /system/.supersu, /cache/.supersu, # /data/.supersu): # SYSTEMLESS - Do a system-less install? (true/false, 6.0+ only) # PATCHBOOTIMAGE - Automatically patch boot image? (true/false, # SYSTEMLESS only) # SIGNBOOTIMAGE - (Force) Sign boot image for Android Verified Boot (v1) # (true/false, PATCHBOOTIMAGE only) # BOOTIMAGE - Boot image location (PATCHBOOTIMAGE only) # STOCKBOOTIMAGE - Stock boot image location (PATCHBOOTIMAGE only) # BINDSYSTEMXBIN - Poor man's overlay on /system/xbin (true/false, # SYSTEMLESS only) # PERMISSIVE - Set sepolicy to fake-permissive (true/false, PATCHBOOTIMAGE # only) # KEEPVERITY - Do not remove dm-verity (true/false, PATCHBOOTIMAGE only) # KEEPFORCEENCRYPT - Do not replace forceencrypt with encryptable (true/ # false, PATCHBOOTIMAGE only) # REMOVEENCRYPTABLE - Remove the encryptable flag, needed on newer # Samsung devices to disable forced encryption. # Automatically used on Samsung 7.0+ if unencrypted # /data detected (true/false, PATCHBOOTIMAGE only). # FRP - Place files in boot image that allow root to survive a factory # reset (true/false, PATCHBOOTIMAGE only). Reverts to su binaries # from the time the ZIP was originally flashed, updates are lost. # BINDSBIN - Place files directly in /data rather than in /data/su.img, # and create a poor man's overlay on /sbin (true/false, # PATCHBOOTIMAGE only) # Shell overrides all, /data/.supersu overrides /cache/.supersu overrides # /system/.supersu # # Note that if SELinux is set to enforcing, the daemonsu binary expects # to be run at startup (usually from install-recovery.sh, 99SuperSUDaemon, # app_process, or init.supersu.rc) from u:r:supersu:s0 (7.0+), u:r:init:s0 or # u:r:kernel:s0 contexts. Depending on the current policies, it can also # deal with u:r:init_shell:s0 and u:r:toolbox:s0 contexts. Any other context # will lead to issues eventually. # # ----- "SYSTEM" INSTALL ----- # # "System" install puts all the files needed in /system and does not need # any boot image modifications. Default install method pre-Android-6.0 # (excluding Samsung-5.1). # # Even on Android-6.0+, the script attempts to detect if the current # firmware is compatible with a system-only installation (see the # "detect_systemless_required" function), and will prefer that # (unless the SYSTEMLESS variable is set) if so. This will catch the # case of several custom ROMs that users like to use custom boot images # with - SuperSU will not need to patch these. It can also catch some # locked bootloader cases that do allow security policy updates. # # To install SuperSU properly, aside from cleaning old versions and # other superuser-type apps from the system, the following files need to # be installed: # # API source target chmod chcon required # # 7-19 common/Superuser.apk /system/app/Superuser.apk 0644 u:object_r:system_file:s0 gui # 20+ common/Superuser.apk /system/app/SuperSU/SuperSU.apk 0644 u:object_r:system_file:s0 gui # # 17+ common/install-recovery.sh /system/etc/install-recovery.sh 0755 *1 required # 17+ /system/bin/install-recovery.sh (symlink to /system/etc/...) required # *1: same as /system/bin/toolbox: u:object_r:system_file:s0 if API < 20, u:object_r:toolbox_exec:s0 if API >= 20 # # 7+ ARCH/su *2 /system/xbin/su *3 u:object_r:system_file:s0 required # 7+ /system/bin/.ext/.su *3 u:object_r:system_file:s0 gui # 17+ /system/xbin/daemonsu 0755 u:object_r:system_file:s0 required # *2: su.pie for 17+ x86(_32) only # *3: 06755 if API < 18, 0755 if API >= 18 # # 19+ ARCH/supolicy /system/xbin/supolicy 0755 u:object_r:system_file:s0 required # 19+ ARCH/libsupol.so /system/lib(64)/libsupol.so 0644 u:object_r:system_file:s0 required # # 21+ /system/bin/app_process32 *5 /system/bin/app_process32_original 0755 u:object_r:zygote_exec:s0 required # 21+ /system/bin/app_process64 *5 /system/bin/app_process64_original 0755 u:object_r:zygote_exec:s0 required # 21+ /system/bin/app_processXX *5 /system/bin/app_process_init 0755 u:object_r:system_file:s0 required # 21+ /system/bin/app_process (symlink to /system/xbin/daemonsu) required # 21+ *5 /system/bin/app_process32 (symlink to /system/xbin/daemonsu) required # 21+ *5 /system/bin/app_process64 (symlink to /system/xbin/daemonsu) required # *5: Only do this for the relevant bits. On a 64 bits system, leave the 32 bits files alone, or dynamic linker errors # will prevent the system from fully working in subtle ways. The bits of the su binary must also match! # # 17+ common/99SuperSUDaemon *6 /system/etc/init.d/99SuperSUDaemon 0755 u:object_r:system_file:s0 optional # *6: only place this file if /system/etc/init.d is present # # 17+ 'echo 1 >' or 'touch' *7 /system/etc/.installed_su_daemon 0644 u:object_r:system_file:s0 optional # *7: the file just needs to exist or some recoveries will nag you. Even with it there, it may still happen. # # It may seem some files are installed multiple times needlessly, but # it only seems that way. Installing files differently or symlinking # instead of copying (unless specified) will lead to issues eventually. # # After installation, run '/system/xbin/su --install', which may need to # perform some additional installation steps. Ideally, at one point, # a lot of this script will be moved there. # # The included chattr(.pie) binaries are used to remove ext2's immutable # flag on some files. This flag is no longer set by SuperSU's OTA # survival since API level 18, so there is no need for the 64 bit versions. # Note that chattr does not need to be installed to the system, it's just # used by this script, and not supported by the busybox used in older # recoveries. # # ----- "SYSTEM-LESS" INSTALL ----- # # "System-less" install requires a modified boot image (the script can patch # many boot images on-the-fly), but does not touch /system at all. Instead # it keeps all the needed files in an image (/data/su.img) which is mounted # to /su. Default install method on all Android-6.0+ and Samsung-5.1+ # devices. # # Note that even on 6.0+, system compatibility is checked. See the "SYSTEM" # install section above. # # An ext4 image is created as /data/su.img, or /cache/su.img if /data could # not be mounted. Similarly, the APK is placed as either /data/SuperSU.apk # or /cache/SuperSU.apk. This is so we are not dependent on /data decryption # working in recovery, which in the past has proved an issue on brand-new # Android versions and devices. # # /sbin/launch_daemonsu.sh, which is added a service to init.rc, will mount # the image at /su, and launch daemonsu from /su/bin/daemonsu. But before it # does that, it will try to merge /data/su.img and /cache/su.img (leading), # if both are present. It will also try to install the SuperSU APK. # # In BINDSBIN mode the files are placed in /data/adb/su (3rd party tools # should refer to /sbin/supersu or readlink /sbin/supersu_link) instead # of an image mounted as /su, and an overlay is created on top of /sbin. # This is the default behavior on Android O and newer. # # Files are expected at the following places (/su being the mountpoint of # the ext4 image, replace with /data/adb/su in BINDSBIN mode): # # API source target chmod chcon required # # 22+ common/Superuser.apk /[data|cache]/SuperSU.apk 0644 u:object_r:system_file:s0 gui # # 22+ ARCH/su *1 /su/bin/su 0755 u:object_r:system_file:s0 required # 22+ /su/bin/daemonsu 0755 u:object_r:system_file:s0 required # *1: su.pie for 17+ x86(_32) only # # 22+ ARCH/supolicy /su/bin/supolicy_wrapped 0755 u:object_r:system_file:s0 required # 22+ /su/bin/su (symlink) *2 /su/bin/supolicy 0755 u:object_r:system_file:s0 required # 22+ ARCH/libsupol.so /su/lib/libsupol.so 0644 u:object_r:system_file:s0 required # *2: when called this way, su sets the correct LD_LIBRARY_PATH and calls supolicy_wrapped # # 22+ ARCH/sukernel /su/bin/sukernel 0755 u:object_r:system_file:s0 required # # These files are automatically created on launch by daemonsu as needed: # 22+ /system/bin/sh /su/bin/sush 0755 u:object_r:system_file:s0 required # 22+ /system/bin/app_process[64] /su/bin/app_process 0755 u:object_r:system_file:s0 required # # These files are injected into the boot image ramdisk: # 22+ common/launch_daemonsu.sh /sbin/launch_daemonsu.sh 0700 u:object_r:rootfs:s0 required # # On devices where / is in the system partition: # 22+ ARCH/suinit /init 0750 u:object_r:rootfs:s0 required # # The automated boot image patcher included makes the following modifications # to the ramdisk: # # - On devices using split policy (ODP2+): # --- Compiles split policy into single policy # --- Patches init to load single policy instead of split policy # - On device that early-load /system, /vendor and /odm based on DTB (ODP2+): # --- Patches DTB verity settings (unless KEEPVERITY is set) # --- TODO: KEEPVERITY doesn't support /system on these devices at this time # --- TODO: DTB is not backup/restored on re-patch # - Uses the supolicy tool to patch the sepolicy file # --- Optionally combined from parts with secilc # --- Also patching recovery's sepolicy if required # - Injects /sbin/launch_daemon.sh # - Injects /sbin/fbe_bypass.sh (24+, unless KEEPFORCEENCRYPT is set) # - Creates /su # - Removes /verity_key (unless KEEPVERITY is set) # - Patches /*fstab* # --- Removes support_scfs and verify flags (unless KEEPVERITY is set) # --- Changes forceencrypt/forcefdeorfbe into encryptable, or removes them (if REMOVEENCRYPTABLE is set) # --- Set ro mounts to use noatime # - Patches /init.rc # --- Removes 'setprop selinux.reload_policy' occurences # --- Adds a SuperSU:PATCH marker with the version of the sukernel tool # --- Adds a SuperSU:STOCK marker listed the SHA1 of the original boot image # - Adds /init.supersu.rc # --- Adds a sukernel.mount property trigger that mounts /data/su.img to /su # --- Adds the daemonsu service that launches /sbin/launch_daemon.sh # --- Adds exec /sbin/launch_daemonsu.sh on post-fs-data # - Patches /init.environ.rc (if BINDSBIN is not set) # --- Adds PATH variable if it does not exist # --- Prepends /su/bin to the PATH variable # - Patches /*.rc # --- Adds a seclabel to services and execs that are missing one # - In case the device has the root directory inside the system partition: # --- /system_root contents are copied to /boot # --- All files mentioned above are modified in /boot instead of / # --- /boot/*fstab* is modified to mount / to /system_root, and # bind-mount /system to /system_root/system # --- Kernel binary is patched to load from initramfs instead of system # --- Our own init binary (suinit) replaces /init # - In case a ChromeOS bootloader is used # --- Boot image is signed with keys from common/chromeos # - Otherwise # --- Android Verified Boot (v1) signature is detected, and if present (or SIGNBOOTIMAGE is set): # --- Boot image is signed with keys from common/avb # # In case this documentation becomes outdated, please note that the sukernel # tool is very chatty, and its output tells you exactly what it is doing # and how. In TWRP, you can view this output by catting /tmp/recovery.log # after flashing the ZIP. # # The boot image patcher creates a backup of the boot image it patches, for # future restoration. It cannot re-patch a patched boot image, it will restore # the previous boot image first. /[data|cache]/stock_boot_*.gz # # The boot image patcher currently supports kernel binaries and ramdisks compressed # in gzip, bzip2, lz4 (legacy), lz4 (modern), lzo, lzma, and xz formats. # # During boot image patch, /data/custom_ramdisk_patch.sh will be called, # with the name of the ramdisk cpio file as parameter. The script must # replace the input file and return a 0 exit code. # # Just before flashing, the boot image patcher will call # /data/custom_boot_image_patch.sh with the name of the patched boot image # as parameter. A device-specific patcher can further patch the boot image # if needed. It must replace the input file and return a 0 exit code. # # For Android Verified Boot, if /tmp/avb/custom.pk8 and /tmp/avb/custom.x509.der # are present, these are used to sign the boot image instead of SuperSU's # default keys. OUTFD=$2 ZIP=$3 getvar() { local VARNAME=$1 local VALUE=$(eval echo \$"$VARNAME"); for FILE in /data/.supersu /cache/.supersu /system/.supersu; do if [ -z "$VALUE" ]; then LINE=$(cat $FILE 2>/dev/null | grep "$VARNAME=") if [ ! -z "$LINE" ]; then VALUE=${LINE#*=} fi fi done eval $VARNAME=\$VALUE } readlink /proc/$$/fd/$OUTFD 2>/dev/null | grep /tmp >/dev/null if [ "$?" -eq "0" ]; then # rerouted to log file, we don't want our ui_print commands going there OUTFD=0 # we are probably running in embedded mode, see if we can find the right fd # we know the fd is a pipe and that the parent updater may have been started as # 'update-binary 3 fd zipfile' for FD in `ls /proc/$$/fd`; do readlink /proc/$$/fd/$FD 2>/dev/null | grep pipe >/dev/null if [ "$?" -eq "0" ]; then ps | grep " 3 $FD " | grep -v grep >/dev/null if [ "$?" -eq "0" ]; then OUTFD=$FD break fi fi done fi ui_print_always() { echo -n -e "ui_print $1\n" >> /proc/self/fd/$OUTFD echo -n -e "ui_print\n" >> /proc/self/fd/$OUTFD } if [ -z "$LESSLOGGING" ]; then LESSLOGGING=false fi UI_PRINT_LAST="" ui_print() { if (! $LESSLOGGING); then UI_PRINT_LAST="$1" ui_print_always "$1" fi } ui_print_less() { if ($LESSLOGGING); then ui_print_always "$1" fi } ch_con() { LD_LIBRARY_PATH=$SYSTEMLIB /system/bin/toybox chcon -h u:object_r:system_file:s0 $1 1>/dev/null 2>/dev/null LD_LIBRARY_PATH=$SYSTEMLIB /system/toolbox chcon -h u:object_r:system_file:s0 $1 1>/dev/null 2>/dev/null LD_LIBRARY_PATH=$SYSTEMLIB /system/bin/toolbox chcon -h u:object_r:system_file:s0 $1 1>/dev/null 2>/dev/null chcon -h u:object_r:system_file:s0 $1 1>/dev/null 2>/dev/null LD_LIBRARY_PATH=$SYSTEMLIB /system/bin/toybox chcon u:object_r:system_file:s0 $1 1>/dev/null 2>/dev/null LD_LIBRARY_PATH=$SYSTEMLIB /system/toolbox chcon u:object_r:system_file:s0 $1 1>/dev/null 2>/dev/null LD_LIBRARY_PATH=$SYSTEMLIB /system/bin/toolbox chcon u:object_r:system_file:s0 $1 1>/dev/null 2>/dev/null chcon u:object_r:system_file:s0 $1 1>/dev/null 2>/dev/null } ch_con_ext() { LD_LIBRARY_PATH=$SYSTEMLIB /system/bin/toybox chcon $2 $1 1>/dev/null 2>/dev/null LD_LIBRARY_PATH=$SYSTEMLIB /system/toolbox chcon $2 $1 1>/dev/null 2>/dev/null LD_LIBRARY_PATH=$SYSTEMLIB /system/bin/toolbox chcon $2 $1 1>/dev/null 2>/dev/null chcon $2 $1 1>/dev/null 2>/dev/null } ln_con() { LD_LIBRARY_PATH=$SYSTEMLIB /system/bin/toybox ln -s $1 $2 1>/dev/null 2>/dev/null LD_LIBRARY_PATH=$SYSTEMLIB /system/toolbox ln -s $1 $2 1>/dev/null 2>/dev/null LD_LIBRARY_PATH=$SYSTEMLIB /system/bin/toolbox ln -s $1 $2 1>/dev/null 2>/dev/null ln -s $1 $2 1>/dev/null 2>/dev/null ch_con $2 1>/dev/null 2>/dev/null } set_perm() { chown $1.$2 $4 chown $1:$2 $4 chmod $3 $4 ch_con $4 ch_con_ext $4 $5 } cp_perm() { rm $5 if [ -f "$4" ]; then cat $4 > $5 set_perm $1 $2 $3 $5 $6 fi } is_mounted() { if [ ! -z "$2" ]; then cat /proc/mounts | grep $1 | grep $2, >/dev/null else cat /proc/mounts | grep $1 >/dev/null fi return $? } toolbox_mount() { RW=rw if [ ! -z "$2" ]; then RW=$2 fi DEV= POINT= FS= for i in `cat /etc/fstab | grep -v "#" | grep "$1"`; do if [ -z "$DEV" ]; then DEV=$i elif [ -z "$POINT" ]; then POINT=$i elif [ -z "$FS" ]; then FS=$i break fi done if [ ! -z "$SYSTEM_DEVICE" ]; then if (`echo "$SYSTEM_DEVICE" | grep "$DEV" >/dev/null`); then DEV=$SYSTEM_DEVICE fi fi if [ ! -z "$VENDOR_DEVICE" ]; then if (`echo "$VENDOR_DEVICE" | grep "$DEV" >/dev/null`); then DEV=$VENDOR_DEVICE fi fi if [ ! -z "$DEV" ] && [ ! -z "$POINT" ] && [ ! -z "$DEV" ]; then if (! is_mounted $1 $RW); then mount -t $FS -o $RW $DEV $POINT; fi if (! is_mounted $1 $RW); then mount -t $FS -o $RW,remount $DEV $POINT; fi fi DEV= POINT= FS= for i in `cat /etc/recovery.fstab | grep -v "#" | grep "$1"`; do if [ -z "$POINT" ]; then POINT=$i elif [ -z "$FS" ]; then FS=$i elif [ -z "$DEV" ]; then DEV=$i break fi done # usually , but sometimes if [ "$DEV" = "ext4" ] || [ "$DEV" = "f2fs" ] || [ "$DEV" = "vfat" ] || [ "$DEV" = "emmc" ] || [ "$DEV" = "swap" ]; then local _POINT=$POINT local _FS=$FS local _DEV=$DEV DEV=$_POINT POINT=$_FS FS=$_DEV fi if [ ! -z "$SYSTEM_DEVICE" ]; then if (`echo "$SYSTEM_DEVICE" | grep "$DEV" >/dev/null`); then DEV=$SYSTEM_DEVICE fi fi if [ ! -z "$VENDOR_DEVICE" ]; then if (`echo "$VENDOR_DEVICE" | grep "$DEV" >/dev/null`); then DEV=$VENDOR_DEVICE fi fi if [ ! -z "$DEV" ] && [ ! -z "$POINT" ] && [ ! -z "$DEV" ]; then if [ "$FS" = "emmc" ]; then if (! is_mounted $1 $RW); then mount -t ext4 -o $RW $DEV $POINT; fi if (! is_mounted $1 $RW); then mount -t ext4 -o $RW,remount $DEV $POINT; fi if (! is_mounted $1 $RW); then mount -t f2fs -o $RW $DEV $POINT; fi if (! is_mounted $1 $RW); then mount -t f2fs -o $RW,remount $DEV $POINT; fi else if (! is_mounted $1 $RW); then mount -t $FS -o $RW $DEV $POINT; fi if (! is_mounted $1 $RW); then mount -t $FS -o $RW,remount $DEV $POINT; fi fi fi } remount_system_rw() { if (! is_mounted /system rw); then mount -o rw,remount /system; fi if (! is_mounted /system rw); then mount -o rw,remount /system /system; fi if (! is_mounted /system rw); then toolbox_mount /system; fi } # 'readlink -f' is not reliable across devices/recoveries, this works for our case resolve_link() { local RESOLVE=$1 local RESOLVED= while (true); do RESOLVED=$(readlink $RESOLVE || echo $RESOLVE) if [ "$RESOLVE" = "$RESOLVED" ]; then echo $RESOLVE break else RESOLVE=$RESOLVED fi done } wipe_system_files_if_present() { GO=false SYSTEMFILES=" /system/xbin/daemonsu /system/xbin/sugote /system/xbin/sugote-mksh /system/xbin/supolicy /system/xbin/ku.sud /system/xbin/.ku /system/xbin/.su /system/lib/libsupol.so /system/lib64/libsupol.so /system/bin/.ext/.su /system/etc/init.d/99SuperSUDaemon /system/etc/.installed_su_daemon /system/app/Superuser.apk /system/app/Superuser.odex /system/app/Superuser /system/app/SuperUser.apk /system/app/SuperUser.odex /system/app/SuperUser /system/app/superuser.apk /system/app/superuser.odex /system/app/superuser /system/app/Supersu.apk /system/app/Supersu.odex /system/app/Supersu /system/app/SuperSU.apk /system/app/SuperSU.odex /system/app/SuperSU /system/app/supersu.apk /system/app/supersu.odex /system/app/supersu /system/app/VenomSuperUser.apk /system/app/VenomSuperUser.odex /system/app/VenomSuperUser " for FILE in $SYSTEMFILES; do if [ -d "$FILE" ]; then GO=true; fi if [ -f "$FILE" ]; then GO=true; fi done RMSU=false if (! $RWSYSTEM); then if [ -f "/system/xbin/su" ]; then # only remove /system/xbin/su if it's SuperSU. Could be firmware-included version, we # do not want to cause remount for that SUPERSU_CHECK=$(cat /system/xbin/su | grep SuperSU) if [ $? -eq 0 ]; then GO=true RMSU=true fi fi SPECIALSYSTEMFILES=" /system/etc/install-recovery_original.sh /system/bin/install-recovery_original.sh /system/bin/app_process32_original /system/bin/app_process32_xposed /system/bin/app_process64_original /system/bin/app_process64_xposed /system/bin/app_process_init " for FILE in $SPECIALSYSTEMFILES; do if [ -d "$FILE" ]; then GO=true; fi done fi if ($GO); then if (! $RWSYSTEM); then ui_print "- Remounting system r/w :(" remount_system_rw fi for FILE in $SYSTEMFILES; do if [ -d "$FILE" ]; then rm -rf $FILE; fi if [ -f "$FILE" ]; then rm -f $FILE; fi done if (! $RWSYSTEM); then # remove wrongly placed /system/xbin/su as well if ($RMSU); then rm -f /system/xbin/su fi # Restore install-recovery and app_process from system install # Otherwise, our system-less install will fail to boot if [ -f "/system/etc/install-recovery_original.sh" ]; then rm -f /system/etc/install-recovery.sh mv /system/etc/install-recovery_original.sh /system/etc/install-recovery.sh fi if [ -f "/system/bin/install-recovery_original.sh" ]; then rm -f /system/bin/install-recovery.sh mv /system/bin/install-recovery_original.sh /system/bin/install-recovery.sh fi if [ -f "/system/bin/app_process64_original" ]; then rm -f /system/bin/app_process64 if [ -f "/system/bin/app_process64_xposed" ]; then ln -s /system/bin/app_process64_xposed /system/bin/app_process64 else mv /system/bin/app_process64_original /system/bin/app_process64 fi fi if [ -f "/system/bin/app_process32_original" ]; then rm -f /system/bin/app_process32 if [ -f "/system/bin/app_process32_xposed" ]; then ln -s /system/bin/app_process32_xposed /system/bin/app_process32 else mv /system/bin/app_process32_original /system/bin/app_process32 fi fi if [ -f "/system/bin/app_process64" ]; then rm /system/bin/app_process ln -s /system/bin/app_process64 /system/bin/app_process elif [ -f "/system/bin/app_process32" ]; then rm /system/bin/app_process ln -s /system/bin/app_process32 /system/bin/app_process fi rm -f /system/bin/app_process_init fi fi } wipe_data_competitors_and_cache() { rm -f /data/dalvik-cache/*com.noshufou.android.su* rm -f /data/dalvik-cache/*/*com.noshufou.android.su* rm -f /data/dalvik-cache/*com.koushikdutta.superuser* rm -f /data/dalvik-cache/*/*com.koushikdutta.superuser* rm -f /data/dalvik-cache/*com.mgyun.shua.su* rm -f /data/dalvik-cache/*/*com.mgyun.shua.su* rm -f /data/dalvik-cache/*com.m0narx.su* rm -f /data/dalvik-cache/*/*com.m0narx.su* rm -f /data/dalvik-cache/*com.kingroot.kinguser* rm -f /data/dalvik-cache/*/*com.kingroot.kinguser* rm -f /data/dalvik-cache/*com.kingroot.master* rm -f /data/dalvik-cache/*/*com.kingroot.master* rm -f /data/dalvik-cache/*me.phh.superuser* rm -f /data/dalvik-cache/*/*me.phh.superuser* rm -f /data/dalvik-cache/*Superuser.apk* rm -f /data/dalvik-cache/*/*Superuser.apk* rm -f /data/dalvik-cache/*SuperUser.apk* rm -f /data/dalvik-cache/*/*SuperUser.apk* rm -f /data/dalvik-cache/*superuser.apk* rm -f /data/dalvik-cache/*/*superuser.apk* rm -f /data/dalvik-cache/*VenomSuperUser.apk* rm -f /data/dalvik-cache/*/*VenomSuperUser.apk* rm -f /data/dalvik-cache/*eu.chainfire.supersu* rm -f /data/dalvik-cache/*/*eu.chainfire.supersu* rm -f /data/dalvik-cache/*Supersu.apk* rm -f /data/dalvik-cache/*/*Supersu.apk* rm -f /data/dalvik-cache/*SuperSU.apk* rm -f /data/dalvik-cache/*/*SuperSU.apk* rm -f /data/dalvik-cache/*supersu.apk* rm -f /data/dalvik-cache/*/*supersu.apk* rm -f /data/dalvik-cache/*.oat rm -rf /data/app/com.noshufou.android.su* rm -rf /data/app/com.koushikdutta.superuser* rm -rf /data/app/com.mgyun.shua.su* rm -rf /data/app/com.m0narx.su* rm -rf /data/app/com.kingroot.kinguser* rm -rf /data/app/com.kingroot.master* rm -rf /data/app/me.phh.superuser* } # check_zero "progress message" "success message" "failure message" "command" check_zero() { if ($CONTINUE); then if [ ! -z "$1" ]; then ui_print "$1"; fi eval "$4" if [ $? -eq 0 ]; then if [ ! -z "$2" ]; then ui_print "$2"; fi else if [ ! -z "$3" ]; then if [ ! -z "$1" ]; then ui_print_less "$1" else ui_print_less "$UI_PRINT_LAST" fi ui_print_always "$3"; fi CONTINUE=false fi fi } # check_zero_def "progress message" "command" check_zero_def() { check_zero "$1" "" "--- Failure, aborting" "$2" } # find boot image partition if not set already find_boot_image() { # expand the detection if we find more, instead of reading from fstab, because unroot # from the SuperSU APK doesn't have the fstab to read from if [ -z "$BOOTIMAGE" ]; then local TRY="kern-a KERN-A android_boot ANDROID_BOOT kernel KERNEL boot BOOT lnx LNX" if (! $SLOT_USED); then # some devices don't have B partitions, but do include A in the name # only include if !$SLOT_USED because otherwise it would interfere with real # A/B partition devices TRY="boot_a BOOT_A $TRY" fi for PARTITION in $TRY; do BOOTIMAGE=$(readlink /dev/block/by-name/$PARTITION || readlink /dev/block/platform/*/by-name/$PARTITION || readlink /dev/block/platform/*/*/by-name/$PARTITION || readlink /dev/block/by-name/$PARTITION$SLOT_SUFFIX || readlink /dev/block/platform/*/by-name/$PARTITION$SLOT_SUFFIX || readlink /dev/block/platform/*/*/by-name/$PARTITION$SLOT_SUFFIX) if [ ! -z "$BOOTIMAGE" ]; then break; fi done fi # if we found nothing, try the recovery.fstab (TWRP), and hope named partitions are actually # available from Android for APK unroot; this is know to occur, suspected to be a TWRP bug if [ -z "$BOOTIMAGE" ]; then BOOTIMAGE=$(cat /etc/recovery.fstab | grep -v "#" | grep -m 1 "^/boot" | sed 's/\t/ /g' | tr -s " " | cut -f 3 -d " " | grep "/dev/block") fi } # which_compression "input_file" # sets $COMPRESSION COMPRESSION= which_compression() { local MATCH=none for COMP in `ls $COM/formats`; do if (`dd if=$1 bs=1 count=2 2>/dev/null | grep -f $COM/formats/$COMP >/dev/null`); then MATCH=$COMP break fi done if (`echo $MATCH | grep gzip >/dev/null`); then MATCH=gzip fi if (`echo $MATCH | grep lz4 >/dev/null`); then MATCH=lz4 fi COMPRESSION=$MATCH } # decompress "$COMPRESSION" "input_file" "output_file" decompress() { rm -rf $3 if [ "$1" = "none" ]; then cat $2 > $3 elif [ "$1" = "gzip" ]; then LD_LIBRARY_PATH=$RAMDISKLIB $BIN/sukernel --ungzip $2 $3 elif [ "$1" = "bzip2" ]; then LD_LIBRARY_PATH=$RAMDISKLIBTOOLS $BINTOOLS/bzip2 -dc < $2 > $3 elif [ "$1" = "legz4" ]; then LD_LIBRARY_PATH=$RAMDISKLIBTOOLS $BINTOOLS/lz4 -dc < $2 > $3 elif [ "$1" = "lz4" ]; then LD_LIBRARY_PATH=$RAMDISKLIBTOOLS $BINTOOLS/lz4 -dc < $2 > $3 elif [ "$1" = "lzo" ]; then LD_LIBRARY_PATH=$RAMDISKLIBTOOLS $BINTOOLS/lzop -dc < $2 > $3 elif [ "$1" = "lzma" ]; then LD_LIBRARY_PATH=$RAMDISKLIBTOOLS $BINTOOLS/xz -dc < $2 > $3 elif [ "$1" = "xz" ]; then LD_LIBRARY_PATH=$RAMDISKLIBTOOLS $BINTOOLS/xz -dc < $2 > $3 fi if [ "$?" != "0" ]; then rm -rf $3 fi } # compress "$COMPRESSION" "input_file" "output_file" compress() { rm -rf $3 if [ "$1" = "none" ]; then cat $2 > $3 elif [ "$1" = "gzip" ]; then LD_LIBRARY_PATH=$RAMDISKLIB $BIN/sukernel --gzip $2 $3 elif [ "$1" = "bzip2" ]; then LD_LIBRARY_PATH=$RAMDISKLIBTOOLS $BINTOOLS/bzip2 -9c < $2 > $3 elif [ "$1" = "legz4" ]; then LD_LIBRARY_PATH=$RAMDISKLIBTOOLS $BINTOOLS/lz4 -l9c < $2 > $3 elif [ "$1" = "lz4" ]; then LD_LIBRARY_PATH=$RAMDISKLIBTOOLS $BINTOOLS/lz4 -9c < $2 > $3 elif [ "$1" = "lzo" ]; then LD_LIBRARY_PATH=$RAMDISKLIBTOOLS $BINTOOLS/lzop -9c < $2 > $3 elif [ "$1" = "lzma" ]; then LD_LIBRARY_PATH=$RAMDISKLIBTOOLS $BINTOOLS/xz --format=lzma --lzma1 -9c < $2 > $3 elif [ "$1" = "xz" ]; then LD_LIBRARY_PATH=$RAMDISKLIBTOOLS $BINTOOLS/xz --check=crc32 --lzma2 -9c < $2 > $3 fi if [ "$?" != "0" ]; then rm -rf $3 fi } # decompress_check "progress message" "input_file" "output_file" decompress_check() { if ($CONTINUE); then which_compression $2 local MSG="" if [ ! -z "$1" ]; then MSG="$1 ($COMPRESSION)" fi check_zero_def "$MSG" "decompress $COMPRESSION $2 $3; cat /$3 >/dev/null 2>/dev/null" fi } # compress_check "progress message" "$COMPRESSION" "input_file" "output_file" compress_check() { if ($CONTINUE); then local MSG="" if [ ! -z "$1" ]; then MSG="$1 ($COMPRESSION)" fi check_zero_def "$MSG" "compress $COMPRESSION $3 $4; cat /$4 >/dev/null 2>/dev/null" fi } # use only on 6.0+, tries to read current boot image and detect if we can do a system install # without any boot image patching. Requirements: # - /data readable # - not pre-patched by SuperSU # - dm-verity disabled # - init loads from /data/security/current/sepolicy # - sepolicy has init load_policy or permissive init # It symlink/patches the relevant files to /data, and sets SYSTEMLESS variable if not already set detect_systemless_required() { OLD_SYSTEMLESS=$SYSTEMLESS if [ "$OLD_SYSTEMLESS" = "detect" ]; then # we don't override a pre-set true/false value SYSTEMLESS=true fi # check /data mounted if (! is_mounted /data); then return fi # find boot image partition find_boot_image CONTINUE=true if [ -z "$BOOTIMAGE" ]; then # no boot image partition detected, abort return fi # extract ramdisk from boot image rm -rf /sutmp mkdir /sutmp check_zero "" "" "" "LD_LIBRARY_PATH=$RAMDISKLIB $BIN/sukernel --bootimg-extract-ramdisk $BOOTIMAGE /sutmp/ramdisk.packed" decompress_check "" "/sutmp/ramdisk.packed" "/sutmp/ramdisk" if (! $CONTINUE); then return; fi # detect SuperSU patch LD_LIBRARY_PATH=$RAMDISKLIB $BIN/sukernel --patch-test /sutmp/ramdisk if [ $? -ne 0 ]; then return fi # detect dm-verity in use if (! $SYSTEM_ROOT_USED); then for i in `LD_LIBRARY_PATH=$RAMDISKLIB $BIN/sukernel --cpio-ls /sutmp/ramdisk | grep fstab`; do rm -f /sutmp/fstab check_zero "" "" "" "LD_LIBRARY_PATH=$RAMDISKLIB $BIN/sukernel --cpio-extract /sutmp/ramdisk $i /sutmp/fstab" if (! $CONTINUE); then return; fi VERIFY=$(cat /sutmp/fstab | grep verify | grep system) if [ $? -eq 0 ]; then # verify flag found, dm-verity probably enabled, modifying /system may prevent boot return fi done else for i in `ls /system_root | grep fstab`; do VERIFY=$(cat /system_root/$i | grep verify | grep system) if [ $? -eq 0 ]; then # verify flag found, dm-verity probably enabled, modifying /system may prevent boot return fi done fi # detect init loading from /data/security/current/sepolicy if (! $SYSTEM_ROOT_USED); then check_zero "" "" "" "LD_LIBRARY_PATH=$RAMDISKLIB $BIN/sukernel --cpio-extract /sutmp/ramdisk ${CPIO_PREFIX}init /sutmp/init" if (! $CONTINUE); then return; fi else cat /system_root/init > /sutmp/init fi if (cat /sutmp/init 2>/dev/null | grep "/data/security/current/sepolicy" >/dev/null); then # this init doesn't load from the default sepolicy override location return fi if (cat /sutmp/init 2>/dev/null | grep "selinux.reload_policy" >/dev/null); then # this init doesn't react to setprop selinux.reload_policy return fi # detect selinux.reload_policy being set if (! $SYSTEM_ROOT_USED); then check_zero "" "" "" "LD_LIBRARY_PATH=$RAMDISKLIB $BIN/sukernel --cpio-extract /sutmp/ramdisk ${CPIO_PREFIX}init.rc /sutmp/init.rc" if (! $CONTINUE); then return; fi else cat /system_root/init.rc > /sutmp/init.rc fi if (cat /sutmp/init.rc 2>/dev/null | grep "setprop selinux.reload_policy 1" >/dev/null); then # this init.rc doesn't setprop selinux.reload_policy 1 return fi # extract sepolicy if (! $SYSTEM_ROOT_USED); then check_zero "" "" "" "LD_LIBRARY_PATH=$RAMDISKLIB $BIN/sukernel --cpio-extract /sutmp/ramdisk ${CPIO_PREFIX}sepolicy /sutmp/sepolicy" if (! $CONTINUE); then return; fi else cat /system_root/sepolicy > /sutmp/sepolicy fi GO=false # detect init permissive if (! $GO); then INIT_PERMISSIVE=$(LD_LIBRARY_PATH=$RAMDISKLIB $BIN/supolicy --dumpav /sutmp/sepolicy | grep "[TYPE]" | grep " init (PERMISSIVE) ") if [ $? -eq 0 ]; then GO=true fi fi # detect init load_policy if (! $GO); then INIT_LOAD_POLICY=$(LD_LIBRARY_PATH=$RAMDISKLIB $BIN/supolicy --dumpav /sutmp/sepolicy | grep "[AV]" | grep " ALLOW " | grep " init-->kernel (security) " | grep "load_policy") if [ $? -eq 0 ]; then GO=true fi fi # copy files to /data if (! $GO); then return; fi rm -rf /data/security/* mkdir /data/security/current set_perm 1000 1000 0755 /data/security/current u:object_r:security_file:s0 LD_LIBRARY_PATH=$RAMDISKLIB $BIN/supolicy --file /sutmp/sepolicy /data/security/current/sepolicy --sdk=$API set_perm 1000 1000 0644 /data/security/current/sepolicy u:object_r:security_file:s0 for i in seapp_contexts file_contexts file_contexts.bin property_contexts service_contexts selinux_version; do ln -s /$i /data/security/current/$i done ln -s /system/etc/security/mac_permissions.xml /data/security/current/mac_permissions.xml # if we reach this point, we can do a system install if [ "$OLD_SYSTEMLESS" = "detect" ]; then # we don't override a pre-set true/false value SYSTEMLESS=false fi } avb() { local OLD_LD_LIBRARY_PATH=$LD_LIBRARY_PATH unset LD_LIBRARY_PATH BOOTSIGNATURE="/system/bin/dalvikvm -Xbootclasspath:/system/framework/core-oj.jar:/system/framework/core-libart.jar:/system/framework/conscrypt.jar:/system/framework/bouncycastle.jar -Xnodex2oat -Xnoimage-dex2oat -cp $COM/avb/BootSignature_Android.jar com.android.verity.BootSignature" AVB_RET=$($BOOTSIGNATURE "$@" 2>&1) LD_LIBRARY_PATH=$OLD_LD_LIBRARY_PATH } detect_avb() { # BootSignature cannot read from /dev/block, make copy local INPUT=$1 if (`echo "$INPUT" | grep '^/dev/' >/dev/null`); then dd if=$INPUT of=/sutmp/avb.img bs=4096 INPUT=/sutmp/avb.img fi avb -verify $INPUT if (`echo $AVB_RET | grep "VALID" >/dev/null 2>&1`); then AVB_SIGNED=true fi rm /sutmp/avb.img } sign_avb() { PK8=$COM/avb/supersu.pk8 X509=$COM/avb/supersu.x509.der if [ -f "/tmp/avb/custom.pk8" ]; then if [ -f "/tmp/avb/custom.x509.der" ]; then PK8=/tmp/avb/custom.pk8 X509=/tmp/avb/custom.x509.der fi fi avb /boot $1 $PK8 $X509 $2 detect_avb $2 } ui_print " " ui_print "*****************" ui_print_always "SuperSU installer" ui_print "*****************" # fix slow RNG on some devices, which may cause installation to take weeks (kernel/toybox issue) mount -o bind /dev/urandom /dev/random # hardware HARDWARE=$(getprop ro.boot.hardware) # detect slot-based partition layout SLOT_USED=false SLOT_SUFFIX=$(getprop ro.boot.slot_suffix 2>/dev/null) if [ -z "$SLOT_SUFFIX" ]; then for i in `cat /proc/cmdline`; do if [ "${i%=*}" = "androidboot.slot_suffix" ]; then SLOT_SUFFIX=${i#*=} break fi done fi if [ ! -z "$SLOT_SUFFIX" ]; then SLOT_USED=true fi # detect system partition # /fstab.* for stock images, which can contain slotselect: # initramfs_root: /dev/block/bootdevice/by-name/system /system ext4 ro,barrier=1,discard wait[,slotselect][,verify] # system_root-boot: /dev/block/bootdevice/by-name/system / ext4 ro,barrier=1,discard wait[,slotselect],verify # system_root-recovery: /dev/block/bootdevice/by-name/system /system_root ext4 ro,barrier=1,discard wait[,slotselect] # # /etc/fstab for TWRP, which will contain $SLOT_SUFFIX, if any # /dev/block/bootdevice/by-name/system_a /system ext4 rw 0 0 # # /etc/recovery.fstab for TWRP, which will NOT contain $SLOT_SUFFIX # /system ext4 /dev/block/bootdevice/by-name/system # find_device fstab-expr recovery.fstab-expr find_device() { FIND_DEVICE_RET= local DEVICE=$(cat /fstab.* /etc/fstab | grep -v "#" | grep -m 1 "$1" | tr -s " "); if [ -z "$DEVICE" ]; then # rare case, only occurs if TWRP boot is incomplete DEVICE=$(cat /etc/recovery.fstab | grep -v "#" | grep -m 1 "$2" | tr -s " ") if [ ! -z "$DEVICE" ]; then local POINT= local FS= for i in $DEVICE; do if [ -z "$POINT" ]; then POINT=$i elif [ -z "$FS" ]; then FS=$i else DEVICE=$i if (! `echo "$DEVICE" | grep '_' >/dev/null`); then DEVICE=$i$SLOT_SUFFIX fi break fi done fi fi if [ ! -z "$DEVICE" ]; then if ($SLOT_USED); then if (! `echo $DEVICE | grep slotselect >/dev/null 2>&1`); then if (! `echo $DEVICE | grep "$SLOT_SUFFIX" >/dev/null 2>&1`); then SLOT_USED=false fi elif [ -d "/twres" ]; then # determine TWRP slot switch, on Pixel/XL needs 3.1.0-RC2+ for i in $DEVICE; do if (`readlink $i >/dev/null 2>&1`); then # only supports _X form of slot names right now LINK=$(readlink $i) SUFFIX=$(echo $LINK | grep -o -e "..\$") if [ ! -z "SUFFIX" ]; then if (`echo "$SUFFIX" | grep '_' >/dev/null`); then SLOT_SUFFIX=$SUFFIX fi fi fi break done fi for i in $DEVICE; do # remove current slot suffix, only supports _X form of slot names right now SUFFIX=$(echo $i | grep -o -e "..\$") if (`echo "$SUFFIX" | grep '_' >/dev/null`); then i=$(echo $i | sed "s/$SUFFIX//g") fi if (! `echo $i | grep "$SLOT_SUFFIX" >/dev/null 2>&1`); then # add correct slot suffix DEVICE=$i$SLOT_SUFFIX else # slot suffix already included, or no slot suffix DEVICE=$i fi break done else # no slot suffix for i in $DEVICE; do DEVICE=$i break done fi fi FIND_DEVICE_RET=$DEVICE } find_device " / \| /system \| /system_root " "^/system " SYSTEM_DEVICE=$FIND_DEVICE_RET find_device " /vendor " "^/vendor " VENDOR_DEVICE=$FIND_DEVICE_RET ui_print "- Mounting /system, /vendor, /data and rootfs" SYSTEM_ROOT_USED=false HAD_SYSTEM=false HAD_SYSTEM_RW=false HAD_VENDOR=false HAD_SYSTEM_ROOT=false if (`mount | grep " /system " >/dev/null 2>&1`); then HAD_SYSTEM=true if (`mount | grep " /system " | grep "rw" >/dev/null 2>&1`); then HAD_SYSTEM_RW=true fi fi if (`mount | grep " /system_root " >/dev/null 2>&1`); then HAD_SYSTEM_ROOT=true fi if (`mount | grep " /vendor " >/dev/null 2>&1`); then HAD_VENDOR=true fi if (! $HAD_SYSTEM); then if (! $HAD_SYSTEM_ROOT); then mount -o ro /system toolbox_mount /system ro fi fi if (! $HAD_VENDOR); then mount -o ro /vendor toolbox_mount /vendor ro fi if [ -f "/system/sepolicy" ]; then SYSTEM_ROOT_USED=true elif [ -f "/system_root/sepolicy" ]; then SYSTEM_ROOT_USED=true elif [ -f "/system/init.rc" ]; then SYSTEM_ROOT_USED=true elif [ -f "/system_root/init.rc" ]; then SYSTEM_ROOT_USED=true fi if ($SYSTEM_ROOT_USED); then if (! $HAD_SYSTEM_ROOT); then if (! `umount /system`); then umount -l /system fi rm /system mkdir /system mkdir /system_root mount -o ro $SYSTEM_DEVICE /system_root mount -o bind /system_root/system /system fi fi mount /data toolbox_mount /data mount -o rw,remount / mount -o rw,remount / / if [ -z "$BIN" ]; then # TWRP went full retard if [ ! -f "/sbin/unzip" ]; then ui_print "- BAD RECOVERY DETECTED, NO UNZIP, ABORTING" exit 1 fi fi if ($SYSTEM_ROOT_USED); then CPIO_PREFIX=boot/ else CPIO_PREFIX= fi if [ -z "$NOOVERRIDE" ]; then # read override variables getvar SYSTEMLESS getvar PATCHBOOTIMAGE getvar SIGNBOOTIMAGE getvar BOOTIMAGE getvar STOCKBOOTIMAGE getvar BINDSYSTEMXBIN getvar PERMISSIVE getvar KEEPVERITY getvar KEEPFORCEENCRYPT getvar REMOVEENCRYPTABLE getvar FRP getvar BINDSBIN fi if [ -z "$SYSTEMLESS" ]; then # detect if we need systemless, based on Android version and boot image SYSTEMLESS=detect fi if [ -z "$PATCHBOOTIMAGE" ]; then # only if we end up doing a system-less install PATCHBOOTIMAGE=true fi if [ -z "$SIGNBOOTIMAGE" ]; then # detect if we need to sign the boot image, based on if the input boot # image was signed itself SIGNBOOTIMAGE=detect fi if [ -z "$BINDSYSTEMXBIN" ]; then # causes launch_daemonsu to bind over /system/xbin, disabled by default BINDSYSTEMXBIN=false fi if [ -z "$PERMISSIVE" ]; then # don't make everything fake-permissive PERMISSIVE=false fi if [ -z "$KEEPVERITY" ]; then # we don't keep dm-verity by default KEEPVERITY=false fi if [ -z "$KEEPFORCEENCRYPT" ]; then # we don't keep forceencrypt by default KEEPFORCEENCRYPT=false fi if [ -z "$REMOVEENCRYPTABLE" ]; then # detect if we need to remove the encryptable flags, based on Android version and brand REMOVEENCRYPTABLE=detect fi if [ -z "$FRP" ]; then # enable FRP if we're using slots, implying large enough boot image FRP=$SLOT_USED fi if [ -z "$BINDSBIN"]; then # would cause launch_daemonsu to bind over /sbin, and places files directly in /data # instead of inside an image and mounted; detected and enabled by default for O+ BINDSBIN=detect fi API=$(cat /system/build.prop | grep "ro.build.version.sdk=" | dd bs=1 skip=21 count=2) ABI=$(cat /system/build.prop /default.prop | grep -m 1 "ro.product.cpu.abi=" | dd bs=1 skip=19 count=3) ABILONG=$(cat /system/build.prop /default.prop | grep -m 1 "ro.product.cpu.abi=" | dd bs=1 skip=19) ABI2=$(cat /system/build.prop /default.prop | grep -m 1 "ro.product.cpu.abi2=" | dd bs=1 skip=20 count=3) SUMOD=06755 SUPOLICY=false INSTALL_RECOVERY_CONTEXT=u:object_r:system_file:s0 MKSH=/system/bin/mksh PIE= SU=su ARCH=arm ARCHTOOLS=arm_tools APKFOLDER=false APKNAME=/system/app/Superuser.apk APPPROCESS=false APPPROCESS64=false SYSTEMLIB=/system/lib:/vendor/lib SYSTEMLIBTOOLS=/system/lib:/vendor/lib SYSTEMLIBPATH=/system/lib RWSYSTEM=true INIT_SUPERSU_RC=init.supersu.rc PATCHDTB=false FBEBYPASS=false if [ "$API" -le "21" ]; then # needed for some intermediate AOSP verions remount_system_rw cat /system/bin/toolbox > /system/toolbox chmod 0755 /system/toolbox ch_con /system/toolbox fi if [ "$ABI" = "x86" ]; then ARCH=x86; ARCHTOOLS=x86_tools; fi; if [ "$ABI2" = "x86" ]; then ARCH=x86; ARCHTOOLS=x86_tools; fi; if [ "$API" -eq "$API" ]; then if [ "$API" -ge "17" ]; then PIE=.pie if [ "$ARCH" = "x86" ]; then SU=su.pie; fi; if [ "$ABILONG" = "armeabi-v7a" ]; then ARCH=armv7; ARCHTOOLS=arm_tools; fi; if [ "$ABI" = "mip" ]; then ARCH=mips; ARCHTOOLS=mips_tools; fi; if [ "$ABILONG" = "mips" ]; then ARCH=mips; ARCHTOOLS=mips_tools; fi; fi if [ "$API" -ge "18" ]; then SUMOD=0755 fi if [ "$API" -ge "20" ]; then if [ "$ABILONG" = "arm64-v8a" ]; then ARCH=arm64; ARCHTOOLS=arm_tools; SYSTEMLIB=/system/lib64:/vendor/lib64; SYSTEMLIBTOOLS=/system/lib:/vendor/lib; SYSTEMLIBPATH=/system/lib64; APPPROCESS64=true; fi; if [ "$ABILONG" = "mips64" ]; then ARCH=mips64; ARCHTOOLS=mips_tools; SYSTEMLIB=/system/lib64:/vendor/lib64; SYSTEMLIBTOOLS=/system/lib:/vendor/lib; SYSTEMLIBPATH=/system/lib64; APPPROCESS64=true; fi; if [ "$ABILONG" = "x86_64" ]; then ARCH=x64; ARCHTOOLS=x86_tools; SYSTEMLIB=/system/lib64:/vendor/lib64; SYSTEMLIBTOOLS=/system/lib:/vendor/lib; SYSTEMLIBPATH=/system/lib64; APPPROCESS64=true; fi; APKFOLDER=true APKNAME=/system/app/SuperSU/SuperSU.apk fi if [ "$API" -ge "19" ]; then SUPOLICY=true if [ "$(LD_LIBRARY_PATH=$SYSTEMLIB /system/toolbox ls -lZ /system/bin/toolbox | grep toolbox_exec > /dev/null; echo $?)" -eq "0" ]; then INSTALL_RECOVERY_CONTEXT=u:object_r:toolbox_exec:s0 fi fi if [ "$API" -ge "21" ]; then APPPROCESS=true fi if [ "$API" -ge "25" ]; then if [ "$API" -ge "26" ]; then # O retail PATCHDTB=true if [ "$BINDSBIN" = "detect" ]; then BINDSBIN=true fi elif (`cat /system/build.prop | grep preview_sdk | grep -v "0" >/dev/null`); then # O preview, to be removed PATCHDTB=true if [ "$BINDSBIN" = "detect" ]; then BINDSBIN=true fi fi fi if [ "$BINDSBIN" = "detect" ]; then BINDSBIN=false fi if [ "$API" -ge "24" ]; then INIT_SUPERSU_RC=init.supersu.rc.24 if (! $KEEPFORCEENCRYPT); then FBEBYPASS=true fi fi if ($BINDSBIN); then INIT_SUPERSU_RC=${INIT_SUPERSU_RC}.bindsbin fi fi if [ ! -f $MKSH ]; then MKSH=/system/bin/sh fi echo -----DBG----- echo "DBG [$API] [$ABI] [$ABI2] [$ABILONG] [$ARCH] [$ARCHTOOLS] [$MKSH]" set echo -----/DBG----- if [ -z "$BIN" ] || [ -z "$BINTOOLS" ]; then ui_print "- Extracting files" cd /tmp mkdir supersu cd supersu unzip -o "$ZIP" BIN=/tmp/supersu/$ARCH BINTOOLS=/tmp/supersu/$ARCHTOOLS COM=/tmp/supersu/common fi # execute binaries from ramdisk chmod -R 0755 $BIN/* chmod -R 0755 $BINTOOLS/* RAMDISKLIB=$BIN:$SYSTEMLIB RAMDISKLIBTOOLS=$BINTOOLS:$SYSTEMLIBTOOLS if [ "$API" -ge "19" ]; then # 4.4+: permissive all teh things LD_LIBRARY_PATH=$RAMDISKLIB $BIN/supolicy --live "permissive *" fi SAMSUNG=false MOTOROLA=false if [ "$API" -eq "$API" ]; then # detect brands if (cat /system/build.prop /default.prop 2>/dev/null | grep "ro.build.fingerprint=" | grep -i "samsung" >/dev/null); then SAMSUNG=true fi if (cat /system/build.prop /default.prop 2>/dev/null | grep "ro.build.fingerprint=" | grep -i "motorola" >/dev/null); then MOTOROLA=true fi # detect systemless if [ "$API" -ge "23" ]; then # 6.0+ DETECT_SYSTEMLESS_REQUIRED=true # Motorola # Stock Motorola firmwares have all the symptoms of firmwares # that should be able to work in system-mode, but in practise # it doesn't work - reason unknown. So system mode is not used # unless SYSTEMLESS=false is explicitly set. if ($MOTOROLA); then if [ "$SYSTEMLESS" = "detect" ]; then SYSTEMLESS=true DETECT_SYSTEMLESS_REQUIRED=false fi fi if ($DETECT_SYSTEMLESS_REQUIRED); then ui_print "- Detecting system compatibility" detect_systemless_required fi if ($SYSTEMLESS); then RWSYSTEM=false fi elif [ "$API" -ge "21" ]; then # 5.1/Samsung # On 5.0, auto-detect sets systemless only for 5.1/Samsung # But we allow SYSTEMLESS=true override for 3rd party mods # - that doesn't officially work, though! if [ "$SYSTEMLESS" = "detect" ]; then SYSTEMLESS=false if [ "$API" -ge "22" ]; then if ($SAMSUNG); then SYSTEMLESS=true fi fi fi # Pre-6.0/Other if ($SYSTEMLESS); then RWSYSTEM=false fi fi # detect REMOVEENCRYPTABLE if [ "$REMOVEENCRYPTABLE" = "detect" ]; then # Only set to true on Samsung/7.0+ without encryption REMOVEENCRYPTABLE=false if [ "$API" -ge "24" ]; then if ($SAMSUNG); then if (! $KEEPFORCEENCRYPT); then if (`mount | grep " /data " | grep -v "dm-" >/dev/null`); then # unencrypted /data on Samsung 7.0+ REMOVEENCRYPTABLE=true fi fi fi fi fi fi # Do not use SYSTEMLESS after this point, but refer to RWSYSTEM if ($RWSYSTEM); then ui_print "- System mode" remount_system_rw ui_print "- Disabling OTA survival" chmod 0755 $BINTOOLS/chattr$PIE LD_LIBRARY_PATH=$SYSTEMLIBTOOLS $BINTOOLS/chattr$PIE -ia /system/bin/su LD_LIBRARY_PATH=$SYSTEMLIBTOOLS $BINTOOLS/chattr$PIE -ia /system/xbin/su LD_LIBRARY_PATH=$SYSTEMLIBTOOLS $BINTOOLS/chattr$PIE -ia /system/bin/.ext/.su LD_LIBRARY_PATH=$SYSTEMLIBTOOLS $BINTOOLS/chattr$PIE -ia /system/sbin/su LD_LIBRARY_PATH=$SYSTEMLIBTOOLS $BINTOOLS/chattr$PIE -ia /vendor/sbin/su LD_LIBRARY_PATH=$SYSTEMLIBTOOLS $BINTOOLS/chattr$PIE -ia /vendor/bin/su LD_LIBRARY_PATH=$SYSTEMLIBTOOLS $BINTOOLS/chattr$PIE -ia /vendor/xbin/su LD_LIBRARY_PATH=$SYSTEMLIBTOOLS $BINTOOLS/chattr$PIE -ia /system/xbin/daemonsu LD_LIBRARY_PATH=$SYSTEMLIBTOOLS $BINTOOLS/chattr$PIE -ia /system/xbin/sugote LD_LIBRARY_PATH=$SYSTEMLIBTOOLS $BINTOOLS/chattr$PIE -ia /system/xbin/sugote_mksh LD_LIBRARY_PATH=$SYSTEMLIBTOOLS $BINTOOLS/chattr$PIE -ia /system/xbin/supolicy LD_LIBRARY_PATH=$SYSTEMLIBTOOLS $BINTOOLS/chattr$PIE -ia /system/xbin/ku.sud LD_LIBRARY_PATH=$SYSTEMLIBTOOLS $BINTOOLS/chattr$PIE -ia /system/xbin/.ku LD_LIBRARY_PATH=$SYSTEMLIBTOOLS $BINTOOLS/chattr$PIE -ia /system/xbin/.su LD_LIBRARY_PATH=$SYSTEMLIBTOOLS $BINTOOLS/chattr$PIE -ia /system/lib/libsupol.so LD_LIBRARY_PATH=$SYSTEMLIBTOOLS $BINTOOLS/chattr$PIE -ia /system/lib64/libsupol.so LD_LIBRARY_PATH=$SYSTEMLIBTOOLS $BINTOOLS/chattr$PIE -ia /system/etc/install-recovery.sh LD_LIBRARY_PATH=$SYSTEMLIBTOOLS $BINTOOLS/chattr$PIE -ia /system/bin/install-recovery.sh ui_print "- Removing old files" if [ -f "/system/bin/install-recovery.sh" ]; then if [ ! -f "/system/bin/install-recovery_original.sh" ]; then mv /system/bin/install-recovery.sh /system/bin/install-recovery_original.sh ch_con /system/bin/install-recovery_original.sh fi fi if [ -f "/system/etc/install-recovery.sh" ]; then if [ ! -f "/system/etc/install-recovery_original.sh" ]; then mv /system/etc/install-recovery.sh /system/etc/install-recovery_original.sh ch_con /system/etc/install-recovery_original.sh fi fi # only wipe these files in /system install, so not part of the wipe_ functions rm -f /system/bin/install-recovery.sh rm -f /system/etc/install-recovery.sh rm -f /system/bin/su rm -f /system/xbin/su rm -f /system/sbin/su rm -f /vendor/sbin/su rm -f /vendor/bin/su rm -f /vendor/xbin/su rm -rf /data/app/eu.chainfire.supersu-* rm -rf /data/app/eu.chainfire.supersu.apk wipe_system_files_if_present wipe_data_competitors_and_cache rm /data/su.img rm /cache/su.img ui_print "- Creating space" if ($APKFOLDER); then if [ -f "/system/app/Maps/Maps.apk" ]; then cp /system/app/Maps/Maps.apk /Maps.apk rm /system/app/Maps/Maps.apk fi if [ -f "/system/app/GMS_Maps/GMS_Maps.apk" ]; then cp /system/app/GMS_Maps/GMS_Maps.apk /GMS_Maps.apk rm /system/app/GMS_Maps/GMS_Maps.apk fi if [ -f "/system/app/YouTube/YouTube.apk" ]; then cp /system/app/YouTube/YouTube.apk /YouTube.apk rm /system/app/YouTube/YouTube.apk fi else if [ -f "/system/app/Maps.apk" ]; then cp /system/app/Maps.apk /Maps.apk rm /system/app/Maps.apk fi if [ -f "/system/app/GMS_Maps.apk" ]; then cp /system/app/GMS_Maps.apk /GMS_Maps.apk rm /system/app/GMS_Maps.apk fi if [ -f "/system/app/YouTube.apk" ]; then cp /system/app/YouTube.apk /YouTube.apk rm /system/app/YouTube.apk fi fi ui_print "- Placing files" mkdir /system/bin/.ext set_perm 0 0 0777 /system/bin/.ext cp_perm 0 0 $SUMOD $BIN/$SU /system/bin/.ext/.su cp_perm 0 0 $SUMOD $BIN/$SU /system/xbin/su cp_perm 0 0 0755 $BIN/$SU /system/xbin/daemonsu if ($SUPOLICY); then cp_perm 0 0 0755 $BIN/supolicy /system/xbin/supolicy cp_perm 0 0 0644 $BIN/libsupol.so $SYSTEMLIBPATH/libsupol.so fi if ($APKFOLDER); then mkdir /system/app/SuperSU set_perm 0 0 0755 /system/app/SuperSU fi cp_perm 0 0 0644 $COM/Superuser.apk $APKNAME cp_perm 0 0 0755 $COM/install-recovery.sh /system/etc/install-recovery.sh ln_con /system/etc/install-recovery.sh /system/bin/install-recovery.sh if ($APPPROCESS); then rm /system/bin/app_process ln_con /system/xbin/daemonsu /system/bin/app_process if ($APPPROCESS64); then if [ ! -f "/system/bin/app_process64_original" ]; then mv /system/bin/app_process64 /system/bin/app_process64_original else rm /system/bin/app_process64 fi ln_con /system/xbin/daemonsu /system/bin/app_process64 if [ ! -f "/system/bin/app_process_init" ]; then cp_perm 0 2000 0755 /system/bin/app_process64_original /system/bin/app_process_init fi else if [ ! -f "/system/bin/app_process32_original" ]; then mv /system/bin/app_process32 /system/bin/app_process32_original else rm /system/bin/app_process32 fi ln_con /system/xbin/daemonsu /system/bin/app_process32 if [ ! -f "/system/bin/app_process_init" ]; then cp_perm 0 2000 0755 /system/bin/app_process32_original /system/bin/app_process_init fi fi fi cp_perm 0 0 0744 $COM/99SuperSUDaemon /system/etc/init.d/99SuperSUDaemon echo 1 > /system/etc/.installed_su_daemon set_perm 0 0 0644 /system/etc/.installed_su_daemon ui_print "- Restoring files" if ($APKFOLDER); then if [ -f "/Maps.apk" ]; then cp_perm 0 0 0644 /Maps.apk /system/app/Maps/Maps.apk rm /Maps.apk fi if [ -f "/GMS_Maps.apk" ]; then cp_perm 0 0 0644 /GMS_Maps.apk /system/app/GMS_Maps/GMS_Maps.apk rm /GMS_Maps.apk fi if [ -f "/YouTube.apk" ]; then cp_perm 0 0 0644 /YouTube.apk /system/app/YouTube/YouTube.apk rm /YouTube.apk fi else if [ -f "/Maps.apk" ]; then cp_perm 0 0 0644 /Maps.apk /system/app/Maps.apk rm /Maps.apk fi if [ -f "/GMS_Maps.apk" ]; then cp_perm 0 0 0644 /GMS_Maps.apk /system/app/GMS_Maps.apk rm /GMS_Maps.apk fi if [ -f "/YouTube.apk" ]; then cp_perm 0 0 0644 /YouTube.apk /system/app/YouTube.apk rm /YouTube.apk fi fi ui_print "- Post-installation script" rm /system/toybox rm /system/toolbox LD_LIBRARY_PATH=$SYSTEMLIB /system/xbin/su --install else ui_print "- System-less mode, boot image support required" SUIMG=/data/su.img NOIMG=/data/supersu_install HAVEDATA=true if (! is_mounted /data); then SUIMG=/cache/su.img NOIMG=/cache/supersu_install HAVEDATA=false fi if (! $BINDSBIN); then mkdir /su ui_print "- Creating image" MOUNTPOINT=/su # we want a 96M image, for SuperSU files and potential mods such as systemless xposed # attempt smaller sizes on failure, and hope the launch_daemonsu.sh script succeeds # in resizing to 96M later for SUIMGSIZE in 96M 64M 32M 16M; do if [ ! -f "$SUIMG" ]; then make_ext4fs -l $SUIMGSIZE -a $MOUNTPOINT -S $COM/file_contexts_image $SUIMG; fi if [ ! -f "$SUIMG" ]; then LD_LIBRARY_PATH=$SYSTEMLIB /system/bin/make_ext4fs -l $SUIMGSIZE -a $MOUNTPOINT -S $COM/file_contexts_image $SUIMG; fi set_perm 0 0 0600 /data/su.img u:object_r:system_data_file:s0 done if [ -f "$SUIMG" ]; then LD_LIBRARY_PATH=$SYSTEMLIB /system/bin/e2fsck -p -f $SUIMG fi ui_print "- Mounting image" # 'losetup -f' is unreliable across devices/recoveries LOOPDEVICE= for LOOP in 0 1 2 3 4 5 6 7; do if (! is_mounted /su); then LOOPDEVICE=/dev/block/loop$LOOP HAVE_LOOPDEVICE=false if [ -f "$LOOPDEVICE" ]; then HAVE_LOOPDEVICE=true elif [ -b "$LOOPDEVICE" ]; then HAVE_LOOPDEVICE=true; fi if (! $HAVE_LOOPDEVICE); then mknod $LOOPDEVICE b 7 $LOOP fi losetup $LOOPDEVICE $SUIMG if [ "$?" -eq "0" ]; then mount -t ext4 -o loop $LOOPDEVICE /su if (! is_mounted /su); then /system/bin/toolbox mount -t ext4 -o loop $LOOPDEVICE /su fi if (! is_mounted /su); then /system/bin/toybox mount -t ext4 -o loop $LOOPDEVICE /su fi fi if (is_mounted /su); then break; fi fi done else mkdir -p $NOIMG if [ -d "/su" ]; then mv /su /su.old fi ln -s $NOIMG /su fi ui_print "- Creating paths" ch_con /su mkdir /su/bin set_perm 0 0 0751 /su/bin mkdir /su/xbin set_perm 0 0 0755 /su/xbin mkdir /su/lib set_perm 0 0 0755 /su/lib mkdir /su/etc set_perm 0 0 0755 /su/etc mkdir /su/su.d set_perm 0 0 0700 /su/su.d ui_print "- Removing old files" wipe_system_files_if_present wipe_data_competitors_and_cache rm -rf /su/bin/app_process rm -rf /su/bin/sush rm -rf /su/bin/daemonsu rm -rf /su/bin/daemonsu_* rm -rf /su/bin/su rm -rf /su/bin/su_* rm -rf /su/bin/supolicy rm -rf /su/bin/supolicy_* rm -rf /su/lib/libsupol.so rm -rf /su/lib/libsupol_* rm -rf /su/bin/sukernel ui_print "- Placing files" # Copy binaries and utilities cp_perm 0 0 0755 $BIN/$SU /su/bin/su cp_perm 0 0 0755 $BIN/$SU /su/bin/daemonsu ln_con su /su/bin/supolicy cp_perm 0 0 0755 $BIN/supolicy /su/bin/supolicy_wrapped cp_perm 0 0 0644 $BIN/libsupol.so /su/lib/libsupol.so cp_perm 0 0 0755 $BIN/sukernel /su/bin/sukernel cp_perm 0 0 0644 $COM/file_contexts /su/file_contexts cp_perm 0 0 0644 $COM/supersu_is_here /su/supersu_is_here # Copy APK, installation is done by /sbin/launch_daemonsu.sh if ($HAVEDATA); then cp_perm 1000 1000 0600 $COM/Superuser.apk /data/SuperSU.apk # Wipe /data/security to prevent SELinux policy override # Important to keep the folder itself rm -rf /data/security/* else cp_perm 1000 1000 0600 $COM/Superuser.apk /cache/SuperSU.apk fi # Fix Samsung deep sleep issue. Affects enough millions of users to include. if ($SAMSUNG); then cp_perm 0 0 0700 $COM/000000deepsleep /su/su.d/000000deepsleep fi # Enable poor man's overlay on /system/xbin if ($BINDSYSTEMXBIN); then mkdir /su/xbin_bind set_perm 0 0 0755 /su/xbin_bind else rm -rf /su/xbin_bind fi if ($PATCHBOOTIMAGE); then ui_print " " ui_print "******************" ui_print_always "Boot image patcher" ui_print "******************" ui_print "- Finding boot image" find_boot_image CONTINUE=true if [ -z "$BOOTIMAGE" ]; then ui_print_less "$UI_PRINT_LAST" ui_print_always "--- Boot image: not found, aborting" CONTINUE=false else ui_print "--- Boot image: $BOOTIMAGE" fi if [ -z "$STOCKBOOTIMAGE" ]; then STOCKBOOTIMAGE=$BOOTIMAGE fi rm -rf /sutmp mkdir /sutmp check_zero_def "- Extracting ramdisk" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --bootimg-extract-ramdisk $BOOTIMAGE /sutmp/ramdisk.packed" decompress_check "- Decompressing ramdisk" "/sutmp/ramdisk.packed" "/sutmp/ramdisk" RAMDISK_COMPRESSION=$COMPRESSION if ($CONTINUE); then ui_print "- Checking patch status" LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --patch-test /sutmp/ramdisk if [ $? -ne 0 ]; then ui_print "--- Already patched, attempting to find stock backup" if ($CONTINUE); then LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --restore /sutmp/ramdisk /sutmp/stock_boot.img if [ $? -ne 0 ]; then ui_print_always "--- Stock restore failed, attempting ramdisk restore" CONTINUE=false else ui_print "--- Stock backup restored" STOCKBOOTIMAGE=/sutmp/stock_boot.img fi fi check_zero_def "- Extracting ramdisk" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --bootimg-extract-ramdisk /sutmp/stock_boot.img /sutmp/ramdisk.packed" decompress_check "- Decompressing ramdisk" "/sutmp/ramdisk.packed" "/sutmp/ramdisk" RAMDISK_COMPRESSION=$COMPRESSION check_zero "- Checking patch status" "" "--- Already patched, attempting ramdisk restore" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --patch-test /sutmp/ramdisk" if (! $CONTINUE); then LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-restore /sutmp/ramdisk /sutmp/ramdisk if [ $? -ne 0 ]; then ui_print_always "--- Ramdisk restore failed, aborting" else ui_print "--- Ramdisk backup restored (OTA impossible)" CONTINUE=true fi check_zero "- Checking patch status" "" "--- Already patched, aborting" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --patch-test /sutmp/ramdisk" fi else ui_print "- Creating backup" rm /data/stock_boot_*.img rm /data/stock_boot_*.img.gz rm /cache/stock_boot_*.img rm /cache/stock_boot_*.img.gz LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --backup $STOCKBOOTIMAGE if [ $? -ne 0 ]; then ui_print "--- Backup failed" fi fi fi if ($CONTINUE); then IMAGETYPE=android LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --bootimg-type $STOCKBOOTIMAGE if [ $? -eq 2 ]; then IMAGETYPE=chromeos fi AVB_SIGNED=false if [ "$IMAGETYPE" = "android" ]; then ui_print "- Checking signature" detect_avb $STOCKBOOTIMAGE if ($AVB_SIGNED); then ui_print "--- Signed" else ui_print "--- Unsigned" fi fi if [ "$SIGNBOOTIMAGE" = "detect" ]; then SIGNBOOTIMAGE=$AVB_SIGNED fi if [ "$IMAGETYPE" = "chromeos" ]; then $BIN/chromeos/futility vbutil_kernel --get-vmlinuz $STOCKBOOTIMAGE --vmlinuz-out /sutmp/boot.chromeos.img STOCKBOOTIMAGE=/sutmp/boot.chromeos.img fi dd if=$STOCKBOOTIMAGE of=/sutmp/boot.img bs=4096 fi if ($CONTINUE); then cp_perm 0 0 0644 /sutmp/ramdisk /sutmp/ramdisk.original if ($SYSTEM_ROOT_USED); then check_zero_def "- Importing system_root" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-import-system-root /sutmp/ramdisk /sutmp/ramdisk" fi fi if ($CONTINUE); then if ($PATCHDTB); then ui_print "- Extracting dtb (if any)" LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --bootimg-extract-dtb $STOCKBOOTIMAGE /sutmp/dtb if [ -f "/sutmp/dtb" ]; then if (! $KEEPVERITY); then mkdir /sutmp/dtb_parts check_zero_def "- Splitting dtb into parts" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --dtb-split /sutmp/dtb /sutmp/dtb_parts" if ($CONTINUE); then ui_print "- Patching dtb fstab in each part" for i in `ls /sutmp/dtb_parts/`; do check_zero_def "" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --dtb-patch-fstab /sutmp/dtb_parts/$i /sutmp/dtb_parts/$i" if (! $CONTINUE); then break fi done fi check_zero_def "- Merging dtb from parts" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --dtb-merge /sutmp/dtb_parts /sutmp/dtb" check_zero_def "- Replacing dtb" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --bootimg-replace-dtb /sutmp/boot.img /sutmp/dtb /sutmp/boot.img" else ui_print "(KEEPVERITY) /system: verity disabled (TODO)" ui_print "(KEEPVERITY) /vendor and /odm: verity enabled" fi fi fi fi if ($CONTINUE); then ui_print "- Patching sepolicy" LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-extract /sutmp/ramdisk ${CPIO_PREFIX}sepolicy /sutmp/sepolicy if [ ! -f "/sutmp/sepolicy" ]; then if [ -f "/system/bin/secilc" ]; then PLAT_CIL="/system/etc/selinux/plat_sepolicy.cil" MAPPING_CIL=$(find /system/etc/selinux | grep mapping | grep -m 1 "\.cil$") NONPLAT_CIL="/vendor/etc/selinux/nonplat_sepolicy.cil" POLICY_VERSION=$(cat /sys/fs/selinux/policyvers) if [ -f "$PLAT_CIL" ] && [ ! -z "$MAPPING_CIL" ] && [ -f "$MAPPING_CIL" ] && [ -f "$NONPLAT_CIL" ] && [ ! -z "$POLICY_VERSION" ]; then # compile split sepolicy to singular LD_LIBRARY_PATH=$SYSTEMLIB /system/bin/secilc "$PLAT_CIL" -M true -c "$POLICY_VERSION" "$MAPPING_CIL" "$NONPLAT_CIL" -o /sutmp/sepolicy -f /dev/null # patch init check_zero_def "" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-extract /sutmp/ramdisk ${CPIO_PREFIX}init /sutmp/init" if ($CONTINUE); then sed -i 's/\/system\/etc\/selinux\/plat_sepolicy.cil/\/system\/etc\/selinux\/plat_sepolicy.xxx/g' /sutmp/init fi check_zero_def "" "LD_LIBRARY_PATH=$RAMDISKLIB $BIN/sukernel --cpio-add /sutmp/ramdisk /sutmp/ramdisk 0750 ${CPIO_PREFIX}init /sutmp/init" fi fi fi if ($CONTINUE); then if [ -f "/sutmp/sepolicy" ]; then LD_LIBRARY_PATH=$RAMDISKLIB $BIN/supolicy --file /sutmp/sepolicy /sutmp/sepolicy.patched --sdk=$API if ($PERMISSIVE); then rm /sutmp/supolicy.tmp mv /sutmp/sepolicy.patched /sutmp/sepolicy.tmp LD_LIBRARY_PATH=$RAMDISKLIB $BIN/supolicy --file /sutmp/sepolicy.tmp /sutmp/sepolicy.patched "permissive *" fi fi if ($BINDSBIN); then if [ -f "/sutmp/sepolicy.patched" ]; then rm /sutmp/supolicy.tmp mv /sutmp/sepolicy.patched /sutmp/sepolicy.tmp LD_LIBRARY_PATH=$RAMDISKLIB $BIN/supolicy --file /sutmp/sepolicy.tmp /sutmp/sepolicy.patched "create supersu_prop" "attradd supersu_prop property_type" fi LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-extract /sutmp/ramdisk ${CPIO_PREFIX}property_contexts /sutmp/property_contexts LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-extract /sutmp/ramdisk ${CPIO_PREFIX}plat_property_contexts /sutmp/plat_property_contexts PROPERTY_CONTEXTS= if [ -f "/sutmp/property_contexts" ]; then PROPERTY_CONTEXTS=property_contexts fi if [ -f "/sutmp/plat_property_contexts" ]; then PROPERTY_CONTEXTS=plat_property_contexts fi if [ ! -z "$PROPERTY_CONTEXTS" ]; then echo "init.svc.daemonsu u:object_r:supersu_prop:s0" >> /sutmp/$PROPERTY_CONTEXTS echo "ro.boottime.daemonsu u:object_r:supersu_prop:s0" >> /sutmp/$PROPERTY_CONTEXTS echo "sukernel.daemonsu.launch u:object_r:supersu_prop:s0" >> /sutmp/$PROPERTY_CONTEXTS echo "supolicy.loaded u:object_r:supersu_prop:s0" >> /sutmp/$PROPERTY_CONTEXTS LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-add /sutmp/ramdisk /sutmp/ramdisk 644 ${CPIO_PREFIX}$PROPERTY_CONTEXTS /sutmp/$PROPERTY_CONTEXTS fi fi if [ ! -f "/sutmp/sepolicy.patched" ]; then ui_print_less "$UI_PRINT_LAST" ui_print_always "--- Failure, aborting" CONTINUE=false fi fi check_zero_def "" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-add /sutmp/ramdisk /sutmp/ramdisk 644 ${CPIO_PREFIX}sepolicy /sutmp/sepolicy.patched" if ($CONTINUE); then if [ ! -z "${CPIO_PREFIX}" ]; then rm /sutmp/sepolicy rm /sutmp/sepolicy.tmp rm /sutmp/sepolicy.patched LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-extract /sutmp/ramdisk sepolicy /sutmp/sepolicy if [ -f "/sutmp/sepolicy" ]; then ui_print "- Patching sepolicy (recovery)" LD_LIBRARY_PATH=$RAMDISKLIB $BIN/supolicy --file /sutmp/sepolicy /sutmp/sepolicy.patched --sdk=$API if ($PERMISSIVE); then rm /sutmp/supolicy.tmp mv /sutmp/sepolicy.patched /sutmp/sepolicy.tmp LD_LIBRARY_PATH=$RAMDISKLIB $BIN/supolicy --file /sutmp/sepolicy.tmp /sutmp/sepolicy.patched "permissive *" fi check_zero_def "" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-add /sutmp/ramdisk /sutmp/ramdisk 644 sepolicy /sutmp/sepolicy.patched" fi fi fi fi check_zero_def "- Adding daemon launcher" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-add /sutmp/ramdisk /sutmp/ramdisk 700 ${CPIO_PREFIX}sbin/launch_daemonsu.sh $COM/launch_daemonsu.sh" if ($FBEBYPASS); then check_zero_def "- Adding FBE bypass" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-add /sutmp/ramdisk /sutmp/ramdisk 700 ${CPIO_PREFIX}sbin/fbe_bypass.sh $COM/fbe_bypass.sh" fi check_zero_def "- Adding init script" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-add /sutmp/ramdisk /sutmp/ramdisk 750 ${CPIO_PREFIX}init.supersu.rc $COM/$INIT_SUPERSU_RC" if (! $BINDSBIN); then check_zero_def "- Creating mount point" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-mkdir /sutmp/ramdisk /sutmp/ramdisk 755 ${CPIO_PREFIX}su" fi COMMAND="LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --patch /sutmp/ramdisk /sutmp/ramdisk $STOCKBOOTIMAGE" if ($KEEPVERITY); then COMMAND="$COMMAND --keep-verity" fi if ($KEEPFORCEENCRYPT); then COMMAND="$COMMAND --keep-forceencrypt" fi if ($REMOVEENCRYPTABLE); then COMMAND="$COMMAND --remove-encryptable" fi if ($BINDSBIN); then COMMAND="$COMMAND --sbin" fi check_zero_def "- Patching init.*.rc, fstabs, dm-verity" "$COMMAND" if ($CONTINUE); then if ($SYSTEM_ROOT_USED); then ui_print "- Patching init, system_root, system" check_zero_def "" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-add /sutmp/ramdisk /sutmp/ramdisk 750 init $BIN/suinit" check_zero_def "" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-mkdir /sutmp/ramdisk /sutmp/ramdisk 755 boot/system_root" check_zero_def "" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-mkdir /sutmp/ramdisk /sutmp/ramdisk 755 boot/system" if (! $CONTINUE); then ui_print_less "$UI_PRINT_LAST" ui_print_always "--- Failure, aborting" fi fi fi if ($CONTINUE); then if [ -f "/data/custom_ramdisk_patch.sh" ]; then check_zero_def "- Calling user ramdisk patch script" "sh /data/custom_ramdisk_patch.sh /sutmp/ramdisk" fi fi if ($CONTINUE); then if ($SYSTEM_ROOT_USED); then check_zero_def "- Reducing system_root footprint" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-reduce-system-root /sutmp/ramdisk /sutmp/ramdisk" fi fi if ($CONTINUE); then if ($FRP); then ui_print "- Factory reset protection" date >/sutmp/frp_date check_zero_def "" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-mkdir /sutmp/ramdisk /sutmp/ramdisk 0 ${CPIO_PREFIX}.sufrp" check_zero_def "" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-add /sutmp/ramdisk /sutmp/ramdisk 644 ${CPIO_PREFIX}.sufrp/frp_date /sutmp/frp_date" check_zero_def "" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-add /sutmp/ramdisk /sutmp/ramdisk 755 ${CPIO_PREFIX}.sufrp/frp_install $COM/frp_install" check_zero_def "" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-add /sutmp/ramdisk /sutmp/ramdisk 644 ${CPIO_PREFIX}.sufrp/file_contexts_image $COM/file_contexts_image" check_zero_def "" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-add /sutmp/ramdisk /sutmp/ramdisk 644 ${CPIO_PREFIX}.sufrp/su $BIN/su" check_zero_def "" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-add /sutmp/ramdisk /sutmp/ramdisk 644 ${CPIO_PREFIX}.sufrp/sukernel $BIN/sukernel" check_zero_def "" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-add /sutmp/ramdisk /sutmp/ramdisk 644 ${CPIO_PREFIX}.sufrp/supolicy $BIN/supolicy" check_zero_def "" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-add /sutmp/ramdisk /sutmp/ramdisk 644 ${CPIO_PREFIX}.sufrp/libsupol.so $BIN/libsupol.so" check_zero_def "" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-add /sutmp/ramdisk /sutmp/ramdisk 644 ${CPIO_PREFIX}.sufrp/file_contexts $COM/file_contexts" check_zero_def "" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-add /sutmp/ramdisk /sutmp/ramdisk 644 ${CPIO_PREFIX}.sufrp/supersu_is_here $COM/supersu_is_here" fi fi check_zero_def "- Creating ramdisk backup" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --cpio-backup /sutmp/ramdisk.original /sutmp/ramdisk /sutmp/ramdisk" compress_check "- Compressing ramdisk" "$RAMDISK_COMPRESSION" "/sutmp/ramdisk" "/sutmp/ramdisk.packed" check_zero_def "- Creating boot image" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --bootimg-replace-ramdisk /sutmp/boot.img /sutmp/ramdisk.packed /sutmp/boot.img" if ($SYSTEM_ROOT_USED); then check_zero_def "- Extracting kernel" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --bootimg-extract-kernel $STOCKBOOTIMAGE /sutmp/kernel" decompress_check "- Decompressing kernel" "/sutmp/kernel" "/sutmp/kernel.d" KERNEL_COMPRESSION=$COMPRESSION check_zero_def "- Patching kernel" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --patch-slot-kernel /sutmp/kernel.d /sutmp/kernel.d" compress_check "- Compressing kernel" "$KERNEL_COMPRESSION" "/sutmp/kernel.d" "/sutmp/kernel" check_zero_def "- Replacing kernel" "LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --bootimg-replace-kernel /sutmp/boot.img /sutmp/kernel /sutmp/boot.img" fi if ($CONTINUE); then # might return 1 even if we do not want to abort ui_print "- Applying hex patches" LD_LIBRARY_PATH=$SYSTEMLIB /su/bin/sukernel --hexpatch $COM/hexpatch /sutmp/boot.img /sutmp/boot.img fi if ($CONTINUE); then if [ -f "/data/custom_boot_image_patch.sh" ]; then check_zero_def "- Calling user boot image patch script" "sh /data/custom_boot_image_patch.sh /sutmp/boot.img" fi fi if ($CONTINUE); then if [ "$IMAGETYPE" = "chromeos" ]; then ui_print "- Signing boot image" $BIN/chromeos/futility vbutil_kernel --pack /sutmp/boot.img.signed --keyblock $COM/chromeos/kernel.keyblock --signprivate $COM/chromeos/kernel_data_key.vbprivk --version 1 --vmlinuz /sutmp/boot.img --config $COM/chromeos/kernel.config --arch arm --bootloader $COM/chromeos/kernel.bootloader --flags 0x1 if [ -f "/sutmp/boot.img.signed" ]; then rm -rf /sutmp/boot.img mv /sutmp/boot.img.signed /sutmp/boot.img else ui_print_less "$UI_PRINT_LAST" ui_print_always "--- Failure, aborting" CONTINUE=false fi elif [ "$IMAGETYPE" = "android" ]; then if ($SIGNBOOTIMAGE); then ui_print "- Signing boot image" sign_avb /sutmp/boot.img /sutmp/boot.img.signed OK=false if [ -f "/sutmp/boot.img.signed" ]; then rm -rf /sutmp/boot.img mv /sutmp/boot.img.signed /sutmp/boot.img if ($AVB_SIGNED); then OK=true fi fi if (! $OK); then ui_print_less "$UI_PRINT_LAST" ui_print_always "--- Failure, aborting" CONTINUE=false fi fi fi fi if ($CONTINUE); then if ($SAMSUNG); then # Prevent "KERNEL IS NOT SEANDROID ENFORCING" SAMSUNG_CHECK=$(cat /sutmp/boot.img | grep SEANDROIDENFORCE) if [ $? -ne 0 ]; then echo -n "SEANDROIDENFORCE" >> /sutmp/boot.img fi fi DEV=$(echo `resolve_link $BOOTIMAGE` | grep /dev/block/) if [ $? -eq 0 ]; then ui_print "- Flashing boot image" cat /sutmp/boot.img /dev/zero | dd of=$BOOTIMAGE bs=4096 else ui_print "- Saving boot image" dd if=/sutmp/boot.img of=$BOOTIMAGE bs=4096 fi fi rm -rf /sutmp fi umount /su losetup -d $LOOPDEVICE ui_print " " if ($CONTINUE); then ui_print "*************************" ui_print " IMPORTANT NOTICES " ui_print "*************************" TWRP2=$(cat /tmp/recovery.log | grep "ro.twrp.version=2"); if [ $? -eq 0 ]; then ui_print "If TWRP offers to install" ui_print "SuperSU, do *NOT* let it!" ui_print "*************************" fi ui_print "First reboot may take a " ui_print "few minutes. It can also " ui_print "loop a few times. Do not " ui_print "interrupt the process! " ui_print "*************************" ui_print " " fi if (! $LESSLOGGING); then sleep 5 fi fi ui_print "- Unmounting /system and /vendor" if ($SYSTEM_ROOT_USED); then if (! $HAD_SYSTEM_ROOT); then if (! `umount /system`); then umount -l /system fi if (! `umount /system_root`); then umount -l /system_root fi if ($HAD_SYSTEM); then if ($HAD_SYSTEM_RW); then mount -o rw /system else mount -o ro /system fi fi fi else if (! $HAD_SYSTEM); then if (! `umount /system`); then umount -l /system fi fi fi if (! $HAD_VENDOR); then if (! `umount /vendor`); then umount -l /vendor fi fi if [ -d "/su.old" ]; then rm /su mv /su.old /su fi # revert RNG fix umount /dev/random ui_print_always "- Done !" exit 0