Fix systemless hosts installation

This commit is contained in:
topjohnwu
2025-08-05 02:22:39 -07:00
committed by John Wu
parent 2923c8ccd1
commit 959430e030
6 changed files with 48 additions and 34 deletions

View File

@@ -22,11 +22,11 @@ import com.topjohnwu.magisk.core.ktx.activity
import com.topjohnwu.magisk.core.ktx.toast
import com.topjohnwu.magisk.core.tasks.AppMigration
import com.topjohnwu.magisk.core.utils.LocaleSetting
import com.topjohnwu.magisk.core.utils.RootUtils
import com.topjohnwu.magisk.databinding.bindExtra
import com.topjohnwu.magisk.events.AddHomeIconEvent
import com.topjohnwu.magisk.events.AuthEvent
import com.topjohnwu.magisk.events.SnackbarEvent
import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.launch
class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler {
@@ -130,7 +130,8 @@ class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler {
}
private fun createHosts() {
Shell.cmd("add_hosts_module").submit {
viewModelScope.launch {
RootUtils.addSystemlessHosts()
AppContext.toast(R.string.settings_hosts_toast, Toast.LENGTH_SHORT)
}
}

View File

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

View File

@@ -109,7 +109,7 @@ fun PackageManager.getPackageInfo(uid: Int, pid: Int): PackageInfo? {
return null
}
// Try to find package name from PID
val proc = RootUtils.obj?.getAppProcess(pid)
val proc = RootUtils.getAppProcess(pid)
if (proc == null) {
if (uid == Process.SHELL_UID) {
// It is possible that some apps installed are sharing UID with shell.

View File

@@ -7,11 +7,14 @@ import android.content.ServiceConnection
import android.os.IBinder
import android.system.Os
import androidx.core.content.getSystemService
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.ShellUtils
import com.topjohnwu.superuser.ipc.RootService
import com.topjohnwu.superuser.nio.FileSystemManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import timber.log.Timber
import java.io.File
import java.util.concurrent.locks.AbstractQueuedSynchronizer
@@ -43,16 +46,7 @@ class RootUtils(stub: Any?) : RootService() {
return object : IRootUtils.Stub() {
override fun getAppProcess(pid: Int) = safe(null) { getAppProcessImpl(pid) }
override fun getFileSystem(): IBinder = FileSystemManager.getService()
}
}
private inline fun <T> safe(default: T, block: () -> T): T {
return try {
block()
} catch (e: Throwable) {
// The process died unexpectedly
Timber.e(e)
default
override fun addSystemlessHosts() = safe(false) { addSystemlessHostsImpl() }
}
}
@@ -78,6 +72,26 @@ class RootUtils(stub: Any?) : RootService() {
return null
}
private fun addSystemlessHostsImpl(): Boolean {
val module = File(Const.MODULE_PATH, "hosts")
if (module.exists()) return true
val hosts = File(module, "system/etc/hosts")
if (!hosts.parentFile.mkdirs()) return false
File(module, "module.prop").outputStream().writer().use {
it.write("""
id=hosts
name=Systemless Hosts
version=1.0
versionCode=1
author=Magisk
description=Magisk app built-in systemless hosts module
""".trimIndent())
}
File("/system/etc/hosts").copyTo(hosts)
File(module, "update").createNewFile()
return true
}
object Connection : AbstractQueuedSynchronizer(), ServiceConnection {
init {
state = 1
@@ -131,11 +145,25 @@ class RootUtils(stub: Any?) : RootService() {
return field
}
private set
var obj: IRootUtils? = null
private var obj: IRootUtils? = null
get() {
Connection.await()
return field
}
private set
fun getAppProcess(pid: Int) = safe(null) { obj?.getAppProcess(pid) }
suspend fun addSystemlessHosts() =
withContext(Dispatchers.IO) { safe(false) { obj?.addSystemlessHosts() ?: false } }
private inline fun <T> safe(default: T, block: () -> T): T {
return try {
block()
} catch (e: Throwable) {
// The process died unexpectedly
Timber.e(e)
default
}
}
}
}

View File

@@ -123,7 +123,9 @@ class Environment : BaseTest {
}
private fun setupSystemlessHost() {
assertTrue("hosts setup failed", Shell.cmd("add_hosts_module").exec().isSuccess)
val error = "hosts setup failed"
assertTrue(error, runBlocking { RootUtils.addSystemlessHosts() })
assertTrue(error, RootUtils.fs.getFile(Const.MODULE_PATH).getChildFile("hosts").exists())
}
private fun setupSepolicyRuleModule(root: ExtendedFile) {

View File

@@ -118,24 +118,6 @@ EOF
cd /
}
add_hosts_module() {
# Do not touch existing hosts module
[ -d /data/adb/modules/hosts ] && return
cd /data/adb/modules
mkdir -p hosts/system/etc
cat << EOF > hosts/module.prop
id=hosts
name=Systemless Hosts
version=1.0
versionCode=1
author=Magisk
description=Magisk app built-in systemless hosts module
EOF
magisk --clone /system/etc/hosts hosts/system/etc/hosts
touch hosts/update
cd /
}
# $1 = APK
# $2 = package name
adb_pm_install() {