SELinux app权限配置 android6.0 新特性

1.SEAndroid app分类

SELinux(或SEAndroid)将app划分为主要三种类型(根据user不同,也有其他的domain类型):

1)untrusted_app  第三方app,没有Android平台签名,没有system权限
2)platform_app    有android平台签名,没有system权限

3)system_app      有android平台签名和system权限

从上面划分,权限等级,理论上:untrusted_app < platform_app < system_app

2.seapp_contexts定义

external\sepolicy\seapp_contexts

[java] view plain copy
  1. isSystemServer=true domain=system_server  
  2. user=system seinfo=platform domain=system_app type=system_app_data_file  
  3. user=bluetooth seinfo=platform domain=bluetooth type=bluetooth_data_file  
  4. user=nfc seinfo=platform domain=nfc type=nfc_data_file  
  5. user=radio seinfo=platform domain=radio type=radio_data_file  
  6. user=shared_relro domain=shared_relro  
  7. user=shell seinfo=platform domain=shell type=shell_data_file  
  8. user=_isolated domain=isolated_app levelFrom=user  
  9. user=_app seinfo=platform domain=platform_app type=app_data_file levelFrom=user  
  10. user=_app domain=untrusted_app type=app_data_file levelFrom=user  

从上面可以看出,domain和type由user和seinfo两个参数决定。
比如:

user=system  seinfo=platform,domain才是system_app

user=_app,可以是untrusted_app或platform_app,如果seinfo=platform,则是platform_app。

3.user和seinfo判定方式

首先看user,user可以理解为UID,例如ps -Z结果如下:

[java] view plain copy
  1. u:r:system_app:s0              system    2414  1172  com.android.keychain  
  2. u:r:platform_app:s0            u0_a6     2439  1172  com.android.managedprovisioning  
  3. u:r:untrusted_app:s0           u0_a8     2460  1172  com.android.onetimeinitializer  
  4. u:r:system_app:s0              system    2480  1172  com.android.tv.settings  
  5. u:r:untrusted_app:s0           u0_a27    2504  1172  com.android.email  
  6. u:r:untrusted_app:s0           u0_a28    2523  1172  com.android.exchange  
  7. u:r:untrusted_app:s0           u0_a7     2567  1172  com.android.musicfx  

第一列是SContext,第二列是UID,只要UID是system的基本都是system_app,反过来一样。
其他的U0_XXX要么属于platform_app或untrusted_app


seinfo由external\sepolicy\mac_permissions.xml决定,内容如下:

[java] view plain copy
  1.   
  2. "@PLATFORM" >  
  3.   "platform" />  
  4.   
  5.   
  6.   
  7. <default>  
  8.   "default" />  
  9. default>  
即如果签名是platform,seinfo就是platform,其他的比如shared等,seinfo是default。
比如上面ps -Z的结果里面,OneTimeInitializer.apk是untrusted_app,ManagedProvisioning.apk是platform_app。

分别查看这两个app的Android.mk

packages\apps\OneTimeInitializer\Android.mk  没有定义LOCAL_CERTIFICATE,默认是shared

packages\apps\ManagedProvisioning\Android.mk    有定义LOCAL_CERTIFICATE := platform

因为ManagedProvisioning.apk有platform签名,所以seinfo是platform。


TvSettings是system_app,查看对应的参数:

packages\apps\TvSettings\Settings\Android.mk  有定义LOCAL_CERTIFICATE := platform

packages\apps\TvSettings\Settings\AndroidManifest.xml  有定义android:sharedUserId="android.uid.system"

TvSettings user是system,seinfo是platform,所以是system_app

packages\apps\ManagedProvisioning\AndroidManifest.xml 没有定义android:sharedUserId="android.uid.system"

所以ManagedProvisioning虽然seinfo是platform,但是user不是system,因此只是platform_app,而不是system_app。

4.app对应的te文件

system_app  ->  external\sepolicy\system_app.te
untrusted_app ->  external\sepolicy\untrusted_app.te
platform_app  ->  external\sepolicy\platform_app.te

对应的权限,通过allow语句给予,比如只有system_app才可以设置prop:
[java] view plain copy
  1. # Write to properties  
  2. unix_socket_connect(system_app, property, init)  
  3. allow system_app debug_prop:property_service set;  
  4. allow system_app net_radio_prop:property_service set;  
  5. allow system_app system_radio_prop:property_service set;  
  6. auditallow system_app net_radio_prop:property_service set;  
  7. auditallow system_app system_radio_prop:property_service set;  
  8. allow system_app system_prop:property_service set;  
  9. allow system_app ctl_bugreport_prop:property_service set;  
  10. allow system_app logd_prop:property_service set;  

总结:
在引入SEAndroid后,app开发需要注意需要哪些权限,根据配置(shareuid和签名)来决定domain,从而决定权限大小。




折腾了一天,用audit2allow工具解析avc错误,把所有的权限都加上了,还是不行,一直有以下提示:

[html] view plain copy
在CODE上查看代码片派生到我的代码片

    01-06 23:47:28.170  1932  1932 W port_api.sample: type=1400 audit(0.0:59): avc: denied { write } for name="ttyS0" dev="tmpfs" ino=4864 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:serial_device:s0 tclass=chr_file permissive=0  


无意中看到网上这篇文章,在device.te加入type serial_device, dev_type, mlstrustedobject;这一行,问题迎刃而解,原文如下,就不标记出处了,因为我是在一个满是成人弹幕广告的网站上搜到的,嘿嘿。

第三方签名APP,在SElinux下,如何获得对一个内核节点的访问权限
    

在android6.0中,出于安全考虑,不允许第三方签名的app被分配mlstrustedsubject:

在external/sepolicy/untrusted_app.te文件中:

# Do not allow untrusted_app to be assignedmlstrustedsubject.
# This would undermine the per-user isolation model being
# enforced via levelFrom=user in seapp_contexts and the mls
# constraints.  As there is no direct way tospecify a neverallow
# on attribute assignment, this relies on the fact that fork
# permission only makes sense within a domain (hence should
# never be granted to any other domain withinmlstrustedsubject)
# and untrusted_app is allowed fork permission to itself.
neverallow untrusted_app mlstrustedsubject:process fork;

所以在使用第三方签名app时,希望第三方签名app某个进程能够对内核节点进行操作,可按如下修改:

1.在device/sprd/scx20/common/sepolicy/file_contexts 文件中添加:
/dev/abc u:object_r:abc_device:s0
2.在device/sprd/scx20/common/sepolicy/device.te 文件中添加:
type abc_device, dev_type, mlstrustedobject;

3.在device/sprd/scx20/common/sepolicy/untrusted_app.te 文件中添加:
allow untrusted_app adc_device:chr_fileoperate;

operate为赋予的权限。

注:

mlstrustedsubject:这一attribute包含了所有能越过MLS检查的主体domain。

mlstrustedobject:这一attribute包含了所有能越过MLS检查的客体type。



你可能感兴趣的:(android)