【问题标题】:SecurityException: 不允许执行 OP_READ_PHONE_STATE
【发布时间】:2017-02-03 06:55:30
【问题描述】:

用户报告我的应用程序崩溃并出现此错误跟踪

java.lang.SecurityException: com.android.phone from uid 10134 not allowed to perform OP_READ_PHONE_STATE
at android.os.Parcel.readException(Parcel.java:1620)
at android.os.Parcel.readException(Parcel.java:1573)
at com.android.internal.telephony.IPhoneSubInfo$Stub$Proxy.getVoiceMailNumberForSubscriber(IPhoneSubInfo.java:858)
at android.telephony.TelephonyManager.getVoiceMailNumber(TelephonyManager.java:2383)
at android.telephony.TelephonyManager.getVoiceMailNumber(TelephonyManager.java:2366)

到目前为止,只有一位用户报告了此问题。数千名其他用户正在运行此版本的应用程序,没有出现明显问题。

当我们调用TelephonyManager.getVoiceMailNumber() 时抛出异常。此操作已按要求记录了READ_PHONE_STATE 权限,该权限已被绝对、肯定地授予。

我找到了OP_READ_PHONE_STATEandroid.apps.AppOpsManager 类的权限,但无法弄清楚它到底对什么不满意。

谁能解释正在发生的事情以及需要做些什么来解决问题。

谢谢, -肯

【问题讨论】:

  • 您是否检查了 read_phone_state 的运行时权限?他们是否可以通过应用设置或 cyanogenmod(或类似工具)手动删除您的权限?
  • 代码在执行 getVoiceMailNumber() 调用之前检查标准的 READ_PHONE_STATE 权限。应用程序生成的支持电子邮件列出了所有未授予的请求权限。该列表中未报告 READ_PHONE_STATE。我几乎可以肯定 READ_PHONE_STATE 权限已被授予dd。
  • 疯了很久以前就看到了。我们现在看到很多这样的东西,只有三星,而且只有那些运行牛轧糖的人。
  • 我在搭载 Android 7 的三星 S8/S8+ 上也看到了这一点。你知道这是否主要是一个承运人而不是另一个承运人?
  • 它还在发生吗?有人可以确认吗?三星很烂!

标签: android security android-permissions android-6.0-marshmallow


【解决方案1】:

在 AOSP 中寻找该方法最终会导致 cheakReadPhoneState() method

在 Android 6 中,该方法为 here

在这两种情况下,它看起来都非常相似。这是 Android 6 代码:

private boolean checkReadPhoneState(String callingPackage, String message) {
    try {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, message);

        // SKIP checking run-time OP_READ_PHONE_STATE since self or using PRIVILEGED
        return true;
    } catch (SecurityException e) {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE,
                message);
    }

    return mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
        callingPackage) == AppOpsManager.MODE_ALLOWED;
}

首先它检查READ_PRIVILEGED_PHONE_STATE 是否被授予。如果是,则其余代码被短路并返回 true。否则,它确保READ_PHONE_STATE 被授予,否则抛出SecurityException。

最后,如果READ_PHONE_STATE 被授予,它确保OP_READ_PHONE_STATE 也被授予。我不完全确定它为什么会这样做,但这就是问题所在。无论发生在哪个设备上,运行时权限的工作方式都发生了一些变化。当READ_PHONE_STATE 权限被授予时,OP_READ_PHONE_STATE 操作也应该被授予,但是系统出于某种原因正在撤销该操作。

(也有可能是用户正在使用某个应用来管理应用操作并手动将其撤消。)

要修复它,我真的不认为你可以。你能做的最好的就是捕获错误并要求用户运行 ADB 命令来手动授予操作:

adb shell appops set com.your.packagename READ_PHONE_STATE allow.

【讨论】:

  • 应用操作字符串不同:adb shell appops set com.your.packagename android:read_phone_state allowsource
  • @EugenPechanec 您可以使用不带OP_ 前缀的操作常量名称以及正确的字符串值。查看the last branch of the strOpToOp() methodthe sOpNames array
  • 你说得对,这正是我所需要的,谢谢!也可以在 Lollipop 上工作,实际上更好,因为在 Pie 之前很多应用程序操作名称都丢失了。
猜你喜欢
  • 2017-12-12
  • 1970-01-01
  • 2018-08-05
  • 2018-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-15
相关资源
最近更新 更多