Update libsu

This commit is contained in:
topjohnwu 2022-05-03 01:25:26 -07:00
parent ff340ce3d8
commit cc79a96fa3
13 changed files with 63 additions and 66 deletions

View File

@ -86,10 +86,10 @@ dependencies {
implementation("${bindingAdapter}:${vBAdapt}")
implementation("${bindingAdapter}-recyclerview:${vBAdapt}")
val vLibsu = "4.0.3"
val vLibsu = "5.0.0"
implementation("com.github.topjohnwu.libsu:core:${vLibsu}")
implementation("com.github.topjohnwu.libsu:io:${vLibsu}")
implementation("com.github.topjohnwu.libsu:service:${vLibsu}")
implementation("com.github.topjohnwu.libsu:nio:${vLibsu}")
val vRetrofit = "2.9.0"
implementation("com.squareup.retrofit2:retrofit:${vRetrofit}")

View File

@ -5,4 +5,5 @@ package com.topjohnwu.magisk.core.utils;
interface IRootUtils {
android.app.ActivityManager.RunningAppProcessInfo getAppProcess(int pid);
IBinder getFileSystem();
}

View File

@ -46,7 +46,7 @@ abstract class BaseMainActivity<Binding : ViewDataBinding> : NavigationActivity<
}
if (doPreload) {
Shell.getShell(null) {
Shell.getShell(Shell.EXECUTOR) {
if (isRunningAsStub && !it.isRoot) {
showInvalidStateMessage()
return@getShell

View File

@ -8,7 +8,6 @@ import android.content.res.Configuration
import android.os.Bundle
import com.topjohnwu.magisk.StubApk
import com.topjohnwu.magisk.core.utils.*
import com.topjohnwu.magisk.di.AppContext
import com.topjohnwu.magisk.di.ServiceLocator
import com.topjohnwu.magisk.ui.surequest.SuRequestActivity
import com.topjohnwu.superuser.Shell
@ -54,13 +53,11 @@ open class App() : Application() {
super.attachBaseContext(base)
ServiceLocator.context = base
app.registerActivityLifecycleCallbacks(ActivityTracker)
}
override fun onCreate() {
super.onCreate()
Shell.setDefaultBuilder(Shell.Builder.create()
.setFlags(Shell.FLAG_MOUNT_MASTER)
.setInitializers(ShellInit::class.java)
.setContext(base)
.setTimeout(2))
Shell.EXECUTOR = DispatcherExecutor(Dispatchers.IO)
RootUtils.bindTask = RootService.bindOrTask(
@ -72,7 +69,7 @@ open class App() : Application() {
Shell.getShell(null) {}
refreshLocale()
AppContext.resources.patch()
resources.patch()
}
override fun onConfigurationChanged(newConfig: Configuration) {

View File

@ -8,7 +8,6 @@ import com.topjohnwu.magisk.core.utils.net.NetworkObserver
import com.topjohnwu.magisk.data.repository.NetworkService
import com.topjohnwu.magisk.di.AppContext
import com.topjohnwu.magisk.ktx.getProperty
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.ShellUtils.fastCmd
import com.topjohnwu.superuser.internal.UiThreadHandler
@ -36,6 +35,7 @@ object Info {
@JvmField var vbmeta = false
var crypto = ""
var noDataExec = false
var isRooted = false
@JvmField var hasGMS = true
val isSamsung = Build.MANUFACTURER.equals("samsung", ignoreCase = true)
@ -62,7 +62,7 @@ object Info {
) {
val versionCode = when {
code < Const.Version.MIN_VERCODE -> -1
else -> if (Shell.rootAccess()) code else -1
else -> if (isRooted) code else -1
}
val isUnsupported = code > 0 && code < Const.Version.MIN_VERCODE
val isActive = versionCode >= 0

View File

@ -2,9 +2,9 @@ package com.topjohnwu.magisk.core.model.module
import com.squareup.moshi.JsonDataException
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.utils.RootUtils
import com.topjohnwu.magisk.di.ServiceLocator
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.io.SuFile
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import timber.log.Timber
@ -26,13 +26,13 @@ data class LocalModule(
var outdated = false
private var updateUrl: String = ""
private val removeFile = SuFile(path, "remove")
private val disableFile = SuFile(path, "disable")
private val updateFile = SuFile(path, "update")
private val ruleFile = SuFile(path, "sepolicy.rule")
private val riruFolder = SuFile(path, "riru")
private val zygiskFolder = SuFile(path, "zygisk")
private val unloaded = SuFile(zygiskFolder, "unloaded")
private val removeFile = RootUtils.fs.getFile(path, "remove")
private val disableFile = RootUtils.fs.getFile(path, "disable")
private val updateFile = RootUtils.fs.getFile(path, "update")
private val ruleFile = RootUtils.fs.getFile(path, "sepolicy.rule")
private val riruFolder = RootUtils.fs.getFile(path, "riru")
private val zygiskFolder = RootUtils.fs.getFile(path, "zygisk")
private val unloaded = RootUtils.fs.getFile(zygiskFolder, "unloaded")
val updated: Boolean get() = updateFile.exists()
val isRiru: Boolean get() = (id == "riru-core") || riruFolder.exists()
@ -139,7 +139,7 @@ data class LocalModule(
private val PERSIST get() = "${Const.MAGISKTMP}/mirror/persist/magisk"
suspend fun installed() = withContext(Dispatchers.IO) {
SuFile(Const.MAGISK_PATH)
RootUtils.fs.getFile(Const.MAGISK_PATH)
.listFiles()
.orEmpty()
.filter { !it.isFile }

View File

@ -12,6 +12,7 @@ import com.topjohnwu.magisk.core.*
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.inputStream
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream
import com.topjohnwu.magisk.core.utils.RootUtils
import com.topjohnwu.magisk.di.ServiceLocator
import com.topjohnwu.magisk.ktx.reboot
import com.topjohnwu.magisk.ktx.withStreams
@ -22,9 +23,8 @@ import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.ShellUtils
import com.topjohnwu.superuser.internal.NOPList
import com.topjohnwu.superuser.internal.UiThreadHandler
import com.topjohnwu.superuser.io.SuFile
import com.topjohnwu.superuser.io.SuFileInputStream
import com.topjohnwu.superuser.io.SuFileOutputStream
import com.topjohnwu.superuser.nio.ExtendedFile
import com.topjohnwu.superuser.nio.FileSystemManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import net.jpountz.lz4.LZ4FrameInputStream
@ -45,21 +45,24 @@ abstract class MagiskInstallImpl protected constructor(
private val logs: MutableList<String> = NOPList.getInstance()
) {
protected var installDir = File("xxx")
private lateinit var srcBoot: File
protected lateinit var installDir: ExtendedFile
private lateinit var srcBoot: ExtendedFile
private val shell = Shell.getShell()
private val service get() = ServiceLocator.networkService
protected val context get() = ServiceLocator.deContext
private val useRootDir = shell.isRoot && Info.noDataExec
private val rootFS get() = RootUtils.fs
private val localFS get() = FileSystemManager.getLocal()
private fun findImage(): Boolean {
val bootPath = "find_boot_image; echo \"\$BOOTIMAGE\"".fsh()
if (bootPath.isEmpty()) {
console.add("! Unable to detect target image")
return false
}
srcBoot = SuFile(bootPath)
srcBoot = rootFS.getFile(bootPath)
console.add("- Target image: $bootPath")
return true
}
@ -77,7 +80,7 @@ abstract class MagiskInstallImpl protected constructor(
console.add("! Unable to detect target image")
return false
}
srcBoot = SuFile(bootPath)
srcBoot = rootFS.getFile(bootPath)
console.add("- Target image: $bootPath")
return true
}
@ -86,7 +89,7 @@ abstract class MagiskInstallImpl protected constructor(
console.add("- Device platform: ${Const.CPU_ABI}")
console.add("- Installing: ${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})")
installDir = File(context.filesDir.parent, "install")
installDir = localFS.getFile(context.filesDir.parent, "install")
installDir.deleteRecursively()
installDir.mkdirs()
@ -146,7 +149,7 @@ abstract class MagiskInstallImpl protected constructor(
if (useRootDir) {
// Move everything to tmpfs to workaround Samsung bullshit
SuFile(Const.TMPDIR).also {
rootFS.getFile(Const.TMPDIR).also {
arrayOf(
"rm -rf $it",
"mkdir -p $it",
@ -160,14 +163,6 @@ abstract class MagiskInstallImpl protected constructor(
return true
}
// Optimization for SuFile I/O streams to skip an internal trial and error
private fun installDirFile(name: String): File {
return if (useRootDir)
SuFile(installDir, name)
else
File(installDir, name)
}
private fun InputStream.cleanPump(out: OutputStream) = withStreams(this, out) { src, _ ->
src.copyTo(out)
}
@ -198,8 +193,8 @@ abstract class MagiskInstallImpl protected constructor(
val name = entry.name.replace(".lz4", "")
console.add("-- Extracting: $name")
val extract = installDirFile(name)
decompressedStream().cleanPump(SuFileOutputStream.open(extract))
val extract = installDir.getChildFile(name)
decompressedStream().cleanPump(extract.newOutputStream())
} else if (entry.name.contains("vbmeta.img")) {
val rawData = decompressedStream().readBytes()
// Valid vbmeta.img should be at least 256 bytes
@ -219,8 +214,8 @@ abstract class MagiskInstallImpl protected constructor(
}
}
}
val boot = installDirFile("boot.img")
val recovery = installDirFile("recovery.img")
val boot = installDir.getChildFile("boot.img")
val recovery = installDir.getChildFile("recovery.img")
if (Config.recovery && recovery.exists() && boot.exists()) {
// Install to recovery
srcBoot = recovery
@ -234,7 +229,7 @@ abstract class MagiskInstallImpl protected constructor(
"./magiskboot cleanup",
"rm -f new-boot.img",
"cd /").sh()
SuFileInputStream.open(boot).use {
boot.newInputStream().use {
tarOut.putNextEntry(newTarEntry("boot.img", boot.length()))
it.copyTo(tarOut)
}
@ -280,9 +275,9 @@ abstract class MagiskInstallImpl protected constructor(
processTar(src, outFile!!.uri.outputStream())
} else {
// raw image
srcBoot = installDirFile("boot.img")
srcBoot = installDir.getChildFile("boot.img")
console.add("- Copying image to cache")
src.cleanPump(SuFileOutputStream.open(srcBoot))
src.cleanPump(srcBoot.newOutputStream())
outFile = MediaStoreUtils.getFile("$filename.img", true)
outFile!!.uri.outputStream()
}
@ -302,12 +297,12 @@ abstract class MagiskInstallImpl protected constructor(
// Output file
try {
val newBoot = installDirFile("new-boot.img")
val newBoot = installDir.getChildFile("new-boot.img")
if (outStream is TarOutputStream) {
val name = if (srcBoot.path.contains("recovery")) "recovery.img" else "boot.img"
outStream.putNextEntry(newTarEntry(name, newBoot.length()))
}
SuFileInputStream.open(newBoot).cleanPump(outStream)
newBoot.newInputStream().cleanPump(outStream)
newBoot.delete()
console.add("")
@ -331,9 +326,9 @@ abstract class MagiskInstallImpl protected constructor(
private fun patchBoot(): Boolean {
var isSigned = false
if (srcBoot.let { it !is SuFile || !it.isCharacter }) {
if (!srcBoot.isCharacter) {
try {
SuFileInputStream.open(srcBoot).use {
srcBoot.newInputStream().use {
if (SignBoot.verifySignature(it, null)) {
isSigned = true
console.add("- Boot image is signed with AVB 1.0")
@ -346,7 +341,7 @@ abstract class MagiskInstallImpl protected constructor(
}
}
val newBoot = installDirFile("new-boot.img")
val newBoot = installDir.getChildFile("new-boot.img")
if (!useRootDir) {
// Create output files before hand
newBoot.createNewFile()
@ -370,7 +365,7 @@ abstract class MagiskInstallImpl protected constructor(
console.add("- Signing boot image with verity keys")
val signed = File.createTempFile("signed", ".img", context.cacheDir)
try {
val src = SuFileInputStream.open(newBoot).buffered()
val src = newBoot.newInputStream().buffered()
val out = signed.outputStream().buffered()
withStreams(src, out) { _, _ ->
SignBoot.doSignature(null, null, src, out, "/boot")
@ -410,11 +405,11 @@ abstract class MagiskInstallImpl protected constructor(
private fun String.fsh() = ShellUtils.fastCmd(shell, this)
private fun Array<String>.fsh() = ShellUtils.fastCmd(shell, *this)
protected fun doPatchFile(patchFile: Uri) = extractFiles() && handleFile(patchFile)
protected fun patchFile(file: Uri) = extractFiles() && handleFile(file)
protected fun direct() = findImage() && extractFiles() && patchBoot() && flashBoot()
protected suspend fun secondSlot() =
protected fun secondSlot() =
findSecondary() && extractFiles() && patchBoot() && flashBoot() && postOTA()
protected fun fixEnv() = extractFiles() && "fix_env $installDir".sh().isSuccess
@ -463,7 +458,7 @@ abstract class MagiskInstaller(
console: MutableList<String>,
logs: MutableList<String>
) : MagiskInstaller(console, logs) {
override suspend fun operations() = doPatchFile(uri)
override suspend fun operations() = patchFile(uri)
}
class SecondSlot(

View File

@ -9,6 +9,7 @@ import androidx.core.content.getSystemService
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.ShellUtils
import com.topjohnwu.superuser.ipc.RootService
import com.topjohnwu.superuser.nio.FileSystemManager
import timber.log.Timber
import java.io.File
import java.util.concurrent.locks.AbstractQueuedSynchronizer
@ -33,6 +34,7 @@ class RootUtils(stub: Any?) : RootService() {
override fun onBind(intent: Intent): IBinder {
return object : IRootUtils.Stub() {
override fun getAppProcess(pid: Int) = safe(null) { getAppProcessImpl(pid) }
override fun getFileSystem(): IBinder = FileSystemManager.getService()
}
}
@ -68,7 +70,10 @@ class RootUtils(stub: Any?) : RootService() {
override fun onServiceConnected(name: ComponentName, service: IBinder) {
Timber.d("onServiceConnected")
obj = IRootUtils.Stub.asInterface(service)
IRootUtils.Stub.asInterface(service).let {
obj = it
fs = FileSystemManager.getRemote(it.fileSystem)
}
releaseShared(1)
}
@ -101,6 +106,8 @@ class RootUtils(stub: Any?) : RootService() {
companion object {
var bindTask: Shell.Task? = null
var fs = FileSystemManager.getLocal()
private set
var obj: IRootUtils? = null
get() {
Connection.await()

View File

@ -19,6 +19,7 @@ import java.util.jar.JarFile
class ShellInit : Shell.Initializer() {
override fun onInit(context: Context, shell: Shell): Boolean {
if (shell.isRoot) {
Info.isRooted = true
RootUtils.bindTask?.let { shell.execTask(it) }
RootUtils.bindTask = null
}

View File

@ -1,7 +1,5 @@
package com.topjohnwu.magisk.core.utils
import com.topjohnwu.superuser.io.SuFile
import com.topjohnwu.superuser.io.SuFileOutputStream
import java.io.File
import java.io.IOException
import java.io.InputStream
@ -31,12 +29,12 @@ fun InputStream.unzip(folder: File, path: String, junkPath: Boolean) {
else
entry.name
var dest = File(folder, name)
if (!dest.parentFile!!.exists() && !dest.parentFile!!.mkdirs()) {
dest = SuFile(folder, name)
dest.parentFile!!.mkdirs()
val dest = File(folder, name)
dest.parentFile!!.let {
if (!it.exists())
it.mkdirs()
}
SuFileOutputStream.open(dest).use { out -> zin.copyTo(out) }
dest.outputStream().use { out -> zin.copyTo(out) }
}
} catch (e: IllegalArgumentException) {
throw IOException(e)

View File

@ -21,14 +21,13 @@ import com.topjohnwu.magisk.databinding.set
import com.topjohnwu.magisk.events.SnackbarEvent
import com.topjohnwu.magisk.ktx.*
import com.topjohnwu.superuser.CallbackList
import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class FlashViewModel : BaseViewModel() {
@get:Bindable
var showReboot = Shell.rootAccess()
var showReboot = Info.isRooted
set(value) = set(value, field, { field = it }, BR.showReboot)
private val _subtitle = MutableLiveData(R.string.flashing)

View File

@ -6,11 +6,11 @@ import android.widget.ImageView
import android.widget.TextView
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseFragment
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.download.DownloadService
import com.topjohnwu.magisk.databinding.FragmentHomeMd2Binding
import com.topjohnwu.magisk.di.viewModel
import com.topjohnwu.magisk.events.RebootEvent
import com.topjohnwu.superuser.Shell
class HomeFragment : BaseFragment<FragmentHomeMd2Binding>() {
@ -56,7 +56,7 @@ class HomeFragment : BaseFragment<FragmentHomeMd2Binding>() {
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.menu_home_md2, menu)
if (!Shell.rootAccess())
if (!Info.isRooted)
menu.removeItem(R.id.action_reboot)
}

View File

@ -18,7 +18,6 @@ import com.topjohnwu.magisk.di.ServiceLocator
import com.topjohnwu.magisk.events.MagiskInstallFileEvent
import com.topjohnwu.magisk.events.dialog.SecondSlotWarningDialog
import com.topjohnwu.magisk.ui.flash.FlashFragment
import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import timber.log.Timber
@ -29,7 +28,7 @@ class InstallViewModel(
svc: NetworkService
) : BaseViewModel() {
val isRooted = Shell.rootAccess()
val isRooted get() = Info.isRooted
val hideVbmeta = Info.vbmeta || Info.isSamsung || Info.isAB
val skipOptions = Info.isEmulator || (Info.isSAR && !Info.isFDE && hideVbmeta && Info.ramdisk)
val noSecondSlot = !isRooted || !Info.isAB || Info.isEmulator