SEAndroid问题解决

来源:互联网 发布:函授和网络教育含金量 编辑:程序博客网 时间:2024/06/06 10:45

  Android从4.4版本引入SEAndroid,SEAndroid是一套基于SELinux做的系统安全机制。SEAndroid有三种模式:Enforcing,Permissive,Disabled。Enforcing状态下,所有违反SEAndroid策略的操作都会被禁止执行并显示警告信息,Permissive状态下所有违反SEAndroid策略的操作不会被禁止执行,但会显示警告信息,Disabled则表示完全关闭状态。
  今日遇到一些Permissive状态下开机显示SEAndroid警告的问题,现在写个文档记录一下。
  下面是Log信息:

[    6.606469] type=1400 audit(1167652801.729:3): avc:  denied  { entrypoint } for  pid=1228 comm="init" path="/system/bin/tee-supplicant" dev="mmcblk0p9" ino=336 scontext=u:r:tee:s0 tcontext=u:object_r:system_file:s0 tclass=file permissive=1

  从Log信息可以看到:源domain为 tee( scontext项),目标file_type为system_file(tcontext项),object_class为file(tclass项),目标文件/进程为”/system/bin/tee-supplicant”(path项,该项可能没有),发生事件为denied(avc项,允许执行时为”granted”),如果事件发生在文件,则会有path项,如果发生在进程则会没有path项。上面log的意思是:domain为tee的进程对file_type为system_file的文件(file)的entrypoint操作是不被允许的。
  既然没有权限,就需要在SEAndroid的策略文件中授权。举例如下,表示允许domain为netd的file_type为proc的file进行write操作。值得注意的是,除了allow语句,还有neverallow语句,优先级比allow高,意思是在allow和neverallow同时设置了同一个操作的情况下,该操作仍是不被允许的。此外,没有设置allow的操作,就没有相应的权限,要想操作被允许,必须显式设置allow。

allow netd proc:file write

  现在看看domain为tee的进程信息,其会被写在tee.te中。可以看到tee和domain这个attribute关联起来了,domain是一个attribute,所有的attribute会被定义在attributes文件中。所谓的attributes相当于一些domain的集合,tee这个domain现在加入到domain这个attributes中了。

...type tee, domain;type tee_exec, exec_type, file_type;type tee_device, dev_type;type tee_data_file, file_type, data_file_type;...

  现在使用”grep -Hrn entrypoint ./”搜索当前路径下关于entrypoint操作的信息。可以看到,在domain.te中使用了如下语句:
  neverallow domain { file_type -exec_type }:file entrypoint;
  这句的意思是不允许domain这个attributes的所有domain,去对除了file_type为exec_type的file进行entrypoint操作。由Log的信息可以看到,报错的file_type为system_file,显然会被拒绝。file_type本质上和domain是一样的,都可以关联到一个或多个attributes。可以留意到tee.te中,tee_exec关联到了exec_type。那么可以通过将对应文件的domain(说是file_type也行)改成tee_exec来通过策略。

./te_macros:14:allow $3 $2:file { entrypoint open read execute getattr };./unconfined.te:72:}:{ chr_file file } ~{entrypoint execute_no_trans execmod execute relabelto};./unconfined.te:73:allow unconfineddomain {dev_type -kmem_device}:{ chr_file file } ~{entrypoint execute_no_trans execmod execute relabelto};./unconfined.te:83:}:{ chr_file file } ~{entrypoint execute_no_trans execmod execute relabelto};./app.te:285:# Write to entrypoint executables../kernel.te:67:neverallow kernel { file_type fs_type -rootfs }:file { entrypoint execute_no_trans };./init.te:119:neverallow init { file_type fs_type }:file entrypoint;./domain.te:236:# Ensure that all entrypoint executables are in exec_type../domain.te:237:neverallow domain { file_type -exec_type }:file entrypoint;./access_vectors:164:   entrypoint./access_vectors:182:   entrypoint./access_vectors:778:   entrypoint

  已知进程对应的文件为”/system/bin/tee-supplicant”,可以在file_contexts文件中找到这些系统进程对应文件及设备文件的domain。现在发现file_contexts没有”/system/bin/tee-supplicant”这一项。在原生的file_contexts中可以发现这样的一项:

/system(/.*)?       u:object_r:system_file:s0

  在没有显式声明的情况下,system目录下所有文件的domain均为system_file,这也是我们看到的file_type为system_file的原因。回到定制的file_contexts可以增加这一条:

/system/bin/tee-supplicant  u:object_r:tee_exec:s0

  现在tee-supplicant文件的file_type改成了tee_exec,其属于exec_type,自然就不会被策略所拒绝。
  如果我想定义一个全新的file_type呢?例如将file_type改成sup_exec这个在策略文件中从没出现过的名字。由于策略只允许exec_type通过,现在需要将sup_exec与exec_type关联起来。打开tee.te文件,加上:

type sup_exec,exec_type;

   便可以通过策略。
   再来看一个例子。

[   10.587032] type=1400 audit(1167652805.709:5): avc: denied { transfer } for pid=1245 comm="MiSetSystemINFO" scontext=u:r:misys:s0 tcontext=u:r:init:s0 tclass=binder permissive=1

   可以看到domain为misys的进程对file_type为init的binder的transfer操作被拒绝了。 grep -Hrn transfer ./看一下:

./unconfined.te:90:allow unconfineddomain { domain -init }:binder { call transfer set_context_mgr };

   这里允许unconfineddomain这个attributes中所有domain对domain这个attributes中除了init外所有domain的call,transfer, set_context_mgr操作。没有allow就是拒绝,这也对应了得到的Log。
   可以猜想到misys这个domain被关联到unconfineddomain这个attribute了。打开misys.te看一下:

...type misys, domain;type misys_exec, exec_type, file_type;unconfined_domain(misys)typeattribute misys mlstrustedsubject;init_daemon_domain(misys)net_domain(misys)...

  在te_macros文件中。可以看到unconfined_domain函数的定义:

 define(`unconfined_domain', ` typeattribute $1 mlstrustedsubject; typeattribute $1 unconfineddomain; ')

  typeattribute用法和type差不多,都是关联一个domain到attributes中,”typeattribute $1 unconfineddomain”表示将第一个参数关联到unconfineddomain中。那么misys这个domain确实关联到unconfineddomain中了,所以会被策略拒绝。
  这个问题的根本原因是在没有显式声明的情况下,子进程会继承父进程的domain。init进程是Android所有进程的父进程,fork出来的misys进程的domain与init进程相同,都是init。这是由于开发者的疏忽导致。一种改法是在misys.te加入对应allow语句授予权限,另一种改法是使用ps -Z找到该进程对应的文件,在file_contexts改变这个文件的domain,只要不是init即可。

原创粉丝点击