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

扫一扫,手机访问本帖 
|
硬件平台:飞凌嵌入式 OKT507-C开发板% |0 c+ x" y8 S1 C" B
操作系统:Android10.0& `8 ?5 V" m; a! I
" S6 h6 m: {# n' y8 f- p 飞凌嵌入式 T507 开发板 Android系统版本为Android10.0,默认开启了SELinux。基于MAC访问控制模型的SElinux,可以更好地保护我们的Android系统, 比如限制系统服务的访问权限、控制应用对数据和系统日志的访问等措施,这样就降低了恶意软件的影响,并且可以防止因代码存在的缺陷而产生的对系统安全的影响。+ b& \5 [& ]" m4 N* L" R
从系统安全方面考虑,SELinux是保护神,但是从软件开发方面,SELinux就是一道牵绊,这是一把双刃剑。
$ g% X/ r2 J! B4 F: F
+ O, w: g6 q( k 比如我们开发应用或者增加系统服务的某些权限的时候,我们必须遵循SELinux的规则,给我们的应用设置对应的安全策略,否则我们的应用就不具备访问数据或者设备的权限。下面我们MAC访问控制模型开始,简单的梳理一下飞凌嵌入式 T507 开发板 Android的安全策略,以及自定义飞凌嵌入式 T507 开发板 Android安全策略的方法。
- R( K! ]' j' R 访问控制模型DAC,MAC 访问控制是指控制对计算机或者网络中某个资源的访问。没有它,所有人都可以访问任何资源。有了访问控制,用户在获取实际访问资源或进行操作之前,必须通过识别、验证、授权。: g- p( o" q& O! m* R8 n
自主访问控制(DAC: Discretionary Access Control)系统识别用户,根据被操作对象的权限的设置,来决定该用户对其拥有的操作权限,read、write、exec。拥有这个对象权限的用户,又可以将该权限分配给其他用户,此谓之“Discretionary”。缺陷就是对权限控制比较分散,不便于管理,比如无法简单地将一组文件设置统一的权限开放给指定的一群用户。
@5 c) P5 ]( L. t# y' Z 强制访问控制(MAC: Mandatory Access Control)MAC是为了弥补DAC权限控制过于分散的问题而诞生的。在MAC这种模型里,管理员管理访问控制。管理员制定策略,用户不能改变它。策略定义了哪个主体能访问哪个对象。这种访问控制模型可以增加安全级别,因为它基于策略,任何没有被显式授权的操作都不能执行。MAC被开发和实现在最重视保密的系统中,如军事系统。主体获得清楚的标记,对象得到分类标记,或称安全级别。! [- }( z! b! O, K9 u7 S
基于MAC的SElinux 参考链接:https://source.android.google.cn/security/selinux7 n0 ?. i5 ]$ U Y0 w% D2 }
软件通常情况下必须以 Root 用户帐号的身份运行,才能向原始块设备写入数据。在基于 DAC 的传统 Linux 环境中,如果 Root 用户遭到入侵,攻击者便可以利用该用户身份向每个原始块设备写入数据。从 Android 4.3 起,SELinux 开始为传统的自主访问控制 (DAC) 环境提供强制访问控制 (MAC) 保护功能。作为 Android 安全模型的一部分,Android 使用安全增强型 Linux (SELinux) 对所有进程强制执行强制访问控制 (MAC),甚至包括以 Root/超级用户权限运行的进程(Linux 功能)。例如,可以使用 SELinux 为这些设备添加标签,以便被分配了 Root 权限的进程只能向相关政策中指定的设备写入数据。这样一来,该进程便无法重写特定原始块设备之外的数据和系统设置。借助 SELinux,Android 可以更好地保护和限制系统服务、控制对应用数据和系统日志的访问、降低恶意软件的影响,并保护用户免遭移动设备上的代码可能存在的缺陷的影响。) O0 o* C5 A& `# a v
4 @) w1 S0 p: f( v7 a1 \# m0 A* z' m0 s- d8 J
飞凌嵌入式 T507 开发板 Android系统版本为Android10,SELinux默认开启,即使获得了该系统的root权限,也只能向相关策略中指定的设备写入数据,从而更好地保护和限制系统服务,保障系统和数据的安全。
0 k7 j+ E' D. o5 z9 y* c3 K 标签、规则和域 SELinux 依靠标签来匹配操作和策略。标签用于决定允许的事项。套接字、文件和进程在 SELinux 中都有标签。SELinux 在做决定时需参照两点:一是为这些对象分配的标签,二是定义这些对象如何交互的策略。
* i& |) y% x1 {' `# j, \/ } e 在 SELinux 中,标签采用以下形式:user:role:type:mls_level,其中 type 是访问决定的主要组成部分,可通过构成标签的其他组成部分进行修改。对象会映射到类,对每个类的不同访问类型由权限表示。
5 Y1 v5 h: K" S4 M( ` 策略规则采用以下形式:allow domains types:classes permissions;,其中:
3 O, p" Y# U+ m- V( x" E2 l) Q. U7 ~4 `9 k, u- b2 `+ i3 z
Domain - 一个进程或一组进程的标签。也称为域类型,因为它只是指进程的类型。" b5 D2 a4 P: G
Type - 一个对象(例如,文件、套接字)或一组对象的标签。
7 p1 d6 P) w1 Z+ T& d Class - 要访问的对象(例如,文件、套接字)的类型。Permission - 要执行的操作(例如,读取、写入)。' E; o1 R3 d; q2 \
策略配置源文件 1、external/sepolicy
# }5 `0 x: v$ ]/ V, l O, C4 {6 c 这是独立于设备的配置,一般不能针对设备进行修改
/ }5 C: o {) r* j3 Q4 t* m
# A) z" i H t8 C% y 2、device/<vendor>/<product>/sepolicy
* D) E( }' N' G- g D' n6 ` 这是特定于设备的配置,基于 BOARD_SEPOLICY_* 变量来选择对应平台的策略配置。3 |, v8 _% u ^( s
' w$ _+ U+ x8 R
以飞凌嵌入式 T507 开发板 为例,T507策略文件的路径如下:- h: h: c0 L; ]5 @/ j
OKT507-android-source/android$ ls device/softwinner/common/sepolicy/private vendor8 w: ]) G: z# J; Z
Type Enforcement (TE) 配置文件 .te 文件中保存了对应对象的域和类型定义、规则。通常每个域一个 .te 文件,例如installd.te。在 device.te、file.te 中声明了设备和文件类型。在某些文件(例如domain.te、app.te)中则存储着共享规则。
* c6 T2 M: u6 X. y; ?* I
& b, N6 s" B7 m 以飞凌嵌入式 T507 开发板 为例,T507 system_app的TE文件的路径如下:
Y+ }7 e B0 f* r3 D' y" m device/softwinner/common/sepolicy/vendor/system_app.te: r* j: n" w8 X& h% K/ S6 }8 E4 D/ x' H
标签配置文件 1、file_contexts:文件安全上下文
) f7 u5 E4 H0 I 2、property_contexts:属性安全上下文5 ]4 o. i7 D5 I
1 Z6 R: }2 U( s; Y: C" ^ 以飞凌嵌入式 T507 开发板 为例,T507 安全上下文文件路径如下:" t3 F1 b) I, G% a3 P
device/softwinner/common/sepolicy/vendor/property_contexts, S; H7 n m* D' l1 s* u
device/softwinner/common/sepolicy/vendor/file_contexts
- T4 Y; D6 [; m( p$ x6 h+ a SEAndroid app分类 SELinux(或SEAndroid)将app划分为主要三种类型(根据user不同,也有其他的domain类型):* Y k, @- ?7 n- t3 ^- x# _
1)untrusted_app 第三方app,没有Android平台签名,没有system权限
+ _, C, e& g/ ]( z! D9 T' g5 s4 T 2)platform_app 有android平台签名,没有system权限. ~: v% R$ p% Y- ?, e7 }" }& `1 L
3)system_app 有android平台签名和system权限8 U4 s, m3 w% i7 E: J- V6 N/ r
从上面划分,权限等级,理论上:untrusted_app < platform_app < system_app& A' O0 R& m' J, g% h
APP的domain和type 查看seapp_contexts文件,APP的domain和type由user和seinfo两个参数决定
" A5 V; G! Z. Q) c system/sepolicy/private/seapp_contexts
4 z" @0 u7 @8 ?) u- } isSystemServer=true domain=system_server_startup& ]& [# b8 v( l9 T, Z }) l5 \
user=_app seinfo=platform name=com.android.traceur domain=traceur_app type=app_data_file levelFrom=all
! L2 B3 ]% I( J% r H1 n" U4 @2 c user=system seinfo=platform domain=system_app type=system_app_data_file
, v [- k& u# O; F5 ? user=bluetooth seinfo=platform domain=bluetooth type=bluetooth_data_file
3 @; g1 }9 n) u+ S user=network_stack seinfo=network_stack domain=network_stack levelFrom=all 9 H. t3 z3 G* h- ]. Z
type=radio_data_file
- h. Y! Z9 g6 v. V user=nfc seinfo=platform domain=nfc type=nfc_data_file
+ ^7 z( x+ m/ U" S2 G% Q U4 [7 J user=secure_element seinfo=platform domain=secure_element levelFrom=all
* F8 g! X' A& s6 d5 d user=radio seinfo=platform domain=radio type=radio_data_file
" o* V! D0 B: w+ h" F$ `5 z1 m user=shared_relro domain=shared_relro
( ?4 u% E) B* p. U$ B user=shell seinfo=platform domain=shell name=com.android.shell type=shell_data_file% M/ Y% b" s7 r Y* k
user=webview_zygote seinfo=webview_zygote domain=webview_zygote
" r' J2 k& o7 O5 j* I. @) j user=_isolated domain=isolated_app levelFrom=al
, G1 s X1 } k* p% ]: _ luser=_app seinfo=app_zygote domain=app_zygote levelFrom=all
8 ]& n5 _/ W% B, R! P) i user=_app seinfo=media domain=mediaprovider name=android.process.media type=app_data_file
1 r9 \1 R: E+ u$ x& O levelFrom=user% y+ V6 r) p: M' ]+ p
user=_app seinfo=platform domain=platform_app type=app_data_file levelFrom=user% f: a! f; z1 x
user=_app isEphemeralApp=true domain=ephemeral_app type=app_data_file levelFrom=all8 W% }2 ?+ @" ^' G2 C6 T" b2 j. {
user=_app isPrivApp=true domain=priv_app type=privapp_data_file levelFrom=user! M8 Y+ H1 o! }4 Q+ p1 w5 h& D
user=_app minTargetSdkVersion=29 domain=untrusted_app type=app_data_file levelFrom=all! q4 K7 W- L4 M/ l
user=_app minTargetSdkVersion=28 domain=untrusted_app_27 type=app_data_file levelFrom=all. M7 J. z; v" j6 S/ e3 ^4 y" r
user=_app minTargetSdkVersion=26 domain=untrusted_app_27 type=app_data_file 6 _" B$ w. \# `2 \3 @
levelFrom=user2 Q( b7 k1 A' x& h0 _: S) s5 ]
user=_app domain=untrusted_app_25 type=app_data_file levelFrom=user
4 c; {& V- h6 u- u9 z7 A" ? user=_app minTargetSdkVersion=28 fromRunAs=true domain=runas_app levelFrom=all
( a! z! a. W; D user=_app fromRunAs=true domain=runas_app levelFrom=user9 F2 {- _; r% b9 K. Z" ]
user 参考链接:https://blog.csdn.net/huilin9960/article/details/81530568
2 p: N: p- ~9 `: U user可以理解为UID。android的UID和linux的UID根本是两回事,Linux的UID是用于针对多用户操作系统中用于区分用户的,而Android中的UID是用于系统进行权限管理的。参考链接中的文章对于uid的产生讲的很清楚。5 r* d. u; z, j' U- ~1 O* K+ w
seinfo 不同签名会创建对应的selinux上下文。' D! ]8 q" P6 Q$ n
Android.mk
" q( j/ h6 l, u* [ LOCAL_CERTIFICATE := platform
* I3 K6 _- |* R1 R/ [; U, W 有platform签名,所以seinfo是platform。+ E- x0 q. z1 w3 A2 F2 `
LOCAL_CERTIFICATE作用 参考文档https://blog.csdn.net/hnlgzb/article/details/107823874
) w( B: y3 z1 v; Y9 U% l3 r' B 可以查看Android源码build/target/product/security/ 目录下提供的默认签名文件,不同平台可能会有差异:飞凌嵌入式 T507 开发板 提供了media、networkstack、platform、shared、testkey、verity六种不同权限的签名文件。
. O1 o6 L+ A7 }+ X7 r
7 \* U) a2 R5 I' N) p) f- S$ g$ s# @# [9 A 以飞凌嵌入式 T507 开发板 为例,查看当前运行的应用信息:
7 ~8 f' G; c- U. F% X; k+ S console:/ # ps -Z; ]7 C: o' |2 Y6 u; W' q) _* x
u:r:system_app:s0 system 15712 1861 1050628 110868 SyS_epoll_wait
' D, Z5 t7 E& F9 P0 j: \ 0 S forlinx.example.app
% ^) q: Z8 |; h0 ^' x4 ^3 x( f2 N# |/ j u:r:untrusted_app_27:s0:c512,c768 u0_a62 30259 1861 1052120 114132 SyS_epoll_wait
& G8 X5 m" f- e) p' ]3 @0 V$ Z3 V 0 S com.forlinx.changelogo, N, r, U6 b* m$ t0 O4 C2 [, D
当前运行的两个APP,forlinx.example.app的UID(user)是system,拥有platform签名,它的domain和type就是system_app。
- h c5 ~# y+ ^ I! |5 y( U* Y0 N Q& A
* b& e/ |0 T0 k0 f
6 A; Q5 \8 v8 ?% r3 t2 q& f% l com.forlinx.changelogo没有设置UID使用的默认设置,其UID为u0_a62,并且没有设置签名文件,它的domain和type就是untrusted_app。
$ e, [* I, v8 ` T507自定义安全策略 以上面两个运行的app来说,我们为这两个APP添加额外的权限,对应的TE配置文件分别就是system_app.te、untrusted_app.te,对应路径为:
% z( y( m* t' ?4 q# S9 U device/softwinner/common/sepolicy/vendor/system_app.te5 N6 h- A( W" N0 m. o- v. s
device/softwinner/common/sepolicy/vendor/untrusted_app.te7 h; U5 E9 K! ?
5 x1 i! O+ X+ V' M; G
以forlinx.example.app为例,我们为其添加can设备的执行权限:0 u8 E+ n! M F2 T
" Y: o ?0 @2 [: E
OKT507-android-source/android$ vi device/softwinner/common/sepolicy/vendor/system_app.te+ [* P* d9 m7 d I6 s J7 K( c
...
% E( W* g1 D- t allow system_app vendor_shell_exec:file { getattr open read execute execute_no_trans };
( g8 |) Y& D. ^7 a, [* j- ^ allow system_app shell_exec:file { getattr open read execute execute_no_trans };
) @. q, V6 n. S! r9 w1 H- M0 F allow system_app shell:file { getattr open read execute execute_no_trans };) Z* H* q! T& n3 l
...+ w5 ?6 {1 M1 i( R" l, R
以策略规则配置形式(allow domains types:classes permissions)1 R# B* b- P( c
分析:domains:system_app k& J) @3 o8 W, ?, r
types:vendor_shell_exec% v: C/ [+ Z; V* e
classes:file
; {1 Y6 g( ^0 A j3 W0 o% a permissions:getattr open read execute execute_no_trans
- o' S/ W) c4 q, u neverallow failures 有时我们增加的权限,系统默认的配置是不允许的,比如我们上面给forlinx.example.app增加的执行脚本的权限,报错如下:; F2 m' O& g/ O3 V/ O) [, g# h& ^
8 K+ m$ M% [0 ^# y V
libsepol.report_failure: neverallow on line 9 of system/sepolicy/private/system_app.te
$ F7 \& v3 N) N0 i! w, r (or line 41463 of policy.conf) violated by allow system_app shell:file { read open };, v. \" l) s1 d v' O0 Y5 d
libsepol.report_failure: neverallow on line 22 of system/sepolicy/private/shell.te! W6 {$ c* E4 Q% f; N* V) B) j
(or line 40025 of policy.conf) violated by allow system_app shell:file { read open };, s9 J0 m% h/ u+ `
libsepol.check_assertions: 2 neverallow failures occurred
) Q8 Z* o# `! E1 q5 z! {: S9 C3 Y0 D% c3 @. F* M8 R* K* t5 T- \
系统默认的安全策略的路径为system/sepolicy/,根据报错的提示,我们可以修改默认的配置,修改system/sepolicy/private/system_app.te和system/sepolicy/private/shell.te,从而完成权限的赋予。
1 s |# V) v0 [4 d$ E: J: r9 E5 Z1 Y, x' X9 o R' e. h$ ?
以上就是Android 安全策略的脉络,以及飞凌嵌入式 T507 开发板 Android系统下自定义安全策略的方法了。
, w% R$ ]% J2 M9 e7 P
9 D& e g4 k Z( k, T3 y) Z |
|