Android 12安装应用出错:For security reasons, the system cannot issue a Uri permission

在Android12系统中,尝试通过自定义多媒体应用打开U盘上的apk文件时,遇到了URI权限错误,具体表现为SecurityException,原因是系统不允许UID10024访问特定的content://Uri。问题出在UriGrantsManagerService的checkGrantUriPermissionUnlocked函数,该函数检查权限时,非指定包名的应用会被拒绝。解决方案是将应用包名添加到豁免列表中。

问题场景:

在Android 12平台中通过自研多媒体应用打开U盘安装apk程序报URI权限错误

05-25 09:42:23.335  2753  2753 E AndroidRuntime: FATAL EXCEPTION: main
05-25 09:42:23.335  2753  2753 E AndroidRuntime: Process: com.android.packageinstaller, PID: 2753
05-25 09:42:23.335  2753  2753 E AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.packageinstaller/com.android.packageinstaller.InstallStart}: java.lang.SecurityException: UID 10024 does not have permission to content://com.example.media.fileProvider/all_files/storage/762F-2749/YouTube_18.03.36_Apkpure.apk [user 0]
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3707)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3864)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2253)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at android.os.Handler.dispatchMessage(Handler.java:106)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at android.os.Looper.loopOnce(Looper.java:201)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at android.os.Looper.loop(Looper.java:288)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at android.app.ActivityThread.main(ActivityThread.java:7870)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at java.lang.reflect.Method.invoke(Native Method)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: Caused by: java.lang.SecurityException: UID 10024 does not have permission to content://com.sx.tv.media.fileProvider/all_files/storage/762F-2749/YouTube_18.03.36_Apkpure.apk [user 0]
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at android.os.Parcel.createExceptionOrNull(Parcel.java:2425)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at android.os.Parcel.createException(Parcel.java:2409)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at android.os.Parcel.readException(Parcel.java:2392)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at android.os.Parcel.readException(Parcel.java:2334)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at android.app.IActivityTaskManager$Stub$Proxy.startActivity(IActivityTaskManager.java:2326)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at android.app.Instrumentation.execStartActivity(Instrumentation.java:1758)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at android.app.Activity.startActivityForResult(Activity.java:5422)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at android.app.Activity.startActivityForResult(Activity.java:5380)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at android.app.Activity.startActivity(Activity.java:5766)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at android.app.Activity.startActivity(Activity.java:5719)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at com.android.packageinstaller.InstallStart.onCreate(InstallStart.java:150)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at android.app.Activity.performCreate(Activity.java:8069)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at android.app.Activity.performCreate(Activity.java:8049)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1341)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3688)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	... 12 more
05-25 09:42:23.335  2753  2753 E AndroidRuntime: Caused by: android.os.RemoteException: Remote stack trace:
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at com.android.server.uri.UriGrantsManagerService.checkGrantUriPermissionUnlocked(UriGrantsManagerService.java:1256)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at com.android.server.uri.UriGrantsManagerService.checkGrantUriPermissionFromIntentUnlocked(UriGrantsManagerService.java:621)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at com.android.server.uri.UriGrantsManagerService.access$1000(UriGrantsManagerService.java:107)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at com.android.server.uri.UriGrantsManagerService$LocalService.checkGrantUriPermissionFromIntent(UriGrantsManagerService.java:1412)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 	at com.android.server.wm.ActivityStarter$Request.resolveActivity(ActivityStarter.java:541)
05-25 09:42:23.335  2753  2753 E AndroidRuntime: 
05-25 09:42:23.345   497   546 W ActivityTaskManager:   Force finishing activity com.android.packageinstaller/.InstallStart
05-25 09:42:23.346   497  2777 I DropBoxManagerService: add tag=system_app_crash isTagEnabled=true flags=0x2

打开UriGrantsManagerService.java中的DEBUG后,发现如下log:

URiGrantsManagerService: For security reasons, the system cannot issue a Uri permission

通过如上log和前面的AndroidRuntime的堆栈打印,定位到是checkGrantUriPermissionUnlocked函数里面做的权限检查,如下是checkGrantUriPermissionUnlocked函数中做判断的部分代码

    /**
     * Check if the targetPkg can be granted permission to access uri by
     * the callingUid using the given modeFlags.  Throws a security exception
     * if callingUid is not allowed to do this.  Returns the uid of the target
     * if the URI permission grant should be performed; returns -1 if it is not
     * needed (for example targetPkg already has permission to access the URI).
     * If you already know the uid of the target, you can supply it in
     * lastTargetUid else set that to -1.
     */
    private int checkGrantUriPermissionUnlocked(int callingUid, String targetPkg, GrantUri grantUri,
            int modeFlags, int lastTargetUid) {
        if (!Intent.isAccessUriMode(modeFlags)) {
            return -1;
        }

        if (targetPkg != null) {
            if (DEBUG) Slog.v(TAG, "Checking grant " + targetPkg + " permission to " + grantUri);
        }

        // If this is not a content: uri, we can't do anything with it.
        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
            if (DEBUG) Slog.v(TAG, "Can't grant URI permission for non-content URI: " + grantUri);
            return -1;
        }

        // Bail early if system is trying to hand out permissions directly; it
        // must always grant permissions on behalf of someone explicit.
        final int callingAppId = UserHandle.getAppId(callingUid);
        if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
            if ("com.android.settings.files".equals(grantUri.uri.getAuthority())
                    || "com.android.rk.fileprovider".equals(grantUri.uri.getAuthority())
                    || "com.rockchips.mediacenter.fileprovider".equals(grantUri.uri.getAuthority())
                    || "com.android.settings.module_licenses".equals(grantUri.uri.getAuthority())) {
                // Exempted authority for
                // 1. cropping user photos and sharing a generated license html
                //    file in Settings app
                // 2. sharing a generated license html file in TvSettings app
                // 3. Sharing module license files from Settings app
            } else {
                Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
                        + " grant to " + grantUri + "; use startActivityAsCaller() instead");
                return -1;
            }
        }

解决方案

通过上面代码可以看出,针对是SYSTEM_ID和ROOT_UID应用,如果不是指定的授权包名就会直接返回-1,即not allow。所以要解决该问题,只要把自己的应用包名加进去就行了

--- a/Android/frameworks/base/services/core/java/com/android/server/uri/UriGrantsManagerService.java
+++ b/Android/frameworks/base/services/core/java/com/android/server/uri/UriGrantsManagerService.java
@@ -1099,7 +1099,8 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub {
             if ("com.android.settings.files".equals(grantUri.uri.getAuthority())
                     || "com.android.rk.fileprovider".equals(grantUri.uri.getAuthority())
                     || "com.rockchips.mediacenter.fileprovider".equals(grantUri.uri.getAuthority())
-                    || "com.android.settings.module_licenses".equals(grantUri.uri.getAuthority())) {
+                    || "com.android.settings.module_licenses".equals(grantUri.uri.getAuthority())
+                    || "com.example.media.fileProvider".equals(grantUri.uri.getAuthority())) {
                 // Exempted authority for
                 // 1. cropping user photos and sharing a generated license html
                 //    file in Settings app

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值