Android系统架构
Android的总体架构被描述为“运行在Linux上的Java”,但是仅仅指的是Android应用层和框架层。
Android架构分为
- Android应用层(允许开发者不需要关注底层代码即可对设备功能进行拓展和提升)
- Android框架层(为上层提供API,充当应用层和Dalvik层的“粘合剂”,API包含各种构件(Building Block),如管理UI元素、访问共享数据存储等)
- Dalvik虚拟机层(为基层操作系统提供高效的抽象层,基于寄存器)
- 用户空间原生代码层(为Dalvik提供服务,包含系统服务、网络服务、程序库)
- Linux内核
安全边界和安全策略执行
安全边界也叫信任边界,用于分隔不同信任级别的特殊区域,如用户空间和内核空间的边界,内核空间能直接对底层进行操作,而用户空间受到CPU的安全边界控制,无法访问所有内存。
权限模型
Android操作系统使用两套独立但是相互配合的权限模型
- Android沙箱,在底层,Linux内核使用用户和用户组来实施权限控制,用于对文件系统和其他Android特定资源进行访问控制
- 以DalvikVM和Android框架层实现第二套权限模型,在用户安装应用时向用户公开,定义应用使用的权限。实际上,第二套权限模型的某些权限直接映射到底层操作系统上的特定用户、用户组和权能(Capability)
Android沙箱
Android继承了Unix的进程隔离机制与最小权限原则,具体而言,进程以隔离的用户环境运行,不能相互干扰,比如发送信号或访问其他进程的内存空间。
Android沙箱的几个概念:
- 标准的Linux进程隔离
- 大多数进程拥有唯一的UID
- 严格限制文件系统权限
Android沿用Linux的UID/GID权限模型,但是使用了AID(Android ID)替代passwd、group文件,AID文件位于system/core/include/private/android_filesystem_config.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| #define AID_ROOT 0 /* traditional unix root user */ #define AID_SYSTEM 1000 /* system server */ #define AID_RADIO 1001 /* telephony subsystem, RIL */ #define AID_BLUETOOTH 1002 /* bluetooth subsystem */ #define AID_GRAPHICS 1003 /* graphics devices */ #define AID_INPUT 1004 /* input devices */ #define AID_AUDIO 1005 /* audio devices */ #define AID_CAMERA 1006 /* camera devices */ #define AID_LOG 1007 /* log devices */ #define AID_COMPASS 1008 /* compass device */ #define AID_MOUNT 1009 /* mountd socket */ #define AID_WIFI 1010 /* wifi subsystem */ #define AID_ADB 1011 /* android debug bridge (adbd) */ #define AID_INSTALL 1012 /* group for installing packages */ #define AID_MEDIA 1013 /* mediaserver process */ #define AID_DHCP 1014 /* dhcp client */ #define AID_SDCARD_RW 1015 /* external storage write access */ #define AID_VPN 1016 /* vpn system */ #define AID_KEYSTORE 1017 /* keystore subsystem */ #define AID_USB 1018 /* USB devices */ #define AID_DRM 1019 /* DRM server */ #define AID_AVAILABLE 1020 /* available for use */ #define AID_GPS 1021 /* GPS daemon */ #define AID_UNUSED1 1022 /* deprecated, DO NOT USE */ #define AID_MEDIA_RW 1023 /* internal media storage write access */ #define AID_MTP 1024 /* MTP USB driver access */ #define AID_NFC 1025 /* nfc subsystem */ #define AID_DRMRPC 1026 /* group for drm rpc */ #define AID_SHELL 2000 /* adb and debug shell user */ #define AID_CACHE 2001 /* cache access */ #define AID_DIAG 2002 /* access to diagnostic resources */ /* The 3000 series are intended for use as supplemental group id's only. * They indicate special Android capabilities that the kernel is aware of. */ #define AID_NET_BT_ADMIN 3001 /* bluetooth: create any socket */ #define AID_NET_BT 3002 /* bluetooth: create sco, rfcomm or l2cap sockets */ #define AID_INET 3003 /* can create AF_INET and AF_INET6 sockets */ #define AID_NET_RAW 3004 /* can create raw INET sockets */ #define AID_NET_ADMIN 3005 /* can configure interfaces and routing tables. */ #define AID_NET_BW_STATS 3006 /* read bandwidth statistics */ #define AID_NET_BW_ACCT 3007 /* change bandwidth statistics accounting */ #define AID_MISC 9998 /* access to misc storage */ #define AID_NOBODY 9999 #define AID_APP 10000 /* first app user */
|
AIDs通过补充组获取权限或共享资源,例如在sdcard_rw组的成员拥有读写**/sdcard**文件的权限。
除了文件系统的权限,补充组也用于获取其他权限。例如AID_INET组,允许用户打开AF_INET和AF_INET6套接字。
当应用运行时,UID,GID和补充组分配给一个新进程,操作系统不仅会在内核层级强制使用权限限制,还会在应用运行时进行控制,这就是Android沙箱。
在Android模拟器中,通过ps
命令可以查看进程的PID。
Android权限
应用定义的权限会通过两种方式实施检查:
- 在调用应用的方法时由运行环境实施检查
- 在操作系统底层进行,由库或内核实施
packages.xml文件
应用包(apk)中包含了一个AndroidManifest.xml
的文件用于指定应用需要的权限,在安装时PackManager
从该文件中提取需要的权限并写入到/data/system/packages.xml
文件中
上图可以看到calendar
应用的uid为10002以及所申请的权限,当应用进程实例化的时候会根据这些条目向应用进程授予权限
表示权限映射到用户组的文件platform.xml
位于/etc/permissions/platform.xml
中,用于确定应用设置的辅助用户组GID
三种权限
API权限
API权限用于控制访问高层次的能力,存在于Android API
、框架层、第三方框架
比如API权限READ_PHONE_STATE
,权限定义为对手机状态的只读访问,当被授予该权限就可以调用关于手机的多种方法如getDeviceSoftwareVersion
和getDeviceID
等
- 根据权限模型的第二套,API权限与内核级的安全机制相对应,如果被授予
INETERNET
权限,那么应用的UID
就会被添加到inet
用户组中,拥有打开AF_INET
和AF_INET6
套接字的能力
文件系统权限
由于Unix系统的任意事物都作为文件看待,因此Android的沙箱机制也依赖于Unix文件系统的权限模型。
如上图所示,第二列和第三列分别为UID和GID,意味着该文件或者目录只能被该UID或GID访问
对于挂载的情况也是一样的,前面提到会使用特定的用户组GID访问共享资源
如上,当sdcard被GID为1015挂载的时候,对应的是sdcard_rw
,那么该应用获得WRITE_EXTERNAL_STORAGE
权限之后,就会将自己的UID添加到sdcard_rw
组中,从而获得读写权限
IPC权限
IPC全称Inter-Process Communication
,IPC权限声明和检查实施可能发生在不同层次上,包括运行环境、库函数或直接在应用上。
IPC权限集合应用与一些Android Binder IPC
机制上建立的主要Android应用组件