尝试在 Android 11 上获取网络功能时出现安全异常

问题描述 投票:0回答:2

在尝试访问下面的代码时,我收到 SecurityException,然后收到 RemoteException。应用程序接口

val 网络功能 = connectivityManager.getNetworkCapability(connectivityManager.activeNetwork)

异常获取

Fatal Exception: java.lang.SecurityException: Package android does not belong to 10319
           at android.os.Parcel.createExceptionOrNull(Parcel.java:2385)
           at android.os.Parcel.createException(Parcel.java:2369)
           at android.os.Parcel.readException(Parcel.java:2352)
           at android.os.Parcel.readException(Parcel.java:2294)
           at android.net.IConnectivityManager$Stub$Proxy.getNetworkCapabilities(IConnectivityManager.java:3347)
           at android.net.ConnectivityManager.getNetworkCapabilities(ConnectivityManager.java:1549)

Caused by android.os.RemoteException: Remote stack trace:
        at android.app.AppOpsManager.checkPackage(AppOpsManager.java:7783)
        at com.android.server.ConnectivityService.getNetworkCapabilities(ConnectivityService.java:2297)
        at android.net.IConnectivityManager$Stub.onTransact(IConnectivityManager.java:1357)
        at android.os.Binder.execTransactInternal(Binder.java:1195)
        at android.os.Binder.execTransact(Binder.java:1159)

我已经分析了它,当我深入研究 aosp 代码时,我发现流程将转到随附屏幕截图中显示的 AppOpsManager 类的 checkPackage 方法,并且从代码中我们知道,只要检查包条件不等于 MODE_ALLOWED,那么只有我们将得到安全异常。但我没有。知道该条件何时会失败。

如果有人对此有任何想法,请帮助我,谢谢😊

android exception android-source android-connectivitymanager android-app-ops
2个回答
20
投票

看起来这是一个已知问题 https://issuetracker.google.com/issues/175055271

Dec 10, 2020 11:43AM
We have passed this to the development team and will update this issue with more information as it becomes available.
Sep 14, 2021 12:04AM
Marked as fixed.
The issue has been fixed in Android S and above.

但没有针对 S 以下 Android 的修复。


0
投票

Google 在 Android 12 中修复了此问题:https://android-review.googlesource.com/c/platform/frameworks/base/+/1758029

根本原因是,在 Android 11 中,

android.intent.action.PROXY_CHANGE
会获取
ConnectivityManager
实例。假设当接收到
PROXY_CHANGE
广播时,
Application
对象刚刚被创建,但是它的
attachBaseContext
还没有执行完,这会导致使用
ConnectivityManager
(包名)创建
SystemContext
android
)。此外,由于
ConnectivityManager
实际上是单例,因此与其关联的 API 调用实际上正在使用
SystemContext
,从而触发
SecurityException

要解决此问题,可以在

attachBaseContext
中使用反射将
mContext
ConnectivityManager
字段修改为正确的 Context 对象。需要注意的是,
mContext
ConnectivityManager
字段在反射灰名单中,所以需要使用https://github.com/tiann/FreeReflection去除反射限制。

修复代码:

@SuppressLint("SoonBlockedPrivateApi")
public static void fixConnectivitySecurityException(Context ctx) {
    if (Build.VERSION.SDK_INT == Build.VERSION_CODES.R) {
        try {
            Reflection.unseal(base);// remove the reflection restriction
            ctx = ctx.getApplicationContext() != null ? ctx.getApplicationContext() : ctx;
            ConnectivityManager cm = (ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
            Field f = cm.getClass().getDeclaredField("mContext");
            f.setAccessible(true);
            Context c = (Context) f.get(cm);
            if (c != null && !ctx.getPackageName().equals(c.getPackageName())) {
                f.set(cm, ctx);
            }
        } catch (Throwable ignored) {
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.