此问题曾在How does Android enforce permissions?之前提出过。虽然讨论很好,但问题仍未得到充分解答。
在开发环境中,当应用程序尝试执行需要未在AndroidManifest.xml中声明的权限的操作时,会引发异常。那么运行时系统如何实现运行时检查呢?
我想这很可能是在核心框架中完成的,可能需要也可能不需要本机代码的支持。但我不知道AOSP中的哪些源代码文件与此相关。
答案 0 :(得分:14)
Android使用了很多标准的Linux(-kernel?)机制,特别是在硬件限制方面。
为每个应用分配一个新的唯一(Linux-)用户ID,每当创建应用程序进程时,系统都会使用该用户ID创建它。除非您删除该应用,否则ID将永远不会更改。这意味着,为了访问较低的系统级别,您的应用程序将显示为特定用户,并且与用户协作的每个(Linux-)权限系统也将应用于您的应用程序。
如果您在清单中请求WRITE_EXTERNAL_STORAGE
,您的应用也将成为有权写入该存储的(Linux-)组(称为sdcard_rw
)的成员。强制执行文件系统的权限只允许写入system
用户(=所有者)和sdcard_rw
组,其他任何人(=其他)只能阅读。另请参阅Is Google blocking apps writing to SD cards
通过这样做,除了设置应用程序启动后产生的进程的正确UID / GID以及其余部分在较低级别处理时,Android几乎不做任何事情。不属于某个组的应用程序根本无法访问某些硬件。
许可列表<>组映射:platform.xml
还有一些(Android软件)限制基于您的应用的签名和/或仅通过查找您的应用所请求的权限: ContextImpl#checkPermission() - 但必须在每个入口点检查这些权限以允许限制操作的代码。
人们不时会发现例如以编程方式打开GPS,因为某处的检查丢失了。
答案 1 :(得分:4)
关于你的第二段,"例外"是运行时故障。在构建时,仅在运行时不会强制执行权限。
访问硬件,低级操作系统资源和系统文件通常要求app userid是相应组的成员,由于具有相应的android权限,它可能由包管理器分配。 (熟悉的例子就是网络套接字,以及zapl提到的sdcard写入,还有系统专用的东西,比如直接与GSM调制解调器通信或读取原始触摸屏坐标)。
对于通过调用库函数完成的大多数android操作,这些函数是用于进程间通信的存根,用于在不同进程中运行的服务,在ipc请求的接收端的更多特权进程中运行的平台代码检查与包管理器一起查看调用应用程序是否具有必要的android权限。
许多特殊权限仅适用于使用系统签名签名的应用程序 - 即使其他应用程序在其清单中声明了这些权限,它们也不会被包管理器应用。