由于SELinux造成的权限问题分析与解决

1 背景

基于Android10,在进行sd卡读取权限配置时候,发现只配置AndroidManifest.xml不能解决权限问题,经过多方查找发现当前版本的Android还需要配置SELinux,废话不多说,请看下面的分析。

2 Android的权限问题

AndroidManifest.xmlAndroid应用的入口文件,它描述了package中暴露的组件(activitiesservices,等等),他们各自的实现类,各种能被处理的数据和启动位置。除了能声明程序中的ActivitiesContentProvidersServicesIntent Receivers,还能指定permissionsinstrumentation(安全控制和测试)。

比如需要加入SD卡的读取权限,则需要添加:

1.	<uses-permission android:name="android.permission.INTERNET"/>  
2.	<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>  
3.	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  

注意:6.0后的版本即使添加了权限还是会报错,但是权限声明是必须要加的

Android10中除了要注意在AndroidManifest.xml中添加权限,还需要关注SELinux的问题。SELinuxGoogleandroid 5.0开始,强制引入的一套非常严格的权限管理机制,主要用于增强系统的安全性。

SELinux出现之前,Linux上的安全模型叫DAC,全称是Discretionary Access Control,翻译为自主访问控制。DAC的核心思想:进程理论上所拥有的权限与执行它的用户的权限相同。比如,以root用户启动Browser,那么Browser就有root用户的权限,在Linux系统上能干任何事情。

显然,DAC太过宽松了,应用获得的权限过多容易造成安全问题。SELinuxDAC之外,设计了一个新的安全模型,叫MACMandatory Access Control),翻译为强制访问控制。MAC的核心思想:即任何进程想在SELinux系统中干任何事情,都必须先在安全策略配置文件中赋予权限。凡是没有出现在安全策略配置文件中的权限,进程就没有该权限。

SELinux中,每个进程都有一个安全属性Security ContextSecurity Context是一个字符串,主要由三部分组成。例如SEAndroid中,进程的SContext可通过ps -Z命令查看,如下所示:

1.	ps -Z  
2.	LABEL       USER    PID  PPID     VSZ    RSS WCHAN          ADDR S NAME  
3.	u:r:su:s0   root    6671  6664   33492   2492 sigsuspend     0   S sh  
4.	u:r:su:s0   root    6673  6671   35972   3216 0              0   R ps  

以第一个进程shSContext为例,其值为u:r:init:s0,其中:

  • uuser的意思。SEAndroid中定义了一个SELinux用户,值为u
  • rrole的意思。role是角色之意,它是SELinux中一种比较高层次,更方便的权限管理思路,即Role Based Access Control(基于角色的访问控制,简称为RBAC)。简单点说,一个u可以属于多个role,不同的role具有不同的权限。RBAC我们到最后再讨论。
  • init,代表该进程所属的DomainsuMAC的基础管理思路其实不是针对上面的RBAC,而是所谓的Type Enforcement Accesc Control(简称TEAC,一般用TE表示)。对进程来说,Type就是Domain。比如sh这个Domain有什么权限,都需要通过[1]allow语句来说明。
  • S0SELinux为了满足军用和教育行业而设计的Multi-Level SecurityMLS)机制有关。简单点说,MLS将系统的进程和文件进行了分级,不同级别的资源需要对应级别的进程才能访问

1

