- 积分
- 305
贡献1469
飞刀577 FD
注册时间2015-12-21
在线时间51 小时

扫一扫,手机访问本帖 
|
硬件平台:飞凌嵌入式 OKT507-C开发板7 ]% h- z6 L9 b' Y" U: N
操作系统:Android10.0- J) C0 T3 Y; S, M: I6 J
, q' w) _5 r2 j: ~! F; F; {9 `8 [, o 飞凌嵌入式 T507 开发板 Android系统版本为Android10.0,默认开启了SELinux。基于MAC访问控制模型的SElinux,可以更好地保护我们的Android系统, 比如限制系统服务的访问权限、控制应用对数据和系统日志的访问等措施,这样就降低了恶意软件的影响,并且可以防止因代码存在的缺陷而产生的对系统安全的影响。. o: Q2 c. |/ S" Y$ Z
从系统安全方面考虑,SELinux是保护神,但是从软件开发方面,SELinux就是一道牵绊,这是一把双刃剑。
( Z" R/ f3 M+ i: P
8 L( E) A/ q; V d, Z5 C' h R) J* H 比如我们开发应用或者增加系统服务的某些权限的时候,我们必须遵循SELinux的规则,给我们的应用设置对应的安全策略,否则我们的应用就不具备访问数据或者设备的权限。下面我们MAC访问控制模型开始,简单的梳理一下飞凌嵌入式 T507 开发板 Android的安全策略,以及自定义飞凌嵌入式 T507 开发板 Android安全策略的方法。( ]$ r( H; j. @0 S0 a; j' c
访问控制模型DAC,MAC 访问控制是指控制对计算机或者网络中某个资源的访问。没有它,所有人都可以访问任何资源。有了访问控制,用户在获取实际访问资源或进行操作之前,必须通过识别、验证、授权。: h, y: ~. K, Z
自主访问控制(DAC: Discretionary Access Control)系统识别用户,根据被操作对象的权限的设置,来决定该用户对其拥有的操作权限,read、write、exec。拥有这个对象权限的用户,又可以将该权限分配给其他用户,此谓之“Discretionary”。缺陷就是对权限控制比较分散,不便于管理,比如无法简单地将一组文件设置统一的权限开放给指定的一群用户。
& g" F1 H& F' E: y$ X+ [ 强制访问控制(MAC: Mandatory Access Control)MAC是为了弥补DAC权限控制过于分散的问题而诞生的。在MAC这种模型里,管理员管理访问控制。管理员制定策略,用户不能改变它。策略定义了哪个主体能访问哪个对象。这种访问控制模型可以增加安全级别,因为它基于策略,任何没有被显式授权的操作都不能执行。MAC被开发和实现在最重视保密的系统中,如军事系统。主体获得清楚的标记,对象得到分类标记,或称安全级别。
- n4 r4 T7 F. [ z9 y! u. L3 G$ S 基于MAC的SElinux 参考链接:https://source.android.google.cn/security/selinux
* Q; p$ p9 L" [$ E* a- t' R& n 软件通常情况下必须以 Root 用户帐号的身份运行,才能向原始块设备写入数据。在基于 DAC 的传统 Linux 环境中,如果 Root 用户遭到入侵,攻击者便可以利用该用户身份向每个原始块设备写入数据。从 Android 4.3 起,SELinux 开始为传统的自主访问控制 (DAC) 环境提供强制访问控制 (MAC) 保护功能。作为 Android 安全模型的一部分,Android 使用安全增强型 Linux (SELinux) 对所有进程强制执行强制访问控制 (MAC),甚至包括以 Root/超级用户权限运行的进程(Linux 功能)。例如,可以使用 SELinux 为这些设备添加标签,以便被分配了 Root 权限的进程只能向相关政策中指定的设备写入数据。这样一来,该进程便无法重写特定原始块设备之外的数据和系统设置。借助 SELinux,Android 可以更好地保护和限制系统服务、控制对应用数据和系统日志的访问、降低恶意软件的影响,并保护用户免遭移动设备上的代码可能存在的缺陷的影响。
2 O& ^5 K: i8 j% L( B$ }
6 U# X1 T4 \( U* H; K+ N. u$ D( r$ ^0 J. a
飞凌嵌入式 T507 开发板 Android系统版本为Android10,SELinux默认开启,即使获得了该系统的root权限,也只能向相关策略中指定的设备写入数据,从而更好地保护和限制系统服务,保障系统和数据的安全。+ n/ v1 b0 Q3 G( f1 ]4 K+ R
标签、规则和域 SELinux 依靠标签来匹配操作和策略。标签用于决定允许的事项。套接字、文件和进程在 SELinux 中都有标签。SELinux 在做决定时需参照两点:一是为这些对象分配的标签,二是定义这些对象如何交互的策略。
' j- n/ K8 O k2 x) U 在 SELinux 中,标签采用以下形式:user:role:type:mls_level,其中 type 是访问决定的主要组成部分,可通过构成标签的其他组成部分进行修改。对象会映射到类,对每个类的不同访问类型由权限表示。
( N) L, D6 } ^+ ^# }4 U; |: B6 s 策略规则采用以下形式:allow domains types:classes permissions;,其中:
& a7 M. {1 Q' x1 d4 D& M: o& k! C( n! A+ r
Domain - 一个进程或一组进程的标签。也称为域类型,因为它只是指进程的类型。 l& n& v& u# t' P
Type - 一个对象(例如,文件、套接字)或一组对象的标签。' Q% O A# b1 G( j( q1 [
Class - 要访问的对象(例如,文件、套接字)的类型。Permission - 要执行的操作(例如,读取、写入)。# w4 K( `7 f1 q& ?1 p! x8 p6 a. |
策略配置源文件 1、external/sepolicy
, V, R( m) ~9 m! U 这是独立于设备的配置,一般不能针对设备进行修改
7 e9 V& q& s* R& T4 C
" Y1 i% S+ s) i2 A9 Z 2、device/<vendor>/<product>/sepolicy
# n/ _7 M1 T+ a5 h) Q3 L) o 这是特定于设备的配置,基于 BOARD_SEPOLICY_* 变量来选择对应平台的策略配置。4 u# ]3 @* s& M* H
3 b: Z9 @" f! g 以飞凌嵌入式 T507 开发板 为例,T507策略文件的路径如下:
! K6 J) r2 _& j( Q8 V1 m V4 d8 {8 T OKT507-android-source/android$ ls device/softwinner/common/sepolicy/private vendor1 |6 m7 V, l3 d! J1 m2 H% t1 Y
Type Enforcement (TE) 配置文件 .te 文件中保存了对应对象的域和类型定义、规则。通常每个域一个 .te 文件,例如installd.te。在 device.te、file.te 中声明了设备和文件类型。在某些文件(例如domain.te、app.te)中则存储着共享规则。' |2 Q6 h8 c( B; d' W
G& i. C K) j6 \: o
以飞凌嵌入式 T507 开发板 为例,T507 system_app的TE文件的路径如下:
( U3 g; n. J( v' P device/softwinner/common/sepolicy/vendor/system_app.te4 e. s- Z& V) L- a. F% G3 K2 Z
标签配置文件 1、file_contexts:文件安全上下文
, q# B2 v5 ^% f& T9 L0 R 2、property_contexts:属性安全上下文
9 s7 a9 O* V1 Z9 t/ p( m, B5 ?
& W6 R2 q: ^' \8 n 以飞凌嵌入式 T507 开发板 为例,T507 安全上下文文件路径如下:& u9 Y6 ~, |9 K+ k6 }
device/softwinner/common/sepolicy/vendor/property_contexts1 K w% O4 S5 u. q/ X
device/softwinner/common/sepolicy/vendor/file_contexts
8 a4 [) v* K; ^4 J" x6 I/ f1 k SEAndroid app分类 SELinux(或SEAndroid)将app划分为主要三种类型(根据user不同,也有其他的domain类型):
+ v0 `& k' b3 r+ {* \ n0 U# n' A 1)untrusted_app 第三方app,没有Android平台签名,没有system权限& j1 Q$ s' t; b& o# U, B a* i
2)platform_app 有android平台签名,没有system权限9 Y7 @+ i; d9 R* m0 Y
3)system_app 有android平台签名和system权限
: P7 c8 T* X. A4 @& E 从上面划分,权限等级,理论上:untrusted_app < platform_app < system_app
; G4 R, c0 O! M" K# W2 m9 h APP的domain和type 查看seapp_contexts文件,APP的domain和type由user和seinfo两个参数决定
: u2 g- [% K- n+ R system/sepolicy/private/seapp_contexts! x6 K" I$ ^5 T
isSystemServer=true domain=system_server_startup
* o7 R3 P/ x' L: u- j user=_app seinfo=platform name=com.android.traceur domain=traceur_app type=app_data_file levelFrom=all
8 c9 \, h% i1 s+ o6 ~7 m0 N user=system seinfo=platform domain=system_app type=system_app_data_file, A. U2 v R y+ z2 }7 R
user=bluetooth seinfo=platform domain=bluetooth type=bluetooth_data_file: e! x+ q/ R9 w9 `; G4 e
user=network_stack seinfo=network_stack domain=network_stack levelFrom=all ( q3 O- ?# o6 J, x( q- P" u/ Q7 b' n
type=radio_data_file
2 J; j, b, M) H# {3 n user=nfc seinfo=platform domain=nfc type=nfc_data_file5 Z/ Z# h( o8 G z
user=secure_element seinfo=platform domain=secure_element levelFrom=all ~2 j: j) N9 p8 E: u- K
user=radio seinfo=platform domain=radio type=radio_data_file
; a7 I, h% A1 M7 E user=shared_relro domain=shared_relro
1 G5 [3 N% x6 v user=shell seinfo=platform domain=shell name=com.android.shell type=shell_data_file# U# x! n) r! K/ }7 q
user=webview_zygote seinfo=webview_zygote domain=webview_zygote4 L7 Y8 \# U6 m. @
user=_isolated domain=isolated_app levelFrom=al, h! t# Q6 {% O$ i# W
luser=_app seinfo=app_zygote domain=app_zygote levelFrom=all
' M; `5 y7 l2 Y2 X/ N( ]0 @/ x user=_app seinfo=media domain=mediaprovider name=android.process.media type=app_data_file
/ {+ _# d2 g! Z5 d5 i( G" z' C levelFrom=user
8 ]4 y% K$ j1 e! T3 v: N user=_app seinfo=platform domain=platform_app type=app_data_file levelFrom=user9 I2 y' i1 `( d$ e9 T$ P& z: k( k
user=_app isEphemeralApp=true domain=ephemeral_app type=app_data_file levelFrom=all
% {3 S1 q3 g* @3 {) M user=_app isPrivApp=true domain=priv_app type=privapp_data_file levelFrom=user
9 w) ~( r4 N/ h. {" o$ O user=_app minTargetSdkVersion=29 domain=untrusted_app type=app_data_file levelFrom=all& w* H$ ?, t! e% G" ^' R
user=_app minTargetSdkVersion=28 domain=untrusted_app_27 type=app_data_file levelFrom=all- q" p0 B8 t; @) N
user=_app minTargetSdkVersion=26 domain=untrusted_app_27 type=app_data_file
- x$ s1 s6 ?2 C! u, S1 O5 B levelFrom=user
) |% ]. ]0 z- U6 U- ~/ w& \ user=_app domain=untrusted_app_25 type=app_data_file levelFrom=user
% N' F) t8 f2 C( `6 n0 v/ ?& @0 | user=_app minTargetSdkVersion=28 fromRunAs=true domain=runas_app levelFrom=all. b9 _0 V4 [# V* g0 I2 e. @) ?
user=_app fromRunAs=true domain=runas_app levelFrom=user
* x, k6 b% G( `) ~1 J user 参考链接:https://blog.csdn.net/huilin9960/article/details/815305687 F, M% \. s7 i$ X/ Y+ R
user可以理解为UID。android的UID和linux的UID根本是两回事,Linux的UID是用于针对多用户操作系统中用于区分用户的,而Android中的UID是用于系统进行权限管理的。参考链接中的文章对于uid的产生讲的很清楚。
+ n1 Y2 V; h; { seinfo 不同签名会创建对应的selinux上下文。9 x4 e- F5 p6 S* ~
Android.mk
+ o: |, M4 h1 V; T" W- s; Q) ] LOCAL_CERTIFICATE := platform5 l {6 Q$ {) C, L, h/ O( v
有platform签名,所以seinfo是platform。# Q, ^7 {# W5 r- @7 c, T( b" E
LOCAL_CERTIFICATE作用 参考文档https://blog.csdn.net/hnlgzb/article/details/107823874
0 B8 `$ p# i! z! u0 `. I$ ? 可以查看Android源码build/target/product/security/ 目录下提供的默认签名文件,不同平台可能会有差异:飞凌嵌入式 T507 开发板 提供了media、networkstack、platform、shared、testkey、verity六种不同权限的签名文件。
7 \% t3 X, o3 V+ \
D* i0 K/ e. C7 z 以飞凌嵌入式 T507 开发板 为例,查看当前运行的应用信息:1 r' e+ @, ]3 p% Q/ q6 h# U
console:/ # ps -Z
& y% ^7 J# e! B3 ? u:r:system_app:s0 system 15712 1861 1050628 110868 SyS_epoll_wait % j5 z: m* Q2 i d: X
0 S forlinx.example.app8 K7 v* x. d9 X P) }. }3 Y( E) o8 {
u:r:untrusted_app_27:s0:c512,c768 u0_a62 30259 1861 1052120 114132 SyS_epoll_wait / W) D( d0 T/ \$ H8 a9 `- w
0 S com.forlinx.changelogo) n( {' p* a# l, @* a+ x) _
当前运行的两个APP,forlinx.example.app的UID(user)是system,拥有platform签名,它的domain和type就是system_app。* p2 x/ Z% j) ^8 g& M. e- a3 g
9 ~ ]% k! L, j) X! p V
& F: F. ]+ e& _: g : I1 }# b2 ]! h
com.forlinx.changelogo没有设置UID使用的默认设置,其UID为u0_a62,并且没有设置签名文件,它的domain和type就是untrusted_app。
. _& v5 b1 v# X+ C/ r T507自定义安全策略 以上面两个运行的app来说,我们为这两个APP添加额外的权限,对应的TE配置文件分别就是system_app.te、untrusted_app.te,对应路径为:, ~+ | M! `( t7 k
device/softwinner/common/sepolicy/vendor/system_app.te
$ ~2 B {, A6 U0 i& d( ^6 ?) X' v device/softwinner/common/sepolicy/vendor/untrusted_app.te" H3 \- H6 `+ N1 h! g- C
7 ]) }( G+ x$ |+ W. I
以forlinx.example.app为例,我们为其添加can设备的执行权限:) d$ ] q# D6 a9 ?! U
, v/ a9 n) w" w0 {# f& D/ P/ t8 I% i
OKT507-android-source/android$ vi device/softwinner/common/sepolicy/vendor/system_app.te Y0 i4 {- @' ^3 o$ y2 m3 k
...: m( o7 ]6 w. J0 S, B/ {
allow system_app vendor_shell_exec:file { getattr open read execute execute_no_trans };
7 `% M/ u* J" w; f! n4 d6 m allow system_app shell_exec:file { getattr open read execute execute_no_trans };
- o U/ }* _: E. F8 M6 j# E: h allow system_app shell:file { getattr open read execute execute_no_trans };' S: F9 q1 A) P+ ^) u3 e7 E
...+ `% h7 ~" d$ F! u. `% o
以策略规则配置形式(allow domains types:classes permissions)
8 D4 Z( ]' V& i& m' Y: U, d6 C 分析:domains:system_app
6 _! L N: k; [, m" W" h$ r8 B types:vendor_shell_exec
. ]: ~+ X- x5 X' U$ w. z classes:file
- T' T& T: g/ }* `8 m5 u0 j2 u permissions:getattr open read execute execute_no_trans
. C9 {4 w ~% @4 n neverallow failures 有时我们增加的权限,系统默认的配置是不允许的,比如我们上面给forlinx.example.app增加的执行脚本的权限,报错如下:
2 |* Z7 j1 R# g8 y9 C: S8 e" R7 {1 e* H/ `% d
libsepol.report_failure: neverallow on line 9 of system/sepolicy/private/system_app.te - g5 U+ U( w& Z3 c- ]) W2 i- `
(or line 41463 of policy.conf) violated by allow system_app shell:file { read open };5 R, s9 o8 H0 S( S/ {, V
libsepol.report_failure: neverallow on line 22 of system/sepolicy/private/shell.te& {7 y- _0 O' C! Q0 D
(or line 40025 of policy.conf) violated by allow system_app shell:file { read open };
- }7 q' {. i: ] libsepol.check_assertions: 2 neverallow failures occurred
`: {; L \( w/ g. Y/ |3 A4 C4 U# `* f5 Y
系统默认的安全策略的路径为system/sepolicy/,根据报错的提示,我们可以修改默认的配置,修改system/sepolicy/private/system_app.te和system/sepolicy/private/shell.te,从而完成权限的赋予。
# o# g" K% M# H" i( Z8 ~/ t6 \8 x9 G4 g( f$ ^* E8 w
以上就是Android 安全策略的脉络,以及飞凌嵌入式 T507 开发板 Android系统下自定义安全策略的方法了。
. b* r* Y1 s8 D) ~1 ?
2 l) z2 k8 `7 x* M, J, u2 G |
|