Allow requesting root from non app process

This commit is contained in:
topjohnwu 2022-05-07 00:46:23 -07:00
parent 71e9c044e6
commit 2793d209a4
3 changed files with 29 additions and 9 deletions

View File

@ -66,7 +66,11 @@ class SuRequestHandler(
val fifo = intent.getStringExtra("fifo") ?: throw SuRequestError()
val uid = intent.getIntExtra("uid", -1).also { if (it < 0) throw SuRequestError() }
val pid = intent.getIntExtra("pid", -1)
pkgInfo = pm.getPackageInfo(uid, pid) ?: throw SuRequestError()
pkgInfo = pm.getPackageInfo(uid, pid) ?: PackageInfo().apply {
val name = pm.getNameForUid(uid) ?: throw SuRequestError()
// We only fill in sharedUserId and leave other fields uninitialized
sharedUserId = name.split(":")[0]
}
output = DataOutputStream(FileOutputStream(fifo).buffered())
policy = SuPolicy(uid)
true

View File

@ -12,6 +12,7 @@ import com.topjohnwu.superuser.ipc.RootService
import com.topjohnwu.superuser.nio.FileSystemManager
import timber.log.Timber
import java.io.File
import java.io.IOException
import java.util.concurrent.locks.AbstractQueuedSynchronizer
class RootUtils(stub: Any?) : RootService() {
@ -55,9 +56,14 @@ class RootUtils(stub: Any?) : RootService() {
if (proc != null)
return proc
// Find PPID
File("/proc/$pid/status").useLines {
val s = it.find { line -> line.startsWith("PPid:") }
pid = s?.substring(5)?.trim()?.toInt() ?: -1
try {
File("/proc/$pid/status").useLines {
val line = it.find { l -> l.startsWith("PPid:") } ?: return null
pid = line.substring(5).trim().toInt()
}
} catch (e: IOException) {
// The process died unexpectedly
return null
}
}
return null

View File

@ -110,11 +110,21 @@ class SuRequestViewModel(
private fun showDialog() {
val pm = handler.pm
val info = handler.pkgInfo
val prefix = if (info.sharedUserId == null) "" else "[SharedUID] "
val app = info.applicationInfo
if (app == null) {
// The request is not coming from an app process, and the UID is a
// shared UID. We have no way to know where this request comes from.
icon = pm.defaultActivityIcon
title = "[SharedUID] ${info.sharedUserId}"
packageName = info.sharedUserId
} else {
val prefix = if (info.sharedUserId == null) "" else "[SharedUID] "
icon = app.loadIcon(pm)
title = "$prefix${app.getLabel(pm)}"
packageName = info.packageName
}
icon = info.applicationInfo.loadIcon(pm)
title = "$prefix${info.applicationInfo.getLabel(pm)}"
packageName = info.packageName
selectedItemPosition = timeoutPrefs.getInt(packageName, 0)
// Set timer
@ -135,7 +145,7 @@ class SuRequestViewModel(
timer.cancel()
val pos = selectedItemPosition
timeoutPrefs.edit().putInt(handler.pkgInfo.packageName, pos).apply()
timeoutPrefs.edit().putInt(packageName, pos).apply()
viewModelScope.launch {
handler.respond(action, Config.Value.TIMEOUT_LIST[pos])