Commit bec5edca authored by topjohnwu's avatar topjohnwu

Avoiding using shell I/O

parent 6fb20b3e
...@@ -10,8 +10,9 @@ import androidx.multidex.MultiDex ...@@ -10,8 +10,9 @@ import androidx.multidex.MultiDex
import androidx.work.WorkManager import androidx.work.WorkManager
import com.topjohnwu.magisk.BuildConfig import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.DynAPK import com.topjohnwu.magisk.DynAPK
import com.topjohnwu.magisk.core.utils.AppShellInit
import com.topjohnwu.magisk.core.utils.BusyBoxInit
import com.topjohnwu.magisk.core.utils.IODispatcherExecutor import com.topjohnwu.magisk.core.utils.IODispatcherExecutor
import com.topjohnwu.magisk.core.utils.RootInit
import com.topjohnwu.magisk.core.utils.updateConfig import com.topjohnwu.magisk.core.utils.updateConfig
import com.topjohnwu.magisk.di.koinModules import com.topjohnwu.magisk.di.koinModules
import com.topjohnwu.magisk.ktx.unwrap import com.topjohnwu.magisk.ktx.unwrap
...@@ -32,7 +33,7 @@ open class App() : Application() { ...@@ -32,7 +33,7 @@ open class App() : Application() {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true) AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
Shell.setDefaultBuilder(Shell.Builder.create() Shell.setDefaultBuilder(Shell.Builder.create()
.setFlags(Shell.FLAG_MOUNT_MASTER) .setFlags(Shell.FLAG_MOUNT_MASTER)
.setInitializers(RootInit::class.java) .setInitializers(BusyBoxInit::class.java, AppShellInit::class.java)
.setTimeout(2)) .setTimeout(2))
Shell.EXECUTOR = IODispatcherExecutor() Shell.EXECUTOR = IODispatcherExecutor()
......
package com.topjohnwu.magisk.core package com.topjohnwu.magisk.core
import android.os.Build
import androidx.databinding.ObservableBoolean import androidx.databinding.ObservableBoolean
import com.topjohnwu.magisk.DynAPK import com.topjohnwu.magisk.DynAPK
import com.topjohnwu.magisk.core.model.UpdateInfo import com.topjohnwu.magisk.core.model.UpdateInfo
...@@ -34,9 +35,10 @@ object Info { ...@@ -34,9 +35,10 @@ object Info {
@JvmStatic val isFDE get() = crypto == "block" @JvmStatic val isFDE get() = crypto == "block"
@JvmField var ramdisk = false @JvmField var ramdisk = false
@JvmField var hasGMS = true @JvmField var hasGMS = true
@JvmField var isPixel = false @JvmField val isPixel = Build.BRAND == "google"
@JvmField val isEmulator = getProperty("ro.kernel.qemu", "0") == "1" @JvmField val isEmulator = getProperty("ro.kernel.qemu", "0") == "1"
var crypto = "" var crypto = ""
var noDataExec = false
val isConnected by lazy { val isConnected by lazy {
ObservableBoolean(false).also { field -> ObservableBoolean(false).also { field ->
......
...@@ -14,20 +14,19 @@ import com.topjohnwu.superuser.ShellUtils ...@@ -14,20 +14,19 @@ import com.topjohnwu.superuser.ShellUtils
import java.io.File import java.io.File
import java.util.jar.JarFile import java.util.jar.JarFile
class RootInit : Shell.Initializer() { abstract class BaseShellInit : Shell.Initializer() {
final override fun onInit(context: Context, shell: Shell): Boolean {
override fun onInit(context: Context, shell: Shell): Boolean {
return init(context.wrap(), shell) return init(context.wrap(), shell)
} }
private fun init(context: Context, shell: Shell): Boolean { abstract fun init(context: Context, shell: Shell): Boolean
}
fun fastCmd(cmd: String) = ShellUtils.fastCmd(shell, cmd)
fun getVar(name: String) = fastCmd("echo \$$name")
fun getBool(name: String) = getVar(name).toBoolean()
class BusyBoxInit : BaseShellInit() {
override fun init(context: Context, shell: Shell): Boolean {
shell.newJob().apply { shell.newJob().apply {
add("export SDK_INT=${Build.VERSION.SDK_INT}")
add("export ASH_STANDALONE=1") add("export ASH_STANDALONE=1")
val localBB: File val localBB: File
...@@ -41,27 +40,58 @@ class RootInit : Shell.Initializer() { ...@@ -41,27 +40,58 @@ class RootInit : Shell.Initializer() {
localBB = File(Const.NATIVE_LIB_DIR, "libbusybox.so") localBB = File(Const.NATIVE_LIB_DIR, "libbusybox.so")
} }
if (!shell.isRoot) { if (shell.isRoot) {
// Directly execute the file add("export MAGISKTMP=\$(magisk --path)/.magisk")
add("exec $localBB sh") // Test if we can properly execute stuff in /data
} else { Info.noDataExec = !shell.newJob().add("$localBB true").exec().isSuccess
// Copy it out of /data to workaround Samsung BS }
if (Info.noDataExec) {
// Copy it out of /data to workaround Samsung bullshit
add( add(
"export MAGISKTMP=\$(magisk --path)/.magisk",
"if [ -x \$MAGISKTMP/busybox/busybox ]; then", "if [ -x \$MAGISKTMP/busybox/busybox ]; then",
" cp -af $localBB \$MAGISKTMP/busybox/busybox", " cp -af $localBB \$MAGISKTMP/busybox/busybox",
" exec \$MAGISKTMP/busybox/busybox sh", " exec \$MAGISKTMP/busybox/busybox sh",
"else", "else",
" exec $localBB sh", " cp -af $localBB /dev/.busybox",
" exec /dev/.busybox sh",
"fi" "fi"
) )
} else {
// Directly execute the file
add("exec $localBB sh")
}
}.exec()
return true
} }
}
class LightShellInit : BaseShellInit() {
override fun init(context: Context, shell: Shell): Boolean {
shell.newJob().apply {
add("export SDK_INT=${Build.VERSION.SDK_INT}")
add(context.rawResource(R.raw.manager))
}.exec()
return true
}
}
class AppShellInit : BaseShellInit() {
override fun init(context: Context, shell: Shell): Boolean {
fun fastCmd(cmd: String) = ShellUtils.fastCmd(shell, cmd)
fun getVar(name: String) = fastCmd("echo \$$name")
fun getBool(name: String) = getVar(name).toBoolean()
shell.newJob().apply {
add("export SDK_INT=${Build.VERSION.SDK_INT}")
add(context.rawResource(R.raw.manager)) add(context.rawResource(R.raw.manager))
if (shell.isRoot) { if (shell.isRoot) {
add(context.assets.open("util_functions.sh")) add(context.assets.open("util_functions.sh"))
} }
add("mm_init") add("app_init")
}.exec() }.exec()
Const.MAGISKTMP = getVar("MAGISKTMP") Const.MAGISKTMP = getVar("MAGISKTMP")
...@@ -69,7 +99,6 @@ class RootInit : Shell.Initializer() { ...@@ -69,7 +99,6 @@ class RootInit : Shell.Initializer() {
Info.ramdisk = getBool("RAMDISKEXIST") Info.ramdisk = getBool("RAMDISKEXIST")
Info.isAB = getBool("ISAB") Info.isAB = getBool("ISAB")
Info.crypto = getVar("CRYPTOTYPE") Info.crypto = getVar("CRYPTOTYPE")
Info.isPixel = fastCmd("getprop ro.product.brand") == "google"
// Default presets // Default presets
Config.recovery = getBool("RECOVERYMODE") Config.recovery = getBool("RECOVERYMODE")
......
...@@ -36,7 +36,7 @@ fix_env() { ...@@ -36,7 +36,7 @@ fix_env() {
rm -rf $MAGISKBIN/* rm -rf $MAGISKBIN/*
mkdir -p $MAGISKBIN 2>/dev/null mkdir -p $MAGISKBIN 2>/dev/null
chmod 700 $NVBASE chmod 700 $NVBASE
cp -af $1/. $MAGISKBIN cp_readlink $1 $MAGISKBIN
rm -rf $1 rm -rf $1
chown -R 0:0 $MAGISKBIN chown -R 0:0 $MAGISKBIN
} }
...@@ -57,6 +57,8 @@ direct_install() { ...@@ -57,6 +57,8 @@ direct_install() {
rm -f $1/new-boot.img rm -f $1/new-boot.img
fix_env $1 fix_env $1
run_migrations
copy_sepolicy_rules
return 0 return 0
} }
...@@ -87,15 +89,17 @@ restore_imgs() { ...@@ -87,15 +89,17 @@ restore_imgs() {
} }
post_ota() { post_ota() {
cd $1 cd /data/adb
cp -f $1 bootctl
rm -f $1
chmod 755 bootctl chmod 755 bootctl
./bootctl hal-info || return ./bootctl hal-info || return
[ $(./bootctl get-current-slot) -eq 0 ] && SLOT_NUM=1 || SLOT_NUM=0 [ $(./bootctl get-current-slot) -eq 0 ] && SLOT_NUM=1 || SLOT_NUM=0
./bootctl set-active-boot-slot $SLOT_NUM ./bootctl set-active-boot-slot $SLOT_NUM
cat << EOF > post-fs-data.d/post_ota.sh cat << EOF > post-fs-data.d/post_ota.sh
${1}/bootctl mark-boot-successful /data/adb/bootctl mark-boot-successful
rm -f ${1}/bootctl rm -f /data/adb/bootctl
rm -f ${1}/post-fs-data.d/post_ota.sh rm -f /data/adb/post-fs-data.d/post_ota.sh
EOF EOF
chmod 755 post-fs-data.d/post_ota.sh chmod 755 post-fs-data.d/post_ota.sh
cd / cd /
...@@ -196,8 +200,7 @@ grep_prop() { return; } ...@@ -196,8 +200,7 @@ grep_prop() { return; }
# Initialize # Initialize
############# #############
mm_init() { app_init() {
export BOOTMODE=true
mount_partitions mount_partitions
get_flags get_flags
run_migrations run_migrations
...@@ -207,3 +210,5 @@ mm_init() { ...@@ -207,3 +210,5 @@ mm_init() {
# Make sure RECOVERYMODE has value # Make sure RECOVERYMODE has value
[ -z $RECOVERYMODE ] && RECOVERYMODE=false [ -z $RECOVERYMODE ] && RECOVERYMODE=false
} }
export BOOTMODE=true
...@@ -28,6 +28,6 @@ kapt.incremental.apt=true ...@@ -28,6 +28,6 @@ kapt.incremental.apt=true
# Magisk # Magisk
magisk.stubVersion=17 magisk.stubVersion=17
magisk.versionCode=21405 magisk.versionCode=21406
magisk.ndkVersion=21d magisk.ndkVersion=21d
magisk.fullNdkVersion=21.3.6528147 magisk.fullNdkVersion=21.3.6528147
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment