android - 应用程序创建的线程如何被视为与应用程序的 ContentProvider 不同的应用程序?

标签 android android-contentprovider uid android-securityexception

我有一个应用程序,当 ContentObserver 通知对 ContentProvider 的更改时,它会尝试在后台线程上查询提供程序。这会导致抛出 SecurityException:

8-10 15:54:29.577    3057-3200/com.xxxx.mobile.android.xxx W/Binder﹕ Caught a RuntimeException from the binder stub implementation.
  java.lang.SecurityException: Permission Denial: reading com.xxx.mobile.android.mdk.model.customer.ContentProvider uri content://com.xxx.mobile.android.consumer.xxx/vehicle from pid=0, uid=1000 requires the provider be exported, or grantUriPermission()
at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:539)
           at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:452)
           at android.content.ContentProvider$Transport.query(ContentProvider.java:205)
           at android.content.ContentResolver.query(ContentResolver.java:478)
           at android.content.ContentResolver.query(ContentResolver.java:422)

应用创建的线程如何以与应用的 ContentProvider 不同的 UID 结束?

通过在 android.content.ContentProvider 中放置一个异常断点,我看到 UserHandle.isSameApp(uid, mMyUid)false 并且 UserHandle.isSameUser(uid, mMyUid)true。我还看到提供者 UID 是 10087。

最佳答案

uid值1000属于Android系统。 Android 的许多功能都涉及将请求代理到系统线程进行处理。如果在此期间抛出异常,错误将包括系统的 uid,而不是原始请求者。

对于其他点:

UserHandle.isSameApp(uid, mMyUid) 为 false

UserHandle.isSameUser(uid, mMyUid) 为真

这些最容易通过查看 source 来解释。 .在支持多用户的 Android 设备上,每个用户都由一系列 UID 定义。 isSameApp 为 false,因为 id 的模数不匹配:

 public static final boolean isSameApp(int uid1, int uid2) {
        return getAppId(uid1) == getAppId(uid2);
}

 public static final int getAppId(int uid) {
        return uid % PER_USER_RANGE;
}

同样,这两个id属于同一个用户,因为他们生活在同一个范围内:

 public static final boolean isSameUser(int uid1, int uid2) {
        return getUserId(uid1) == getUserId(uid2);
 }

public static final int getUserId(int uid) {
        if (MU_ENABLED) {
            return uid / PER_USER_RANGE;
        } else {
            return 0;
        }
}

请注意,此逻辑存在缺陷,因为这意味着所有 Android 系统 uid (< 10000) 都将被假定为“属于”第一个用户。

另请注意,如果第二个用户安装了超过 1000 个应用(!),则应用可能会被误认为是系统应用(uid % PER_USER_RANGE 都将返回 1000)。不过这并不重要,因为强大的沙盒可以防止任何太糟糕的事情发生。

关于android - 应用程序创建的线程如何被视为与应用程序的 ContentProvider 不同的应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31929908/

相关文章:

java - 带有 contentprovider 的 Listview 中没有数据

Facebook Connect uid MySQL 存储问题

java - Android Studio(IntelliJ),maven构建工具: Failed to load dx. jar

android - Appcompact activity 和 action bar activity 的区别

Android FrameLayout 和软键盘问题

java - 安卓 NSD : Why service type don't match

android - 动态注册内容提供者

android - android 应用程序如何确保自定义外部内容提供程序到位

javascript - 在 JavaScript 中生成唯一的订单号(人类可读)

android - 附近的消息 api : how to retrieve pictures and videos?