(授权转载)微信码个蛋授权转载 码个蛋(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
xml <package codepath="/data/app/com.feelschaotic.demo-Gi5ksdF6mUDLakfOugCcwQ==" ft="16348dc3870" it="16343f1d6aa" name="com.feelschaotic.demo" nativelibrarypath="/data/app/com.feelschaotic.demo-Gi5ksdF6mUDLakfOugCcwQ==/lib" primarycpuabi="x86" privateflags="0" publicflags="945307462" userid="10102" ut="16348dc4c4d" version="8220"> <sigscount> </sigscount> <perms> </perms> </package>
可以发现,其他信息没有太大差异,但是权限列表中,部分在 Android 6.0 被标记为高危的权限都不在 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 的整个关系。总共分为三层:
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Django权限机制实现代码详解
- ZooKeeper ACL 权限控制机制
- Django 默认权限机制介绍及实践
- KodExplorer 4.40 发布,权限机制优化
- 你真的了解Android权限机制吗?@3
- 你真的了解Android权限机制吗?@2
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
淘宝天猫店是如何运营的
贾真 / 电子工业出版社 / 2017-5 / 49.8
《淘宝天猫店是如何运营的——网店从0到千万实操手册》是由天猫行业Top10卖家、电商圈知名讲师贾真写就的一本运营干货书籍。《淘宝天猫店是如何运营的——网店从0到千万实操手册》的最大卖点就是作者把自己运营店铺的经验系统地总结出来,把碎片化的“干货”形成一个系统的知识体系。句句易懂,读后受益! 现在网上能看到的电商经验,大多是碎片化知识,零散不成体系,其实很难系统地给卖家提供帮助。《淘宝天猫店是......一起来看看 《淘宝天猫店是如何运营的》 这本书的介绍吧!