device/*/common/sepolicy/system_app.te

allow system_app proc:file write

根据SELinux语句,表示为:允许(allowsystem_app域(domain)中的进程写(write)类型为proc的文件。如果没有在system_app中使用上例中的权限配置allow语句,则system_app就无法往/proc目录下得任何文件中写数据

这条语句的语法为:

  • allowTEallow语句,表示授权。除了allow之外,还有allowauditdontauditneverallow等。
  • system_appsource type。也叫subjectdomain
  • proctarget type。它代表其后的file所对应的Type
  • file:代表Object Class。它代表能够给subject操作的一类东西。例如FileDirsocket等。在Android系统中,有一个其他Linux系统没有的Object Class,那就是Binder
  • write:在该类Object Class中所定义的操作。

3 问题分析与解决 

 

当对SD卡进行读写操作时候,即使已经配置了AndroidManifest.xml,使其能够对外置SD卡进行读写,但是在应用中读写SD卡时候仍然报错:

W System.err: java.io.FileNotFoundException: /sys/block/mmcblk1/device/ssr: open failed: EACCES (Permission denied)

原因为:

AndroidManifest.xml中配置了权限之后,仍然需要配置SELinux的相关权限。因为SELinux3种操作模式,分别是DisabledPermissiveEnforcing,在Android中可以通过输入adb命令getenforce来获取当前系统的SELinux状态。Disabled表示SELinux是被禁止的,Permissive只发出警告但不拒绝访问,而Enforcing在发出警告的同时会拒绝访问。

解决办法为:

为了澄清是否因为SELinux导致的问题,可先执行:

setenforce 0(临时禁用掉SELinux

getenforce(得到结果为Permissive

如果问题消失了,基本可以确认是SELinux造成的权限问题,需要通过正规的方式来解决权限问题。

遇到权限问题,在kernellog中一定会打印avc denied提示缺少什么权限,可以通过命令过滤出所有的avc denied,再根据这些log各个击破:

cat /proc/kmsg | grep avc

<5>[67.544398] c4 audit: type=1400 audit(1584583763.943:407): avc:denied { read } for  pid=3578 comm="HwBinder:357 8_2" name="u:object_r:default_prop:s0" dev="tmpfs" ino=15134 scontext=u:r: system_app:s0 tcontext=u:object_r: sysfs:s0 tclass=file permissive=0

可以看到有avc denied,且最后有permissive=0,表示不允许。

该问题的解决原则是:缺什么权限补什么权限。

上例中的hal_camera_default权限配置文件一般在:

android根源码目录/device/厂商/硬件型号/common/sepolicy/hal_camera_default.tee

log分析:

缺少什么权限:{read}权限,

谁缺少权限:scontext=u:r: system_app:s0

对哪个文件缺少权限:tcontext=u:object_r: sysfs:s0

什么类型的文件:tclass=file

完整的意思:system_app进程对sysfs类型的file缺少read权限。所以只需要在system_app.tee中添加如下配置语句:

allow system_app sysfs:file { read };

但是添加了上述配置之后编译会报错,通常错误形式为:

libsepol.report_failure: neverallow on line 31 of system/sepolicy/private/domain.te (or line 26746 of policy.conf) violated by allow system_app sysfs:file { read write create setattr open };
libsepol.report_failure: neverallow on line 507 of system/sepolicy/public/app.te (or line 8383 of policy.conf) violated by allow system_app sysfs:file { write };
libsepol.check_assertions: 2 neverallow failures occurred
Error while expanding policy

 该错误意思是:在system_app.tee中的配置违反了在system/sepolicy/private/domain.tesystem/sepolicy/public/app.teneverallows规则

  • 修改system/sepolicy/private/domain.te中的内容,增加-system_app
	# /sys  
	  neverallow {  
	    coredomain  
	    -init  
	    -ueventd  
	    -vold  
	    -system_app     //排除system_app  
	  } sysfs:file no_rw_file_perms;  

 

  • 修改system/sepolicy/public/app.te中的内容,注销限制
	# Write to various pseudo file systems.  
	#neverallow { appdomain -bluetooth -nfc }//注销app对sysfs的操作限制  
	#    sysfs:dir_file_class_set write;  
	neverallow appdomain  
	    proc:dir_file_class_set write;  

到此还有最后一步工作需要完成,否在编译会报错:

FAILED: out/target/product/ums512_20c10/obj/ETC/sepolicy_freeze_test_intermediates/sepolicy_freeze_test
/bin/bash -c "(diff -rq -x bug_map system/sepolicy/prebuilts/api/29.0/public system/sepolicy/public ) && (diff -rq -x bug_map system/sepolicy/prebuilts/api/29.0/private system/sepolicy/private ) && (touch out/target/product/ums512_20c10/obj/ETC/sepolicy_freeze_test_intermediates/sepolicy_freeze_test )"
Files system/sepolicy/prebuilts/api/29.0/public/app.te and system/sepolicy/public/app.te differ
[  0% 97/84946] target  C: libsensor_imx586 <= vendor/sprd/modules/libcamera/sensor/sensor_drv/classic/So
vendor/sprd/modules/libcamera/sensor/sensor_drv/classic/Sony/imx586/sensor_imx586_mipi_raw.c:62:31: warning: unused variable 'sns_drv_cxt' [-Wunused-variable]
struct sensor_ic_drv_cxt *sns_drv_cxt = (struct sensor_ic_drv_cxt *)handle;

该错误是因为system/sepolicy/prebuilts/api/29.0/privatesystem/sepolicy/private文件内容不一致,system/sepolicy/prebuilts/api/29.0/privatesystem/sepolicy/private文件内容不一致导致的。

通过

diff –Naur system/sepolicy/prebuilts/api/29.0/private system/sepolicy/private
diff –Naur system/sepolicy/prebuilts/api/29.0/private system/sepolicy/private

来查看文件的不同,同步为一致即可。

自此该问题可以得到解决。

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值