- 积分
- 296
贡献1418
飞刀565 FD
注册时间2015-12-21
在线时间50 小时

扫一扫,手机访问本帖 
|
硬件平台:飞凌嵌入式 OKT507-C开发板9 [9 Y# V3 @1 c8 O* Z
操作系统:Android10.03 K1 {* f+ a* q4 f
8 f7 W. x- Y' N
飞凌嵌入式 T507 开发板 Android系统版本为Android10.0,默认开启了SELinux。基于MAC访问控制模型的SElinux,可以更好地保护我们的Android系统, 比如限制系统服务的访问权限、控制应用对数据和系统日志的访问等措施,这样就降低了恶意软件的影响,并且可以防止因代码存在的缺陷而产生的对系统安全的影响。
5 c& }" z& Y* ~: U% {! p5 ]6 t9 } 从系统安全方面考虑,SELinux是保护神,但是从软件开发方面,SELinux就是一道牵绊,这是一把双刃剑。
4 D/ e% E& D1 {' l, K : p& e( w) x3 f1 y. a
比如我们开发应用或者增加系统服务的某些权限的时候,我们必须遵循SELinux的规则,给我们的应用设置对应的安全策略,否则我们的应用就不具备访问数据或者设备的权限。下面我们MAC访问控制模型开始,简单的梳理一下飞凌嵌入式 T507 开发板 Android的安全策略,以及自定义飞凌嵌入式 T507 开发板 Android安全策略的方法。& y& W7 c; C$ |
访问控制模型DAC,MAC 访问控制是指控制对计算机或者网络中某个资源的访问。没有它,所有人都可以访问任何资源。有了访问控制,用户在获取实际访问资源或进行操作之前,必须通过识别、验证、授权。
3 P9 t% i% o1 P 自主访问控制(DAC: Discretionary Access Control)系统识别用户,根据被操作对象的权限的设置,来决定该用户对其拥有的操作权限,read、write、exec。拥有这个对象权限的用户,又可以将该权限分配给其他用户,此谓之“Discretionary”。缺陷就是对权限控制比较分散,不便于管理,比如无法简单地将一组文件设置统一的权限开放给指定的一群用户。4 j$ f Q) s- j* t; U! |+ R3 M1 k
强制访问控制(MAC: Mandatory Access Control)MAC是为了弥补DAC权限控制过于分散的问题而诞生的。在MAC这种模型里,管理员管理访问控制。管理员制定策略,用户不能改变它。策略定义了哪个主体能访问哪个对象。这种访问控制模型可以增加安全级别,因为它基于策略,任何没有被显式授权的操作都不能执行。MAC被开发和实现在最重视保密的系统中,如军事系统。主体获得清楚的标记,对象得到分类标记,或称安全级别。# g- i* \3 U8 ^, u) |; M
基于MAC的SElinux 参考链接:https://source.android.google.cn/security/selinux6 `+ i9 j8 l* p+ d4 N9 k
软件通常情况下必须以 Root 用户帐号的身份运行,才能向原始块设备写入数据。在基于 DAC 的传统 Linux 环境中,如果 Root 用户遭到入侵,攻击者便可以利用该用户身份向每个原始块设备写入数据。从 Android 4.3 起,SELinux 开始为传统的自主访问控制 (DAC) 环境提供强制访问控制 (MAC) 保护功能。作为 Android 安全模型的一部分,Android 使用安全增强型 Linux (SELinux) 对所有进程强制执行强制访问控制 (MAC),甚至包括以 Root/超级用户权限运行的进程(Linux 功能)。例如,可以使用 SELinux 为这些设备添加标签,以便被分配了 Root 权限的进程只能向相关政策中指定的设备写入数据。这样一来,该进程便无法重写特定原始块设备之外的数据和系统设置。借助 SELinux,Android 可以更好地保护和限制系统服务、控制对应用数据和系统日志的访问、降低恶意软件的影响,并保护用户免遭移动设备上的代码可能存在的缺陷的影响。
3 L: n: Y4 d# I( u3 z S ! U! S- I+ |% B; v
+ U" O' V, w6 ?* K6 w 飞凌嵌入式 T507 开发板 Android系统版本为Android10,SELinux默认开启,即使获得了该系统的root权限,也只能向相关策略中指定的设备写入数据,从而更好地保护和限制系统服务,保障系统和数据的安全。
- v. d& f o) m 标签、规则和域 SELinux 依靠标签来匹配操作和策略。标签用于决定允许的事项。套接字、文件和进程在 SELinux 中都有标签。SELinux 在做决定时需参照两点:一是为这些对象分配的标签,二是定义这些对象如何交互的策略。) Z9 [ S; ]& S! C9 d
在 SELinux 中,标签采用以下形式:user:role:type:mls_level,其中 type 是访问决定的主要组成部分,可通过构成标签的其他组成部分进行修改。对象会映射到类,对每个类的不同访问类型由权限表示。
1 X l; i7 n' y1 u) Q" w 策略规则采用以下形式:allow domains types:classes permissions;,其中:0 J/ W! {; U2 L+ J) u. l6 _ c
3 }( W$ \+ @; n; B Domain - 一个进程或一组进程的标签。也称为域类型,因为它只是指进程的类型。: ~* K9 U% K5 |+ ]
Type - 一个对象(例如,文件、套接字)或一组对象的标签。
/ G8 a$ R6 l; J) }2 ` p/ s Class - 要访问的对象(例如,文件、套接字)的类型。Permission - 要执行的操作(例如,读取、写入)。- C: Z. \/ y3 t, G! n( s! z8 k3 J
策略配置源文件 1、external/sepolicy* Z- I8 ~6 m# |1 s
这是独立于设备的配置,一般不能针对设备进行修改
8 C Q* U y6 _( l
5 ^( J# V" y% `" z 2、device/<vendor>/<product>/sepolicy
# V D. N' B1 x' I 这是特定于设备的配置,基于 BOARD_SEPOLICY_* 变量来选择对应平台的策略配置。6 p) y! V3 D4 @1 ~
- `5 x( a& Q; Z: [' E
以飞凌嵌入式 T507 开发板 为例,T507策略文件的路径如下:
; J( n5 Z5 ~8 v. D( x+ l OKT507-android-source/android$ ls device/softwinner/common/sepolicy/private vendor+ y. W* q! f+ D% b5 ^$ \
Type Enforcement (TE) 配置文件 .te 文件中保存了对应对象的域和类型定义、规则。通常每个域一个 .te 文件,例如installd.te。在 device.te、file.te 中声明了设备和文件类型。在某些文件(例如domain.te、app.te)中则存储着共享规则。 h" j0 c3 l H6 `+ ?( b6 @$ d
' c5 g- O: ]5 y2 A% v 以飞凌嵌入式 T507 开发板 为例,T507 system_app的TE文件的路径如下:6 B2 [$ _ d2 ]2 n2 ~$ ?6 [
device/softwinner/common/sepolicy/vendor/system_app.te
5 V& N) i$ M' h- w% g1 P$ `7 M) s 标签配置文件 1、file_contexts:文件安全上下文
; T( g* e3 i! q 2、property_contexts:属性安全上下文; Y5 m) r- i0 P. k i
4 x* c& b1 J! ^4 I 以飞凌嵌入式 T507 开发板 为例,T507 安全上下文文件路径如下:
$ S C0 ]* W: W% |5 q device/softwinner/common/sepolicy/vendor/property_contexts
* I3 P- F/ _) T device/softwinner/common/sepolicy/vendor/file_contexts
$ d2 D6 h6 c/ Y7 D: _5 Q SEAndroid app分类 SELinux(或SEAndroid)将app划分为主要三种类型(根据user不同,也有其他的domain类型):
3 O+ y* C& N- x9 Q1 n2 Q K 1)untrusted_app 第三方app,没有Android平台签名,没有system权限+ x7 O" r7 b. K r7 u4 a4 r6 U: t
2)platform_app 有android平台签名,没有system权限* s4 k+ k$ x! t$ Z
3)system_app 有android平台签名和system权限, z# G* W7 y' h. _1 F& x
从上面划分,权限等级,理论上:untrusted_app < platform_app < system_app
! b! x8 q$ \# t" |5 O- q APP的domain和type 查看seapp_contexts文件,APP的domain和type由user和seinfo两个参数决定0 W/ k, S" p$ j
system/sepolicy/private/seapp_contexts
" c! F' y8 W6 d6 x, a+ }/ z7 t isSystemServer=true domain=system_server_startup4 B2 i% y3 G$ @" r4 x! m; j. v+ g# Q
user=_app seinfo=platform name=com.android.traceur domain=traceur_app type=app_data_file levelFrom=all" a. y C2 w7 H
user=system seinfo=platform domain=system_app type=system_app_data_file5 L- T3 ?- s1 z% L3 f; L
user=bluetooth seinfo=platform domain=bluetooth type=bluetooth_data_file
, l6 r4 Q- L% D1 C+ r% s) u' Q# W% d7 Q user=network_stack seinfo=network_stack domain=network_stack levelFrom=all 1 G' ?& [/ Y6 S7 F) Q' ]
type=radio_data_file6 b* M( [9 i% i$ V
user=nfc seinfo=platform domain=nfc type=nfc_data_file
; C! I1 g) ~) Q. A$ H2 q user=secure_element seinfo=platform domain=secure_element levelFrom=all
+ w9 A: K5 O0 j0 E% y user=radio seinfo=platform domain=radio type=radio_data_file' a3 B3 G3 X7 D7 K0 r" M9 w3 k
user=shared_relro domain=shared_relro5 c' p- o; u5 O
user=shell seinfo=platform domain=shell name=com.android.shell type=shell_data_file; j+ D( w8 D% x2 `! k7 J/ @
user=webview_zygote seinfo=webview_zygote domain=webview_zygote& e6 K+ f2 p# L
user=_isolated domain=isolated_app levelFrom=al
* m$ i1 A/ W# [/ h& l luser=_app seinfo=app_zygote domain=app_zygote levelFrom=all% p/ C6 R4 }) K; Q! t! w1 X/ R- m
user=_app seinfo=media domain=mediaprovider name=android.process.media type=app_data_file 5 ~5 D9 d+ J6 N
levelFrom=user
) H1 W6 w. k4 e1 B5 h9 u, b user=_app seinfo=platform domain=platform_app type=app_data_file levelFrom=user
; M* o( Z% _8 t0 B6 ]# e+ Z user=_app isEphemeralApp=true domain=ephemeral_app type=app_data_file levelFrom=all
9 V- C5 J$ r$ M9 y: ^ user=_app isPrivApp=true domain=priv_app type=privapp_data_file levelFrom=user
2 {* t) G! K& a3 k: ~( ~8 ^/ p user=_app minTargetSdkVersion=29 domain=untrusted_app type=app_data_file levelFrom=all. }( ]7 [# F) {
user=_app minTargetSdkVersion=28 domain=untrusted_app_27 type=app_data_file levelFrom=all
+ S& A& n; F" b) C. u8 h user=_app minTargetSdkVersion=26 domain=untrusted_app_27 type=app_data_file
?! X. Q( w& z1 P7 D, T levelFrom=user6 U" i1 m, c l# ^, J Y
user=_app domain=untrusted_app_25 type=app_data_file levelFrom=user# }/ N+ T4 \3 I, ~# a' @
user=_app minTargetSdkVersion=28 fromRunAs=true domain=runas_app levelFrom=all
, g6 f; e. x9 o/ s8 l: @: u user=_app fromRunAs=true domain=runas_app levelFrom=user
8 B' D9 _: ^2 j$ z8 q" L1 {- c user 参考链接:https://blog.csdn.net/huilin9960/article/details/81530568; s1 b7 S: f* I+ y; u7 g
user可以理解为UID。android的UID和linux的UID根本是两回事,Linux的UID是用于针对多用户操作系统中用于区分用户的,而Android中的UID是用于系统进行权限管理的。参考链接中的文章对于uid的产生讲的很清楚。. T% \3 D- w6 V- z
seinfo 不同签名会创建对应的selinux上下文。
4 T$ `3 D' ?1 S+ X* E! P6 F Android.mk4 j: J& ^, \3 G& b ?' q" ?
LOCAL_CERTIFICATE := platform
/ d5 L. I/ A1 l2 \. d8 J 有platform签名,所以seinfo是platform。
$ T3 N: h& K" [. c! F LOCAL_CERTIFICATE作用 参考文档https://blog.csdn.net/hnlgzb/article/details/107823874
: \8 V8 F9 K! W+ G- Z2 Z, ~- J* } 可以查看Android源码build/target/product/security/ 目录下提供的默认签名文件,不同平台可能会有差异:飞凌嵌入式 T507 开发板 提供了media、networkstack、platform、shared、testkey、verity六种不同权限的签名文件。
& T/ r2 M! u7 j' F( { # H. U) r& E( }- R. ~% r
以飞凌嵌入式 T507 开发板 为例,查看当前运行的应用信息:
2 C" ^) B, X) X console:/ # ps -Z& t: V% ~. [" a; b( d
u:r:system_app:s0 system 15712 1861 1050628 110868 SyS_epoll_wait
7 {! I, r! ^/ C" R I 0 S forlinx.example.app' j" ?8 J& Q2 a- l( q
u:r:untrusted_app_27:s0:c512,c768 u0_a62 30259 1861 1052120 114132 SyS_epoll_wait , O2 ^3 S8 P! E+ F. B% c" b
0 S com.forlinx.changelogo/ y, R% I' ?* Z( y! m( t
当前运行的两个APP,forlinx.example.app的UID(user)是system,拥有platform签名,它的domain和type就是system_app。* T+ r! C! a- _. d
0 d8 g' A4 Z' | k+ V2 x4 J% ^4 S
+ }7 U* [2 ~3 `2 f6 U1 M b& \
1 ?8 T' o, T$ g- F com.forlinx.changelogo没有设置UID使用的默认设置,其UID为u0_a62,并且没有设置签名文件,它的domain和type就是untrusted_app。
7 A- t- w8 C1 S! M T507自定义安全策略 以上面两个运行的app来说,我们为这两个APP添加额外的权限,对应的TE配置文件分别就是system_app.te、untrusted_app.te,对应路径为:
9 l p- B; L8 S6 D; n q/ A device/softwinner/common/sepolicy/vendor/system_app.te# K% r+ d$ w" d3 I5 _
device/softwinner/common/sepolicy/vendor/untrusted_app.te
/ g" Z# o2 q6 @. b9 R9 i+ _7 H& e* C+ n# `& S7 y/ w
以forlinx.example.app为例,我们为其添加can设备的执行权限:
4 x9 \+ ^0 | N7 {$ a1 f% \8 B7 p
OKT507-android-source/android$ vi device/softwinner/common/sepolicy/vendor/system_app.te- u7 ?0 T" k2 h. f) \
...: Z' J: F$ s6 t$ [
allow system_app vendor_shell_exec:file { getattr open read execute execute_no_trans };
5 F1 M& l1 m+ v% \' m" t allow system_app shell_exec:file { getattr open read execute execute_no_trans };# T3 J! L6 `- I4 ]
allow system_app shell:file { getattr open read execute execute_no_trans };; Z+ z" v4 a# o5 Q u) d Q
...( w; l3 z+ n. P. c4 I" O
以策略规则配置形式(allow domains types:classes permissions)
. ~/ y( { A% z+ Z 分析:domains:system_app
% H. Y% h% L% p, g, _ types:vendor_shell_exec
. T+ S* T" x% Z; ]5 u8 P8 ~ classes:file" |/ Y3 u1 i U: R
permissions:getattr open read execute execute_no_trans, Y* C* ~; _( g% }8 L; ]1 j3 O1 D% d% g
neverallow failures 有时我们增加的权限,系统默认的配置是不允许的,比如我们上面给forlinx.example.app增加的执行脚本的权限,报错如下:0 z% O0 o% P5 S
) D9 Q1 d9 ^ C m/ [( Z- x7 v
libsepol.report_failure: neverallow on line 9 of system/sepolicy/private/system_app.te
" f# K* P A6 m (or line 41463 of policy.conf) violated by allow system_app shell:file { read open };
9 q3 T8 B( f- s' A$ h( _$ O libsepol.report_failure: neverallow on line 22 of system/sepolicy/private/shell.te
3 i/ A: M3 h6 X" @ (or line 40025 of policy.conf) violated by allow system_app shell:file { read open };
$ H& i$ C' g0 I. z; m8 R libsepol.check_assertions: 2 neverallow failures occurred! N: z& M+ y( S1 [( x
" D+ R6 V! ~. r8 M 系统默认的安全策略的路径为system/sepolicy/,根据报错的提示,我们可以修改默认的配置,修改system/sepolicy/private/system_app.te和system/sepolicy/private/shell.te,从而完成权限的赋予。* e8 Y1 c6 j: S/ C6 ?
0 K8 C# l" X5 L$ T
以上就是Android 安全策略的脉络,以及飞凌嵌入式 T507 开发板 Android系统下自定义安全策略的方法了。! q) I7 d/ w" O
+ c! |; b1 ~! p2 W( J3 ~& u0 N
|
|