Commit bec5edca authored by topjohnwu's avatar topjohnwu

Avoiding using shell I/O

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