mirror of
https://github.com/topjohnwu/libsu.git
synced 2024-11-23 12:09:42 +00:00
Update Shell.rootAccess() implementation
This commit is contained in:
parent
47c8d2c9c2
commit
9c7025130e
@ -28,6 +28,7 @@ import androidx.annotation.Nullable;
|
||||
import com.topjohnwu.superuser.internal.BuilderImpl;
|
||||
import com.topjohnwu.superuser.internal.MainShell;
|
||||
import com.topjohnwu.superuser.internal.UiThreadHandler;
|
||||
import com.topjohnwu.superuser.internal.Utils;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
@ -206,17 +207,17 @@ public abstract class Shell implements Closeable {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code Shell.getShell().isRoot()}
|
||||
* Whether the application has access to root.
|
||||
* <p>
|
||||
* Please refer to {@link #getShell()} for info about concerns on blocking.
|
||||
* This method would NEVER produce false negatives, but false positives can be returned before
|
||||
* actually constructing a root shell. A {@code false} returned is guaranteed to be
|
||||
* 100% accurate, while {@code true} may be returned if the device is rooted, but the user
|
||||
* did not grant root access to your application. However, after any root shell is constructed,
|
||||
* this method will accurately return {@code true}.
|
||||
* @return whether the application has access to root.
|
||||
*/
|
||||
public static boolean rootAccess() {
|
||||
try {
|
||||
return getShell().isRoot();
|
||||
} catch (NoShellException e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Utils.isAppGrantedRoot();
|
||||
}
|
||||
|
||||
/* ************
|
||||
|
@ -89,8 +89,12 @@ public final class BuilderImpl extends Shell.Builder {
|
||||
if (shell == null && !hasFlags(FLAG_NON_ROOT_SHELL)) {
|
||||
try {
|
||||
shell = build("su");
|
||||
if (shell.getStatus() != ROOT_SHELL)
|
||||
if (shell.getStatus() != ROOT_SHELL) {
|
||||
shell = null;
|
||||
synchronized (Utils.class) {
|
||||
Utils.confirmedRootState = false;
|
||||
}
|
||||
}
|
||||
} catch (NoShellException ignore) {}
|
||||
}
|
||||
|
||||
|
@ -141,8 +141,12 @@ class ShellImpl extends Shell {
|
||||
STDIN.write(("id\n").getBytes(UTF_8));
|
||||
STDIN.flush();
|
||||
s = br.readLine();
|
||||
if (!TextUtils.isEmpty(s) && s.contains("uid=0"))
|
||||
if (!TextUtils.isEmpty(s) && s.contains("uid=0")) {
|
||||
status = ROOT_SHELL;
|
||||
synchronized (Utils.class) {
|
||||
Utils.confirmedRootState = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (status == ROOT_SHELL) {
|
||||
STDIN.write(("readlink /proc/self/ns/mnt\n").getBytes(UTF_8));
|
||||
|
@ -20,6 +20,7 @@ import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.os.Build;
|
||||
import android.os.Process;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
|
||||
@ -42,6 +43,7 @@ public final class Utils {
|
||||
public static Context context;
|
||||
private static Class<?> synchronizedCollectionClass;
|
||||
private static final String TAG = "LIBSU";
|
||||
static Boolean confirmedRootState = null;
|
||||
|
||||
public static void log(Object log) {
|
||||
log(TAG, log);
|
||||
@ -123,4 +125,28 @@ public final class Utils {
|
||||
return new HashSet<>();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized static boolean isAppGrantedRoot() {
|
||||
if (confirmedRootState != null) {
|
||||
// This confirmed root state will also be set in BuilderImpl
|
||||
// and ShellImpl when new shells are getting constructed.
|
||||
return confirmedRootState;
|
||||
}
|
||||
if (Process.myUid() == 0) {
|
||||
// The current process is a root service
|
||||
confirmedRootState = true;
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
Runtime.getRuntime().exec("su --version");
|
||||
// Even if the execution worked, we don't actually know whether the app has
|
||||
// been granted root access. As a heuristic, let's return true here,
|
||||
// but do NOT set the value as a confirmed state.
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
// Cannot run program "su": error=2, No such file or directory
|
||||
confirmedRootState = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user