From 9043cd5c46d5ead16e37d0a27fe3470dc353356e Mon Sep 17 00:00:00 2001 From: canyie Date: Mon, 2 Jan 2023 23:07:33 +0800 Subject: [PATCH] Do not readlink `/proc/self/exe` Old platforms prevent `readlink /proc/self/exe` from being called from non-main threads on release builds https://stackoverflow.com/questions/28590831/android-permission-denied-when-reading-proc-self-exe-from-non-main-thread --- .../topjohnwu/superuser/internal/Utils.java | 21 +++++++++++++++++++ .../internal/RootServiceManager.java | 3 ++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/topjohnwu/superuser/internal/Utils.java b/core/src/main/java/com/topjohnwu/superuser/internal/Utils.java index 1e3575f..3aa847c 100644 --- a/core/src/main/java/com/topjohnwu/superuser/internal/Utils.java +++ b/core/src/main/java/com/topjohnwu/superuser/internal/Utils.java @@ -32,6 +32,7 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.lang.reflect.Method; import java.util.Collection; import java.util.Collections; import java.util.HashSet; @@ -180,4 +181,24 @@ public final class Utils { public static boolean isMainShellRoot() { return MainShell.get().isRoot(); } + + @SuppressLint("DiscouragedPrivateApi") + public static boolean isProcess64Bit() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + return Process.is64Bit(); + } + try { + Class classVMRuntime = Class.forName("dalvik.system.VMRuntime"); + Method getRuntime = classVMRuntime.getDeclaredMethod("getRuntime"); + getRuntime.setAccessible(true); + Object runtime = getRuntime.invoke(null); + Method is64Bit = classVMRuntime.getDeclaredMethod("is64Bit"); + is64Bit.setAccessible(true); + // noinspection ConstantConditions + return (boolean) is64Bit.invoke(runtime); + } catch (ReflectiveOperationException e) { + err(e); + return false; + } + } } diff --git a/service/src/main/java/com/topjohnwu/superuser/internal/RootServiceManager.java b/service/src/main/java/com/topjohnwu/superuser/internal/RootServiceManager.java index 52a0d68..e07e8e0 100644 --- a/service/src/main/java/com/topjohnwu/superuser/internal/RootServiceManager.java +++ b/service/src/main/java/com/topjohnwu/superuser/internal/RootServiceManager.java @@ -215,7 +215,8 @@ public class RootServiceManager implements Handler.Callback { break; } - String app_process = new File("/proc/self/exe").getCanonicalPath(); + // We cannot readlink /proc/self/exe on old kernels + String app_process = "/system/bin/app_process" + (Utils.isProcess64Bit() ? "64" : "32"); String cmd = String.format(Locale.ROOT, "(%s CLASSPATH=%s %s %s /system/bin %s " + "com.topjohnwu.superuser.internal.RootServerMain '%s' %d %s >/dev/null 2>&1)&",