你真的了解Android权限机制吗?(1)

栏目: IOS · Android · 发布时间: 5年前

(授权转载)微信码个蛋授权转载 码个蛋(codeegg)第 610 次推文 作者:FeelsChaotic 原文:https://www.jianshu.com/p/a17c8bed79d9 前言 Android将安全设计贯穿系统架构的各个层面,覆盖系统内核、虚拟机、应用程序框架层以及应用层各个环节,力求在开放的同时,也最大程度地保护用户的数据、应用程序和设备的安全。Android安全模型主要提供以下几种安全机制: 从技术架构角度来看,Android安全模型基于 Linux 操作系统内核安全性,有基本的用户和文件访问隔离,在这个基础上辅以内存管理技术和进程间通信机制,来适应移动端处理器性能与内存容量的限制。在应用层面,使用显式定义且经用户授权的权限控制机制,系统化地规范并强制各类应用程序的行为准则与权限许可,可以看到权限机制在安全模型中所处的位置。 那么为什么有权限机制? 我们知道 Android 应用程序是沙箱隔离的,每个应用都有一个只有自己具有读写权限的专用数据目录,应用只能访问自己的文件和一些设备上全局可访问的资源。 那如果我需要访问系统服务呢?这就有了 Android 的权限机制。所以根本原因一是沙箱隔离,二是服务支持的需求。 在本文开始之前,先抛出几个问题思考,什么是权限?权限是怎么进行赋予的?怎么判断一个组件是否拥有特定的权限?权限维护在哪?Android 6.0 运行时权限是什么原理?权限赋予后还能再更改吗? 带着问题和结构图,我们一一解开疑惑。 权限的本质 什么是权限?在 Android 中,一个权限,本质上是一个字符串,一个可以表示执行特定操作的能力的字符串。比如说:访问 SD 卡的能力,访问通讯录的能力,启动或访问一个第三方应用中的组件的能力。 使用 pm list permissions -f 命令可以详细查看 Android 所有预定义的权限。我们挑一个权限出来: +permission:android.permission.DELETE_PACKAGES package:android label:null description:null protectionLevel:signature|privileged 可以看到,一个权限的信息包括:定义的包名、标签、描述和保护级别,保护级别,嗯,这个我们需要详细讲讲。因为不是应用声明了权限,就一定会全部被自动赋予的,保护级别决定了包管理器是否应该赋予组件所申请的权限。 权限的级别 normal 级别。权限保护级别的默认值,无须用户确认,只要声明了,就自动默默授权。如:ACCESS_NETWORK_STATE。 dangerous 级别。赋予权限前,会弹出对话框,显式请求权限。如:READ_SMS。因为 Android 需要在安装时赋予权限,所以安装的确认对话框,也会显示列出权限清单。 signature 级别。signature 级别的权限是最严格的权限,只会赋予与声明权限使用相同证书的应用程序。 以系统内置 signature 级别权限为例,Android 系统应用的签名由平台密钥签发,默认情况下源码树里有 4 个不同的密钥文件:platform、shared、media 和 testkey。所有核心平台的包(如:设置、电话、蓝牙)均使用 platform 密钥签发;搜索和通讯录相关的包使用 shared 签发;图库和媒体相关的包使用 media 密钥签发;其他的应用使用 testkey 签发。定义系统内置权限的 framework-res.apk 文件是使用平台密钥签发的,因此任何试图请求 signature 级别内置权限的应用程序,需要使用与框架资源包相同的密钥进行签名。 signatureOrSystem 级别。可以看做是一种折中的级别,可被赋予与声明权限具有相同签名证书密钥的应用程序(同 signature 级别)或者系统镜像的部分应用,也就是说这允许厂商无须共享签名密钥。Android 4.3 之前,安装在 system 分区下的应用会被自动赋予该保护级别的权限,而 Android 4.4 之后,只允许安装在 system/priv-app/ 目录下的应用才能被主动赋予。 权限的管理 那么,系统内置权限,自定义权限,是怎么维护和管理的? 在每个应用安装时,权限就已经赋予了,系统使用包管理服务来管理权限。打开我们系统目录下的 /data/system/packages.xml,可以看到文件包含了所有已定义的权限列表和所有 apk 的包信息,这可以看做是包管理服务维护的一个已安装程序的核心数据库,这个数据库,随着每次应用安装、升级或卸载而进行更新。 主要属性如图: 标签内,定义了目前系统中的所有权限,分为系统内置的(package 属性为 android 的)和 apk 自定义的(package 属性为 apk 的包名)。根元素 含有每个 apk 的核心属性,以一个应用程序的条目为例: Android 6.0 以下 packages.xml Android 6.0 及以上 packages.xml xml   <package codepath="&#47;data&#47;app&#47;com&#46;feelschaotic&#46;demo&#45;Gi5ksdF6mUDLakfOugCcwQ&#61;&#61;" ft="16348dc3870" it="16343f1d6aa" name="com&#46;feelschaotic&#46;demo" nativelibrarypath="&#47;data&#47;app&#47;com&#46;feelschaotic&#46;demo&#45;Gi5ksdF6mUDLakfOugCcwQ&#61;&#61;&#47;lib" primarycpuabi="x86" privateflags="0" publicflags="945307462" userid="10102" ut="16348dc4c4d" version="8220"> <sigscount> </sigscount> <perms> </perms> </package> 可以发现,其他信息没有太大差异,但是权限列表中,部分在 Android 6.0 被标记为高危的权限都不在 里了,如:READ_SMS、READ_EXTERNAL_STORAGE、CALL_PHONE 等。这是怎么一回事呢? Android 6.0 之前,权限都是在安装时自动赋予的,不卸载应用的情况下,不能更改或撤销(实际上有些厂商打开了appOps,使得 6.0 以下也能更改权限,这种特殊情况我们不讨论)。而 Android 6.0 版本对 permission 的管理做了部分改动,针对 dangerous 级别,不再安装的时候赋予权限,而是在运行时动态申请。 我们大胆地推断下,packages.xml 里保留的是不会再变更的权限,运行时权限一定是另外单独地维护。我们在 data/system 目录下来了个全盘搜索,找到了 /data/system/users/0/runtime-permissions.xml。 xml   <pkgname> ... </pkgname>   没错了,就是这个文件。里面就记录着运行时权限的授予和拒绝状态。申请时,申请的结果会动态修改 granted 值。管理权限的仍然是 PMS,只不过 Android 6.0 之后新增了 runtime-permissions.xml 数据库。   权限的赋予   我们知道,Android 应用安装时,会被分配一个唯一的 UID,应用启动时,包管理器会设置新建进程的 UID 和 GID 为应用程序的 UID。如果应用已经被赋予了额外的权限,就把这些权限映射成一组 GID,作为补充 GID 分配给进程。低层就可以依赖于进程的 UID、GID 和补充 GID 来决定是否赋予权限了。   那么,上面流程的重点:   权限是如何映射到 OS 层的 UID、GID 上的呢?   映射完是怎么分配给进程的?   低层是怎么判断是否赋予权限的?   我们一个个来看,首先第一个,权限是如何映射的?内置权限到 GID 的映射是定义在 /etc/permission/platform.xml 中。   <permissions> ··· <permissionname> </permissionname> <permissionname> </permissionname> <permissionname> </permissionname> ··· </permissions>   值得注意的是:READ_EXTERNAL_STORAGE 这种运行时权限,在 Android 6.0 之后已经不会映射到 gid 了。动态赋予,动态申请,也就不需要映射了。     包管理器在启动时读取 platform.xml,并维护「权限-GID」对应的列表。当它给安装中的包授权时,会把权限对应的 GID 加入到该应用进程的补充 GID 中。我们举个例子,看下进程的属性:adb shell ps 拿到想要查找的进程的 PID。   USERPIDPPIDVSZRSSWCHANADDRSNAME ... u0_a882149 1624 1929916 112340SyS_epoll_wait0Scom.feelschaotic.demo   接着 adb shell -> cd proc -> cd 2149 (2149 为进程 PID,不固定) -> cat status 我们关注如下两行: Gid: 10050 10050 10050 10050 Groups: 1006 1015 1028 3002 3003 50050 这里我们便看到了系统进程的权限配置信息,这里的数字具体代表意义,可以在Android \system\core\include\private\android_filesystem_config.h 里面看到,其部分内容如下: #defineAID_CAMERA 1006/* camera devices / #defineAID_SDCARD_RW 1015/ external storage write access / #defineAID_SDCARD_R 1028/ external storage read access */ ··· staticconststructandroid_id_infoandroid_ids[] = { {"camera", AID_CAMERA, }, {"sdcard_r", AID_SDCARD_R, }, {"sdcard_rw", AID_SDCARD_RW, }, ··· }; 有没有发现什么?前文所述 sdcard_r 和 android.permission.READ_EXTERNAL_STORAGE 的映射已经定义在 /etc/permission/platform.xml 中了,此处 sdcard_r 映射 AID_SDCARD_R 对应 gid = 1015,这就是权限映射到 gid 的整个关系。总共分为三层:


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Mechanics of Web Handling

The Mechanics of Web Handling

David R. Roisum

This unique book covers many aspects of web handling for manufacturing, converting, and printing. The book is applicable to any web including paper, film, foil, nonwovens, and textiles. The Mech......一起来看看 《The Mechanics of Web Handling》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

在线进制转换器
在线进制转换器

各进制数互转换器

随机密码生成器
随机密码生成器

多种字符组合密码