详解Android 安全机制
d 对应的 HashMap《Uri, UriPermission》 数据结构。用 target uid 和 Uri 生成UriPermission 并保存在 mGrantedUriPermissions 中。
revokeUriPermission 实现分析。
找到该 Uri 对应的 ContentProvider ,然后删除 mGrantedUriPermissions 中与 Uri 对应的所有权限。
2.2 permission 的动态检查
这里的动态检查是指是 package 在程序运行过程中进行某些操作或者数据访问时才进行的 check ,与之对应的是应用程序安装或者升级时 PackageManagerService 通过扫描包中的静态权限信息相对应。
系统与权限 检查 相关的机制的实现主要集中在 PackageManagerService 和 ActivityManagerService 中。 ActivityManagerService 主要负责的是底层的 uid 层次的身份检查; PackageManagerService 则维护了 uid 到自己拥有的和被授予的权限的一张表。在通过 ActivityManagerService 的身份检查后, PackageManagerService 根据请求者的 uid 来查看这张表,判断其是否具有相应的权限。
除此之外, per-URI permission 机制的实现也需要一张表,它维护在 ActivityManagerService 中,它建立了从 content URI 到被授权访问这个 URI 的 component 之间的映射。但是它也需要借助 PackageManagerService 的机制来辅助实现。
2.2.1 framework 提供的接口
Android framework 中提供了一些接口用来对外来的访问(包括自己)进行权限检查 。 这些接口 主要通过 ContextWrapper 提供,具体实现在 ContextImpl 中 。如果 package 接受到外来访问者的操作请求,那么可以调用这些接口进行权限检查。一般情况下可以把这些接口的检查接口分为两种,一种是返回错误,另一种是抛出异常。
主要包含如下几组:
n permission 和 uid 检查 API
下面这一组接口主要用来检查某个调用(或者是其它 package 或者是自己)是否拥有访问某个 permission 的权限。参数中 pid 和 uid 可以指定,如果没有指定,那么 framework 会通过 Binder 来获取调用者的 uid 和 pid 信息,加以填充。返回值为 PackageManager.PERMISSION_GRANTED 或者 PackageManager.PERMISSION_DENIED 。
public int checkPermission(String permission, int pid, int uid) // 检查某个 uid 和 pid 是否有 permission 权限
public int checkCallingPermission(String permission) // 检查调用者是否有 permission 权限,如果调用者是自己那么返回PackageManager.PERMISSION_DENIED
public int checkCallingOrSelfPermission(String permission) // 检查自己或者其它调用者是否有 permission 权限
下面这一组和上面类似,如果遇到检查不通过时,会抛出异常,打印消息 。
public void enforcePermission(String permission, int pid, int uid, String message)
public void enforceCallingPermission(String permission, String message)
public void enforceCallingOrSelfPermission(String permission, String message)
n per-URI 检查 API
为某个 package 添加访问 content Uri 的读或者写权限。
public void grantUriPermission(String toPackage, Uri uri, int modeFlags)
public void revokeUriPermission(Uri uri, int modeFlags)
检查某个 pid 和 uid 的 package 是否拥有 uri 的读写权限,返回值表示是否被 granted 。
public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags)
public int checkCallingUriPermission(Uri uri, int modeFlags)
public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags)
public int checkUriPermission(Uri uri, String readPermission,String writePermission, int pid, int uid, int modeFlags)
检查某个 pid 和 uid 的 package 是否拥有 uri 的读写权限,如果失败则抛出异常,打印消息 。
public void enforceUriPermission(Uri uri, int pid, int uid, int modeFlags, String message)
public void enforceCallingUriPermission(Uri uri, int modeFlags, String m message)
public void enforceCallingOrSelfUriPermission(Uri uri, int modeFlags, String message)
public void enforceUriPermission(Uri uri, String readPermission, String writePermission,int pid, int uid, int modeFlags, String message)
2.2.2 实现分析
ContextImpl.java 中提供的 API ,其实都是由 ActivityManagerService 中的如下几个接口进行的封装。
pu
- Palm Pre拆解:剖析电池及多点触控问题(12-16)
- 用充电IC实现手机快速充电(11-17)
- 电池供电的IoT世界中的USB连接(12-21)
- 如此简单!两招教你轻松搞定Android手机耗电问题(12-08)
- 一种手机端的Android驾驶辅助系统的设计(12-07)
- 入门专用,Android应用程序中常用传感器的使用(12-05)
