5

这个问题之前在Android 如何强制执行权限?. 虽然那里的讨论很好,但问题仍然没有完全回答。

在开发环境中,当应用尝试执行需要未在 AndroidManifest.xml 中声明的权限的操作时,会引发异常。那么运行时系统是如何实现运行时检查的呢?

我想这很可能是在核心框架中完成的,它可能需要也可能不需要本机代码的支持。但是我不知道 AOSP 中的哪些源代码文件与此相关。

4

2 回答 2

14

Android 使用了很多标准的 Linux(-kernel?)机制,尤其是在硬件限制方面。

每个应用程序都被分配了一个新的唯一(Linux-)用户 ID,并且每当创建应用程序进程时,系统都会使用该用户 ID 创建它。除非您删除应用程序,否则 id 永远不会改变。这意味着为了访问较低的系统级别,您的应用程序将显示为特定用户,并且与用户一起使用的每个 (Linux-) 权限系统也将适用于您的应用程序。

如果您WRITE_EXTERNAL_STORAGE在清单中请求,您的应用也将成为(Linux-)组(称为sdcard_rw)的成员,该组有权写入该存储。文件系统上的权限被强制只允许写入system用户(=所有者)和sdcard_rw组,其他任何人(=其他)只能读取。另请参阅Google 是否阻止应用程序写入 SD 卡

通过这样做,Android 几乎什么都不做,除了设置应用程序启动后它生成的进程的正确 UID/GID,其余部分在较低级别处理。不属于某个组的应用程序根本无法访问某些硬件。

权限 <> 组映射列表:platform.xml

还有一些(Android 软件)限制基于您的应用程序的签名和/或仅通过查找您的应用程序请求的权限:例如ContextImpl#checkPermission() - 但必须在每个入口点检查这些权限允许受限操作的代码。

人们有时会发现一些方法,例如以编程方式打开 GPS,因为这样的检查在某处丢失。

于 2012-04-29T01:40:46.030 回答
4

关于您的第二段,“异常”是运行时错误。在构建时不强制执行权限,仅在运行时强制执行。

访问硬件、低级操作系统资源和系统文件通常需要应用程序用户 ID 是适当组的成员,该组可能由包管理器分配,因为具有相应的 android 权限。(熟悉的例子是网络套接字和 zapl 提到的 sdcard 写入,还有系统专用的东西,比如直接与 GSM 调制解调器交谈或读取原始触摸屏坐标)。

对于大多数通过调用库函数来完成的android操作,这些库函数是与运行在不同进程中的服务进行进程间通信的存根,运行在ipc请求接收端的更高特权进程中的平台代码会检查包manager 来确定调用应用程序是否具有必要的 android 权限。

许多特殊权限仅适用于使用系统签名签名的应用程序 - 即使另一个应用程序在其清单中声明了这些权限,包管理器也不会应用它们。

于 2012-04-29T01:58:07.333 回答