- 积分
- 304
贡献1459
飞刀573 FD
注册时间2015-12-21
在线时间51 小时

扫一扫,手机访问本帖 
|
硬件平台:飞凌嵌入式 OKT507-C开发板
, X0 l; A9 B& S+ k# } d, ^2 v' y+ g 操作系统:Android10.06 v$ A4 Q3 K0 n" q/ b T% l
$ d' c1 w, Y; i2 [, b# x9 c" f 飞凌嵌入式 T507 开发板 Android系统版本为Android10.0,默认开启了SELinux。基于MAC访问控制模型的SElinux,可以更好地保护我们的Android系统, 比如限制系统服务的访问权限、控制应用对数据和系统日志的访问等措施,这样就降低了恶意软件的影响,并且可以防止因代码存在的缺陷而产生的对系统安全的影响。
& j& a6 x+ r @% h 从系统安全方面考虑,SELinux是保护神,但是从软件开发方面,SELinux就是一道牵绊,这是一把双刃剑。
* Q/ j3 |. S& ` m1 U/ E 8 H) x1 S; l& ?
比如我们开发应用或者增加系统服务的某些权限的时候,我们必须遵循SELinux的规则,给我们的应用设置对应的安全策略,否则我们的应用就不具备访问数据或者设备的权限。下面我们MAC访问控制模型开始,简单的梳理一下飞凌嵌入式 T507 开发板 Android的安全策略,以及自定义飞凌嵌入式 T507 开发板 Android安全策略的方法。
' d! P. m" Y. l8 u6 I' M 访问控制模型DAC,MAC 访问控制是指控制对计算机或者网络中某个资源的访问。没有它,所有人都可以访问任何资源。有了访问控制,用户在获取实际访问资源或进行操作之前,必须通过识别、验证、授权。
' o8 p6 t2 A; c% e$ F- D0 [+ {3 Q' ] 自主访问控制(DAC: Discretionary Access Control)系统识别用户,根据被操作对象的权限的设置,来决定该用户对其拥有的操作权限,read、write、exec。拥有这个对象权限的用户,又可以将该权限分配给其他用户,此谓之“Discretionary”。缺陷就是对权限控制比较分散,不便于管理,比如无法简单地将一组文件设置统一的权限开放给指定的一群用户。
1 @- S7 ]2 R \, V7 g, x" ~$ U 强制访问控制(MAC: Mandatory Access Control)MAC是为了弥补DAC权限控制过于分散的问题而诞生的。在MAC这种模型里,管理员管理访问控制。管理员制定策略,用户不能改变它。策略定义了哪个主体能访问哪个对象。这种访问控制模型可以增加安全级别,因为它基于策略,任何没有被显式授权的操作都不能执行。MAC被开发和实现在最重视保密的系统中,如军事系统。主体获得清楚的标记,对象得到分类标记,或称安全级别。( k7 u0 X; M, i0 u! N6 O
基于MAC的SElinux 参考链接:https://source.android.google.cn/security/selinux' @; F8 k. J; \3 j
软件通常情况下必须以 Root 用户帐号的身份运行,才能向原始块设备写入数据。在基于 DAC 的传统 Linux 环境中,如果 Root 用户遭到入侵,攻击者便可以利用该用户身份向每个原始块设备写入数据。从 Android 4.3 起,SELinux 开始为传统的自主访问控制 (DAC) 环境提供强制访问控制 (MAC) 保护功能。作为 Android 安全模型的一部分,Android 使用安全增强型 Linux (SELinux) 对所有进程强制执行强制访问控制 (MAC),甚至包括以 Root/超级用户权限运行的进程(Linux 功能)。例如,可以使用 SELinux 为这些设备添加标签,以便被分配了 Root 权限的进程只能向相关政策中指定的设备写入数据。这样一来,该进程便无法重写特定原始块设备之外的数据和系统设置。借助 SELinux,Android 可以更好地保护和限制系统服务、控制对应用数据和系统日志的访问、降低恶意软件的影响,并保护用户免遭移动设备上的代码可能存在的缺陷的影响。* u$ \* b5 _7 {8 I
+ \! R4 v* o$ Z5 m+ t+ {2 F7 D' ~$ G# c$ K4 W1 h, m! _& R
飞凌嵌入式 T507 开发板 Android系统版本为Android10,SELinux默认开启,即使获得了该系统的root权限,也只能向相关策略中指定的设备写入数据,从而更好地保护和限制系统服务,保障系统和数据的安全。
* }9 t2 X' x) S) W: n9 a 标签、规则和域 SELinux 依靠标签来匹配操作和策略。标签用于决定允许的事项。套接字、文件和进程在 SELinux 中都有标签。SELinux 在做决定时需参照两点:一是为这些对象分配的标签,二是定义这些对象如何交互的策略。# f# I# m% B& b. B/ P$ R4 ] a
在 SELinux 中,标签采用以下形式:user:role:type:mls_level,其中 type 是访问决定的主要组成部分,可通过构成标签的其他组成部分进行修改。对象会映射到类,对每个类的不同访问类型由权限表示。
/ g4 c- U R2 g/ x 策略规则采用以下形式:allow domains types:classes permissions;,其中:0 j3 i3 A( D$ M
0 F3 @2 T# m$ `! z
Domain - 一个进程或一组进程的标签。也称为域类型,因为它只是指进程的类型。
5 V5 i+ u9 O, Z Type - 一个对象(例如,文件、套接字)或一组对象的标签。: c! b) v- M, F; Y4 R$ Z
Class - 要访问的对象(例如,文件、套接字)的类型。Permission - 要执行的操作(例如,读取、写入)。
3 S& W! U" Y5 R' ^ R 策略配置源文件 1、external/sepolicy" | z/ X( x1 x2 r- V0 X4 h
这是独立于设备的配置,一般不能针对设备进行修改
8 i4 m! Y$ f, y. n* u7 r' U# G8 h2 E( o5 O3 H
2、device/<vendor>/<product>/sepolicy2 p: {+ I8 M- S0 i! o" a) W& D4 N
这是特定于设备的配置,基于 BOARD_SEPOLICY_* 变量来选择对应平台的策略配置。( f6 S" p3 l# K$ J$ \& c& a
( D7 q7 W3 W$ C. h9 P
以飞凌嵌入式 T507 开发板 为例,T507策略文件的路径如下:
5 |* B( U3 K" s) ^ OKT507-android-source/android$ ls device/softwinner/common/sepolicy/private vendor
4 \% O7 D, B& B- p( a Type Enforcement (TE) 配置文件 .te 文件中保存了对应对象的域和类型定义、规则。通常每个域一个 .te 文件,例如installd.te。在 device.te、file.te 中声明了设备和文件类型。在某些文件(例如domain.te、app.te)中则存储着共享规则。) R, G8 p; w: p8 w& z1 Y
5 `2 ?7 c. Z3 K7 w+ {( q6 J 以飞凌嵌入式 T507 开发板 为例,T507 system_app的TE文件的路径如下:
! L" ~0 X! `" a ~ device/softwinner/common/sepolicy/vendor/system_app.te' g U$ H! f% |- b4 o+ q% |
标签配置文件 1、file_contexts:文件安全上下文+ c% R. }) U$ d& C9 p6 ]$ p/ `
2、property_contexts:属性安全上下文* T& W% S7 a- P a& J% }# s
, @3 O8 |* B9 _6 @' Z( W( p
以飞凌嵌入式 T507 开发板 为例,T507 安全上下文文件路径如下:
1 }0 ^5 O* s1 v/ }: P9 ^! U device/softwinner/common/sepolicy/vendor/property_contexts% m' X% w. G8 o0 i# X# Z0 s
device/softwinner/common/sepolicy/vendor/file_contexts
+ O5 ]7 {- L" ?. y" U3 Y4 t SEAndroid app分类 SELinux(或SEAndroid)将app划分为主要三种类型(根据user不同,也有其他的domain类型):
& w7 n( j* _8 X+ t3 ^2 g 1)untrusted_app 第三方app,没有Android平台签名,没有system权限7 {" y( d. m- ^1 X% q8 r
2)platform_app 有android平台签名,没有system权限
' p; T% L0 K5 s4 ~" n) f 3)system_app 有android平台签名和system权限 V! n5 L% ~/ N9 z5 j% o8 F
从上面划分,权限等级,理论上:untrusted_app < platform_app < system_app
C) b+ `9 X4 U# i. N0 d APP的domain和type 查看seapp_contexts文件,APP的domain和type由user和seinfo两个参数决定
7 }! j: a1 I, @+ v system/sepolicy/private/seapp_contexts
* B5 L6 K) W) Q& ] isSystemServer=true domain=system_server_startup0 f2 v _7 B$ z1 u5 D3 d
user=_app seinfo=platform name=com.android.traceur domain=traceur_app type=app_data_file levelFrom=all- Y# x- ~4 l- q. K1 p w7 g2 x
user=system seinfo=platform domain=system_app type=system_app_data_file' E" p0 `3 |6 o7 W) Y1 y
user=bluetooth seinfo=platform domain=bluetooth type=bluetooth_data_file, U5 |6 p' \6 v5 W2 {/ p
user=network_stack seinfo=network_stack domain=network_stack levelFrom=all + B* _; o3 j. A+ Z
type=radio_data_file. J! S# r5 [& K( J$ N7 L3 {
user=nfc seinfo=platform domain=nfc type=nfc_data_file
& q- Z% T2 S4 l9 ^4 o3 ` user=secure_element seinfo=platform domain=secure_element levelFrom=all7 p* T( a; Q# H8 g/ F: f9 Q" q9 O3 Y
user=radio seinfo=platform domain=radio type=radio_data_file. d# S8 k; N& L/ f, G4 B4 |
user=shared_relro domain=shared_relro
% Q5 n1 u2 c! [( \ c6 u7 g user=shell seinfo=platform domain=shell name=com.android.shell type=shell_data_file
" x+ V8 R( b2 e% q3 \. X user=webview_zygote seinfo=webview_zygote domain=webview_zygote
' \2 r3 z2 K0 |# x% l user=_isolated domain=isolated_app levelFrom=al% }2 Q% f7 K8 ^, X
luser=_app seinfo=app_zygote domain=app_zygote levelFrom=all
1 n$ G& X+ k3 n, |' u+ y% Q user=_app seinfo=media domain=mediaprovider name=android.process.media type=app_data_file
3 e+ |+ k# j$ C. y) k8 k3 h8 A' b levelFrom=user
7 b! f2 P/ H5 q) b user=_app seinfo=platform domain=platform_app type=app_data_file levelFrom=user
' E9 G8 D" U. K9 u$ m+ m user=_app isEphemeralApp=true domain=ephemeral_app type=app_data_file levelFrom=all
) }! j: O" a2 ^* k user=_app isPrivApp=true domain=priv_app type=privapp_data_file levelFrom=user
) x( ~! ^4 Z: F- d user=_app minTargetSdkVersion=29 domain=untrusted_app type=app_data_file levelFrom=all
$ H& F5 f* ?4 q$ ]$ } user=_app minTargetSdkVersion=28 domain=untrusted_app_27 type=app_data_file levelFrom=all2 q( ]9 A `. h
user=_app minTargetSdkVersion=26 domain=untrusted_app_27 type=app_data_file
- X3 f. i4 R# _0 I/ L; L( S levelFrom=user4 s# H$ m" v+ K/ I( S
user=_app domain=untrusted_app_25 type=app_data_file levelFrom=user3 `, }3 S5 g" ~# k2 R2 \* U1 u( E
user=_app minTargetSdkVersion=28 fromRunAs=true domain=runas_app levelFrom=all
$ U& Q' h) {7 m. E4 S& \ user=_app fromRunAs=true domain=runas_app levelFrom=user
3 h. X _2 ^- c3 D! b user 参考链接:https://blog.csdn.net/huilin9960/article/details/81530568
% W# t, y8 a. D8 v0 ?$ p user可以理解为UID。android的UID和linux的UID根本是两回事,Linux的UID是用于针对多用户操作系统中用于区分用户的,而Android中的UID是用于系统进行权限管理的。参考链接中的文章对于uid的产生讲的很清楚。
9 ?$ x4 T3 K, v seinfo 不同签名会创建对应的selinux上下文。4 r" J# k* X4 E! j0 m) ]8 q" C. q& z
Android.mk8 `& x, _* ^6 \
LOCAL_CERTIFICATE := platform- {* }7 v) H3 t& E* H% P" P
有platform签名,所以seinfo是platform。
# b% g9 o( R u1 K1 ] LOCAL_CERTIFICATE作用 参考文档https://blog.csdn.net/hnlgzb/article/details/107823874% }! B, a" Z+ i( ]
可以查看Android源码build/target/product/security/ 目录下提供的默认签名文件,不同平台可能会有差异:飞凌嵌入式 T507 开发板 提供了media、networkstack、platform、shared、testkey、verity六种不同权限的签名文件。
2 i) q+ N* \3 n& p$ k3 A
9 r" w* \# P% J" ~ 以飞凌嵌入式 T507 开发板 为例,查看当前运行的应用信息:
- b C$ h& |) c: Z+ d console:/ # ps -Z
/ m5 t" Y0 \8 K4 m- _ u:r:system_app:s0 system 15712 1861 1050628 110868 SyS_epoll_wait 7 u ]7 b) U+ V) `- U1 T9 P
0 S forlinx.example.app. J; q0 K* f, Q
u:r:untrusted_app_27:s0:c512,c768 u0_a62 30259 1861 1052120 114132 SyS_epoll_wait
' b/ F. l& z) E4 g 0 S com.forlinx.changelogo! W/ G) T% J( H$ I" o8 _
当前运行的两个APP,forlinx.example.app的UID(user)是system,拥有platform签名,它的domain和type就是system_app。
] _( H- M6 z: Z1 e& I
- A/ Y. {- _3 y2 l0 s9 I+ \) I
: P$ m9 g' ]7 `( n1 h, P 6 `$ V, C7 `* d# f0 i! s
com.forlinx.changelogo没有设置UID使用的默认设置,其UID为u0_a62,并且没有设置签名文件,它的domain和type就是untrusted_app。! j7 W; ^% |& H6 X' }
T507自定义安全策略 以上面两个运行的app来说,我们为这两个APP添加额外的权限,对应的TE配置文件分别就是system_app.te、untrusted_app.te,对应路径为:
( f& ]6 t! j; n device/softwinner/common/sepolicy/vendor/system_app.te
( Z; P: R$ e6 ^ device/softwinner/common/sepolicy/vendor/untrusted_app.te+ J- d- C( u" h4 c' @
) |7 a4 _5 |. y 以forlinx.example.app为例,我们为其添加can设备的执行权限:0 H( ^. M9 n0 g0 ~7 H2 J& l
3 j8 ?" x4 p% M' E OKT507-android-source/android$ vi device/softwinner/common/sepolicy/vendor/system_app.te8 g% F, @& h( d* a' Z2 g
...
0 X% T/ ~5 Z0 i( [. Z9 T allow system_app vendor_shell_exec:file { getattr open read execute execute_no_trans };
' j, U) P( Q! G allow system_app shell_exec:file { getattr open read execute execute_no_trans };" Z' l [; R0 n
allow system_app shell:file { getattr open read execute execute_no_trans };
! ~2 K2 S; V M- t$ F ...
% _, n c: w# t' @! n 以策略规则配置形式(allow domains types:classes permissions)( h, N# n4 b1 j: k+ N! A
分析:domains:system_app/ R+ v5 C, z! ^3 H$ j
types:vendor_shell_exec- x) c" a n4 Q7 \, O2 S9 N; |% Z3 Z! [
classes:file: j4 ^2 }+ w( i, ?" E# m6 U
permissions:getattr open read execute execute_no_trans, `: _8 h. a& c" H6 X
neverallow failures 有时我们增加的权限,系统默认的配置是不允许的,比如我们上面给forlinx.example.app增加的执行脚本的权限,报错如下:; `: M/ g3 F( T
7 n$ S1 P' ]9 l& l* W7 d! `" I libsepol.report_failure: neverallow on line 9 of system/sepolicy/private/system_app.te
- M( W4 Z- N0 A (or line 41463 of policy.conf) violated by allow system_app shell:file { read open };3 v: l" [+ K* C! ?& k6 m* a' v, q$ j
libsepol.report_failure: neverallow on line 22 of system/sepolicy/private/shell.te9 L/ {9 a- I" v* A4 |
(or line 40025 of policy.conf) violated by allow system_app shell:file { read open };% b5 Q8 l5 S/ n* c: O6 r
libsepol.check_assertions: 2 neverallow failures occurred; i" @5 }4 P3 k
" p1 K5 F4 p# J4 V+ O" H5 h
系统默认的安全策略的路径为system/sepolicy/,根据报错的提示,我们可以修改默认的配置,修改system/sepolicy/private/system_app.te和system/sepolicy/private/shell.te,从而完成权限的赋予。! C+ I0 S6 b" s% Y# A- ^! E
- r j; R. |/ g* _, r+ N" k0 m 以上就是Android 安全策略的脉络,以及飞凌嵌入式 T507 开发板 Android系统下自定义安全策略的方法了。
' \$ q1 ?- v3 p1 l% C( A2 e
- E" X, _ E x8 S. E |
|