嵌入式爱好者

查看: 13449|回复: 0

[帮助] 国产平台之T507 开发板Android 安全策略漫谈

[复制链接]

48

主题

55

帖子

305

积分

扫一扫,手机访问本帖
发表于 2021-12-5 17:25:38 | 显示全部楼层 |阅读模式
        硬件平台:飞凌嵌入式 OKT507-C开发板& b/ \- w& c+ e( {+ Z0 }
        操作系统:Android10.0
1 k$ H/ s8 N7 q1 D6 i+ |" F1 n3 E* ]+ z! b4 x# t/ z
                            飞凌嵌入式 T507 开发板 Android系统版本为Android10.0,默认开启了SELinux。基于MAC访问控制模型的SElinux,可以更好地保护我们的Android系统, 比如限制系统服务的访问权限、控制应用对数据和系统日志的访问等措施,这样就降低了恶意软件的影响,并且可以防止因代码存在的缺陷而产生的对系统安全的影响。
3 P8 f) b" ]7 p+ s2 I$ k$ g; R% ^  W        从系统安全方面考虑,SELinux是保护神,但是从软件开发方面,SELinux就是一道牵绊,这是一把双刃剑。
7 j  [" j$ q+ l! y' p$ ^                               
3 [. W: B: J4 G( n' H        比如我们开发应用或者增加系统服务的某些权限的时候,我们必须遵循SELinux的规则,给我们的应用设置对应的安全策略,否则我们的应用就不具备访问数据或者设备的权限。下面我们MAC访问控制模型开始,简单的梳理一下飞凌嵌入式 T507 开发板  Android的安全策略,以及自定义飞凌嵌入式 T507 开发板 Android安全策略的方法。
& [0 @4 f8 i, ]& n, j        访问控制模型DAC,MAC         访问控制是指控制对计算机或者网络中某个资源的访问。没有它,所有人都可以访问任何资源。有了访问控制,用户在获取实际访问资源或进行操作之前,必须通过识别、验证、授权。; a- O) z+ S) U' W; p/ Y5 O9 f0 {
        自主访问控制(DAC: Discretionary Access Control)系统识别用户,根据被操作对象的权限的设置,来决定该用户对其拥有的操作权限,read、write、exec。拥有这个对象权限的用户,又可以将该权限分配给其他用户,此谓之“Discretionary”。缺陷就是对权限控制比较分散,不便于管理,比如无法简单地将一组文件设置统一的权限开放给指定的一群用户。9 U1 G: n2 Y% o- y" A
        强制访问控制(MAC: Mandatory Access Control)MAC是为了弥补DAC权限控制过于分散的问题而诞生的。在MAC这种模型里,管理员管理访问控制。管理员制定策略,用户不能改变它。策略定义了哪个主体能访问哪个对象。这种访问控制模型可以增加安全级别,因为它基于策略,任何没有被显式授权的操作都不能执行。MAC被开发和实现在最重视保密的系统中,如军事系统。主体获得清楚的标记,对象得到分类标记,或称安全级别。; k0 Y' r7 I7 a6 w
        基于MAC的SElinux         参考链接:https://source.android.google.cn/security/selinux$ Q# y5 r/ i- f
        软件通常情况下必须以 Root 用户帐号的身份运行,才能向原始块设备写入数据。在基于 DAC 的传统 Linux 环境中,如果 Root 用户遭到入侵,攻击者便可以利用该用户身份向每个原始块设备写入数据。从 Android 4.3 起,SELinux 开始为传统的自主访问控制 (DAC) 环境提供强制访问控制 (MAC) 保护功能。作为 Android 安全模型的一部分,Android 使用安全增强型 Linux (SELinux) 对所有进程强制执行强制访问控制 (MAC),甚至包括以 Root/超级用户权限运行的进程(Linux 功能)。例如,可以使用 SELinux 为这些设备添加标签,以便被分配了 Root 权限的进程只能向相关政策中指定的设备写入数据。这样一来,该进程便无法重写特定原始块设备之外的数据和系统设置。借助 SELinux,Android 可以更好地保护和限制系统服务、控制对应用数据和系统日志的访问、降低恶意软件的影响,并保护用户免遭移动设备上的代码可能存在的缺陷的影响。
4 p; j! V. k" p                               0 W6 }; s4 x6 I- Z( y; n0 y

* S" a+ ~/ q$ ~                            飞凌嵌入式 T507 开发板 Android系统版本为Android10,SELinux默认开启,即使获得了该系统的root权限,也只能向相关策略中指定的设备写入数据,从而更好地保护和限制系统服务,保障系统和数据的安全。
( r: X" z4 ~5 M; M7 B6 A        标签、规则和域         SELinux 依靠标签来匹配操作和策略。标签用于决定允许的事项。套接字、文件和进程在 SELinux 中都有标签。SELinux 在做决定时需参照两点:一是为这些对象分配的标签,二是定义这些对象如何交互的策略。9 h; ]1 B; h2 m
        在 SELinux 中,标签采用以下形式:user:role:type:mls_level,其中 type 是访问决定的主要组成部分,可通过构成标签的其他组成部分进行修改。对象会映射到类,对每个类的不同访问类型由权限表示。
  I: o- n, P; S* w        策略规则采用以下形式:allow domains types:classes permissions;,其中:
! S+ l+ f! J" Z4 G( ]$ U
5 I' B% E( Q7 [) s" Z                            Domain - 一个进程或一组进程的标签。也称为域类型,因为它只是指进程的类型。; C9 g2 e  ~9 s
        Type - 一个对象(例如,文件、套接字)或一组对象的标签。4 j( q* u0 d& a* s
        Class - 要访问的对象(例如,文件、套接字)的类型。Permission - 要执行的操作(例如,读取、写入)。
' ?  B6 Y4 M$ X& h) {0 i4 b2 J        策略配置源文件         1、external/sepolicy
. ?5 A! J2 d, A7 x' f# {& e: g6 Z        这是独立于设备的配置,一般不能针对设备进行修改
% o$ |( p  i- s, I4 L$ @
; h  H5 ?) C- ]/ d6 U/ f1 c                            2、device/<vendor>/<product>/sepolicy
7 j' i  f/ H, V3 p. T        这是特定于设备的配置,基于 BOARD_SEPOLICY_* 变量来选择对应平台的策略配置。( [0 e* {' `5 b% t5 X
2 @- ?2 p9 C1 T8 n9 @* n
                            以飞凌嵌入式 T507 开发板 为例,T507策略文件的路径如下:. I$ T, }$ ^# O1 b; H
        OKT507-android-source/android$ ls device/softwinner/common/sepolicy/private  vendor+ a% ~( ^% q$ S" B) i  A
        Type Enforcement (TE) 配置文件         .te 文件中保存了对应对象的域和类型定义、规则。通常每个域一个 .te 文件,例如installd.te。在 device.te、file.te 中声明了设备和文件类型。在某些文件(例如domain.te、app.te)中则存储着共享规则。0 @% ^5 E$ {& P% |0 w
( c8 {( R7 G& D; C
                            以飞凌嵌入式 T507 开发板 为例,T507 system_app的TE文件的路径如下:% E- c; A+ ?* v2 {9 @3 [  I* B$ p# J
        device/softwinner/common/sepolicy/vendor/system_app.te
0 h2 q6 {2 c( c, \) V* `        标签配置文件         1、file_contexts:文件安全上下文( l. s: u  T: [! B. m
        2、property_contexts:属性安全上下文
! H3 Q7 @( O! Z4 C4 m* N3 H( f& P2 b# {1 L9 k& q
                            以飞凌嵌入式 T507 开发板 为例,T507 安全上下文文件路径如下:
4 e- n, }( n3 m) g: L        device/softwinner/common/sepolicy/vendor/property_contexts/ k- Q3 J; \' Z& x: |' u
        device/softwinner/common/sepolicy/vendor/file_contexts
% X( a' Y- d' Y& M8 N* v( O4 Z1 x4 z        SEAndroid app分类         SELinux(或SEAndroid)将app划分为主要三种类型(根据user不同,也有其他的domain类型):" x/ r3 @- B& b& r% o
        1)untrusted_app 第三方app,没有Android平台签名,没有system权限" n7 X3 s" }! B2 N2 y2 T: X
        2)platform_app 有android平台签名,没有system权限$ j5 v! b" j1 _7 Q9 r3 p
        3)system_app 有android平台签名和system权限- E2 m! ^$ L+ [- I: J) h0 k" f- @* ^
        从上面划分,权限等级,理论上:untrusted_app < platform_app < system_app4 e* B1 W9 e& ^6 m# M
        APP的domain和type         查看seapp_contexts文件,APP的domain和type由user和seinfo两个参数决定
5 ~* ]9 L0 i% [        system/sepolicy/private/seapp_contexts! R( ~3 R7 N( {$ k9 Y* G& D
        isSystemServer=true domain=system_server_startup: u  [- y/ x6 [- A
        user=_app seinfo=platform name=com.android.traceur domain=traceur_app type=app_data_file levelFrom=all
: ]; {* |5 @5 e0 O/ u. C! g        user=system seinfo=platform domain=system_app type=system_app_data_file
0 ]; P6 W5 W7 ~8 d! S/ R        user=bluetooth seinfo=platform domain=bluetooth type=bluetooth_data_file
1 @$ E0 B# @" y; O        user=network_stack seinfo=network_stack domain=network_stack levelFrom=all & Q' R  w& q* i: y' I9 e
        type=radio_data_file
8 k/ v/ l7 ~2 Q5 E! N( l& r4 s/ l        user=nfc seinfo=platform domain=nfc type=nfc_data_file
/ b$ o% s) E8 r, g4 E( q        user=secure_element seinfo=platform domain=secure_element levelFrom=all
# w& r$ o) c/ R4 M9 V0 z) {        user=radio seinfo=platform domain=radio type=radio_data_file/ l4 r# T  r0 O
        user=shared_relro domain=shared_relro
, K9 H8 `+ u' {% j        user=shell seinfo=platform domain=shell name=com.android.shell type=shell_data_file
5 W, v: ~9 p6 @# S+ x/ Z1 R* Z" F        user=webview_zygote seinfo=webview_zygote domain=webview_zygote
7 P6 J) S: M% T+ \( t9 _. ^# g        user=_isolated domain=isolated_app levelFrom=al
; ^7 I2 l0 n; Z( _) H* ]        luser=_app seinfo=app_zygote domain=app_zygote levelFrom=all+ d, ?4 t5 S4 E( Y4 K
        user=_app seinfo=media domain=mediaprovider name=android.process.media type=app_data_file
0 v9 f; V0 n" ^        levelFrom=user8 Z' i6 L7 o2 l/ I+ A0 C- C
        user=_app seinfo=platform domain=platform_app type=app_data_file levelFrom=user9 Q" h% {/ _3 q! }& g" c
        user=_app isEphemeralApp=true domain=ephemeral_app type=app_data_file levelFrom=all$ V* X, \5 h) q1 m0 P7 @
        user=_app isPrivApp=true domain=priv_app type=privapp_data_file levelFrom=user
- s' E; ?$ k# T8 {2 h        user=_app minTargetSdkVersion=29 domain=untrusted_app type=app_data_file levelFrom=all
7 W& _, s6 g& ?- Q- c        user=_app minTargetSdkVersion=28 domain=untrusted_app_27 type=app_data_file levelFrom=all6 {' a/ F( o, ~, X  ?4 |3 U8 Z# P
        user=_app minTargetSdkVersion=26 domain=untrusted_app_27 type=app_data_file
( r# b  I, g" l+ I$ }        levelFrom=user+ j7 v. c1 W) a$ u. c+ n
        user=_app domain=untrusted_app_25 type=app_data_file levelFrom=user0 h, M* K# U7 i# v" D+ A* ^) v6 O
        user=_app minTargetSdkVersion=28 fromRunAs=true domain=runas_app levelFrom=all' N, y3 U1 m  f9 a$ f7 r
        user=_app fromRunAs=true domain=runas_app levelFrom=user& t- \( r: _  _- O1 O0 ?
        user         参考链接:https://blog.csdn.net/huilin9960/article/details/81530568
- {& M9 U- Z) [" v        user可以理解为UID。android的UID和linux的UID根本是两回事,Linux的UID是用于针对多用户操作系统中用于区分用户的,而Android中的UID是用于系统进行权限管理的。参考链接中的文章对于uid的产生讲的很清楚。
$ O3 P/ h" T+ Q$ D7 I7 N        seinfo         不同签名会创建对应的selinux上下文。- n$ m" ]  E7 p( e7 D5 x- g
        Android.mk- Z( K; o. i. `  J
        LOCAL_CERTIFICATE := platform
& F$ _* |% }5 P+ D5 m+ t/ V        有platform签名,所以seinfo是platform。
- U8 O) k* }7 C# c, H  u, M* w' P0 u        LOCAL_CERTIFICATE作用         参考文档https://blog.csdn.net/hnlgzb/article/details/107823874- D! z) p; E7 ]
        可以查看Android源码build/target/product/security/ 目录下提供的默认签名文件,不同平台可能会有差异:飞凌嵌入式 T507 开发板 提供了media、networkstack、platform、shared、testkey、verity六种不同权限的签名文件。: ^% p8 _6 d. \3 D
                              
4 R; G$ _3 q; q        以飞凌嵌入式 T507 开发板 为例,查看当前运行的应用信息:' F1 e2 r( G0 R; B
        console:/ # ps -Z9 _; r9 Q; M& W; k0 Y
        u:r:system_app:s0              system       15712  1861 1050628 110868 SyS_epoll_wait     
, G" N# M; `/ F# c# I% R/ o' L- B        0 S forlinx.example.app3 J+ o9 w5 \; O& j6 r
        u:r:untrusted_app_27:s0:c512,c768 u0_a62    30259  1861 1052120 114132 SyS_epoll_wait     ( C4 J, K3 P: a# e9 S% ~0 y6 t. n
        0 S com.forlinx.changelogo
$ I% l  }  n2 O7 a6 |        当前运行的两个APP,forlinx.example.app的UID(user)是system,拥有platform签名,它的domain和type就是system_app。7 Z5 j, j3 @# K0 @9 i- S
                               7 ?: d" \5 N. t8 t+ i
1 ~4 h& ~7 x% L/ \
                                                   8 u+ L/ Z% v( y' w$ x3 q) ~
        com.forlinx.changelogo没有设置UID使用的默认设置,其UID为u0_a62,并且没有设置签名文件,它的domain和type就是untrusted_app。
" B+ A8 Q" r4 [        T507自定义安全策略         以上面两个运行的app来说,我们为这两个APP添加额外的权限,对应的TE配置文件分别就是system_app.te、untrusted_app.te,对应路径为:2 A8 q% k9 y* z! ^1 F2 v% ]
        device/softwinner/common/sepolicy/vendor/system_app.te4 ^4 C4 z$ U0 h2 k- b4 q
        device/softwinner/common/sepolicy/vendor/untrusted_app.te! w7 k( y8 @4 i5 |# E5 ]
6 [+ W6 u7 P5 |' r3 P
                            以forlinx.example.app为例,我们为其添加can设备的执行权限:
9 Z- a) r9 H+ x6 b, a, Q* v, s7 R8 E6 r6 d$ Z0 c. |3 Y+ B" Z
                            OKT507-android-source/android$ vi device/softwinner/common/sepolicy/vendor/system_app.te0 W' G8 M* M+ Z9 w7 H3 c) Q3 h9 C! P
        ...
. C1 H3 n" d4 B4 W8 N- d* N8 m4 t        allow system_app vendor_shell_exec:file { getattr open read execute execute_no_trans };
: _+ S+ {" \0 N* P( q        allow system_app shell_exec:file { getattr open read execute execute_no_trans };0 R7 G8 ]& R3 h, e' g# `9 a
        allow system_app shell:file { getattr open read execute execute_no_trans };
/ \2 A  ~0 U( l. |5 O- i# |: s        ...
: n: {2 a) b# c  }4 F" D. R' Z; A        以策略规则配置形式(allow domains types:classes permissions)
* w( C0 b1 `* o9 K8 @! K; {  M        分析:domains:system_app
" w* ~- E) {: d/ H5 h        types:vendor_shell_exec
; R8 j! ]- F+ |        classes:file
7 u3 A3 `- |, k2 v2 F2 V        permissions:getattr open read execute execute_no_trans
% o: i. i; E7 V$ w        neverallow failures         有时我们增加的权限,系统默认的配置是不允许的,比如我们上面给forlinx.example.app增加的执行脚本的权限,报错如下:. d0 |$ t% k4 B
6 d5 h# j3 R+ y2 }; R: v, w, C
                            libsepol.report_failure: neverallow on line 9 of system/sepolicy/private/system_app.te 5 {2 S  Y, D5 N) V, ]3 M7 k
        (or line 41463 of policy.conf) violated by allow system_app shell:file { read open };# s- o6 [3 B) g) x6 M" z# b
        libsepol.report_failure: neverallow on line 22 of system/sepolicy/private/shell.te) A9 B6 L( c6 I' F( }
         (or line 40025 of policy.conf) violated by allow system_app shell:file { read open };, Z$ J, O# V; a$ s
        libsepol.check_assertions: 2 neverallow failures occurred' ^- C& V9 f3 P7 c8 N( I

( ?. t8 ]- i) x; C) o                            系统默认的安全策略的路径为system/sepolicy/,根据报错的提示,我们可以修改默认的配置,修改system/sepolicy/private/system_app.te和system/sepolicy/private/shell.te,从而完成权限的赋予。+ p: ]: Z5 F7 r' `- j2 j

4 c; B3 Q0 P6 C& t9 S                            以上就是Android 安全策略的脉络,以及飞凌嵌入式 T507 开发板 Android系统下自定义安全策略的方法了。' q! h2 X- D% h0 S+ c
! ]! k2 z/ A5 S/ M
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋| 飞凌嵌入式 ( 冀ICP备12004394号-1 )

GMT+8, 2026-5-4 12:53

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表