关于Permission Denial: getTaskThumbnails()

具体错误如下:

java.lang.SecurityException: Permission Denial: getTaskThumbnails() from pid=2881, uid=10077 requires android.permission.READ_FRAME_BUFFER

意思就是应用没有android.permission.READ_FRAME_BUFFER,但是我已经在AndroidManifest.xml中赋予了该权限:

    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
    <uses-permission android:name="android.permission.GET_TASKS"/>
    <uses-permission android:name="android.permission.READ_FRAME_BUFFER"/>
还是不行,就只能跟踪源码了,首先我们可以差点在调用getTaskThumbnails的时候,在ActivityManagerService中的getTaskThumbnails会进行权限检测,调用enforceCallingPermission,enforceCallingPermission又调用checkComponentPermission,最终会调用PackageManagerService的checkUidPermission
    public int checkUidPermission(String permName, int uid) {
        synchronized (mPackages) {
            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
            if (obj != null) {
                GrantedPermissions gp = (GrantedPermissions)obj;
                if (gp.grantedPermissions.contains(permName)) {
                    return PackageManager.PERMISSION_GRANTED;
                }
            } else {
                HashSet<String> perms = mSystemPermissions.get(uid);
                if (perms != null && perms.contains(permName)) {
                    return PackageManager.PERMISSION_GRANTED;
                }
            }
        }
        return PackageManager.PERMISSION_DENIED;
    }

这里会获取该apk赋予的权限,看里面是否有需要请求的权限。

我们跟踪代码的时候,发现这里面没有请求的权限android.permission.READ_FRAME_BUFFER,这是为什么呢,原因可能是安装的时候,解析AndroidManifest.xml的时候没有给他赋予这个权限,添加权限在grantPermissionsLPw函数里面,如下代码获取应用需要的权限对应的等级:

final BasePermission bp = mSettings.mPermissions.get(name);
            if (DEBUG_INSTALL) {
                if (gp != ps) {
                    Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
                }
            }

            if (bp == null || bp.packageSetting == null) {
                Slog.w(TAG, "Unknown permission " + name
                        + " in package " + pkg.packageName);
                continue;
            }

            final String perm = bp.name;
            boolean allowed;
            boolean allowedSig = false;
            final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;

Android里面共有6个权限等级,定义在PermissionInfo文件。

  /**
     * Dangerous value for {@link #protectionLevel}, corresponding
     * to the <code>dangerous</code> value of
     * {@link android.R.attr#protectionLevel}.
     */
    public static final int PROTECTION_DANGEROUS = 1;

    /**
     * System-level value for {@link #protectionLevel}, corresponding
     * to the <code>signature</code> value of
     * {@link android.R.attr#protectionLevel}.
     */
    public static final int PROTECTION_SIGNATURE = 2;

    /**
     * System-level value for {@link #protectionLevel}, corresponding
     * to the <code>signatureOrSystem</code> value of
     * {@link android.R.attr#protectionLevel}.
     */
    public static final int PROTECTION_SIGNATURE_OR_SYSTEM = 3;

    /**
     * Additional flag for {@link #protectionLevel}, corresponding
     * to the <code>system</code> value of
     * {@link android.R.attr#protectionLevel}.
     */
    public static final int PROTECTION_FLAG_SYSTEM = 0x10;

    /**
     * Additional flag for {@link #protectionLevel}, corresponding
     * to the <code>development</code> value of
     * {@link android.R.attr#protectionLevel}.
     */
    public static final int PROTECTION_FLAG_DEVELOPMENT = 0x20;
    
 android的权限大部分定义在framework-res.apk里面,部分如下所示:

    <permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"
        android:label="@string/permlab_changeComponentState"
        android:description="@string/permdesc_changeComponentState"
        android:protectionLevel="signature|system" />

    <!-- @hide Allows an application to grant or revoke specific permissions. -->
    <permission android:name="android.permission.GRANT_REVOKE_PERMISSIONS"
        android:label="@string/permlab_grantRevokePermissions"
        android:description="@string/permdesc_grantRevokePermissions"
        android:protectionLevel="signature" />

    <!-- Allows an application to use SurfaceFlinger's low level features.
    <p>Not for use by third-party applications. -->
    <permission android:name="android.permission.ACCESS_SURFACE_FLINGER"
        android:label="@string/permlab_accessSurfaceFlinger"
        android:description="@string/permdesc_accessSurfaceFlinger"
        android:protectionLevel="signature" />

    <!-- Allows an application to take screen shots and more generally
         get access to the frame buffer data.
         <p>Not for use by third-party applications. -->
    <permission android:name="android.permission.READ_FRAME_BUFFER"
        android:label="@string/permlab_readFrameBuffer"
        android:description="@string/permdesc_readFrameBuffer"
        android:protectionLevel="signature|system" />   

 这些权限最后在android系统起来后会保存到一个/data/system/packages.xml,如:
         <item name="android.permission.BROADCAST_STICKY" package="android" />
        <item name="android.permission.GRANT_REVOKE_PERMISSIONS" package="android" protection="2" />
        <item name="android.permission.WRITE_USER_DICTIONARY" package="android" />
        <item name="android.permission.READ_FRAME_BUFFER" package="android" protection="18" />
  言归正传,我们看安装时候对权限的解析,通过如下
  final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
  获取对应的权限等级,然后判断各个级别是否允许授权:
  if (level == PermissionInfo.PROTECTION_NORMAL
                    || level == PermissionInfo.PROTECTION_DANGEROUS) {
                // We grant a normal or dangerous permission if any of the following
                // are true:
                // 1) The permission is required
                // 2) The permission is optional, but was granted in the past
                // 3) The permission is optional, but was requested by an
                //    app in /system (not /data)
                //
                // Otherwise, reject the permission.
                allowed = (required || origPermissions.contains(perm)
                        || (isSystemApp(ps) && !isUpdatedSystemApp(ps)));
            } else if (bp.packageSetting == null) {
                // This permission is invalid; skip it.
                allowed = false;
            } else if (level == PermissionInfo.PROTECTION_SIGNATURE) {
                allowed = grantSignaturePermission(perm, pkg, bp, origPermissions);
                if (allowed) {
                    allowedSig = true;
                }
            } else {
                allowed = false;
            }
如果允许,则添加到该apk拥有的权限列表里面:
   if (allowed) {
                    if (!gp.grantedPermissions.contains(perm)) {
                        changedPermission = true;
                        gp.grantedPermissions.add(perm);
                        gp.gids = appendInts(gp.gids, bp.gids);
                    } else if (!ps.haveGids) {
                        gp.gids = appendInts(gp.gids, bp.gids);
                    }
                } 


跟踪代码我们可以发现,虽然apk请求了android.permission.READ_FRAME_BUFFER权限,但并没有赋予他,原因是签名不一致(签名需要跟定义权限的apk一致),这里获取到的level=PROTECTION_SIGNATURE,调用grantSignaturePermission判断是否获取权限。

修改对策:

1、修改apk签名

2、修改android.permission.READ_FRAME_BUFFER等级




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值