【Linux驱动调试技巧】如何进行SELinux安全策略配置?

SELinux(Security-Enhanced Linux)

SELinux解决的是安全问题,即指定的进程只能访问特定的资源,执行特定的操作,避免越权操作引发安全性问题

传统的DAC机制(Discretionary Access Control)自主访问控制,用户和其所在分组决定了该进程的用户权限 root用户具有所有的访问权限。

SELinux MAC机制(Mandatory Access Control)强制访问控制,即访问一个文件资源都要根据已定义的策略进行针对性验证


SELinux的资源分为两类 : subject(主体)和object(客体)

主体:可以主动对其他资源进行操作,即进程,服务等

客体:只能被动访问。如file,socket,device等。

标签(Labels) 所有的subject和object都有自己的标签,通过这样可以控制某个subject标签对某个object标签进行访问控制,android只定义了一种安全级别S0,即不使用安全级别

其格式: user:role:type:mls_level 用户:角色:类型:安全级别.

在android系统中只定义了一个用户 u和一个subject角色r,一个objec角色object_r

example: u:object_r:system_file:s0 ,---> user:object_r:system_file:s0

策略(Strategy)

   指定处于什么域的subject可以对什么类型的object执行那些权限操作
   策略格式: rule subject_type target_type : class perm_set 
   rule :控制类型,如allow,neverallow
   subject_type :指domain
   target_type: 请求资源的类型
   class perm_set: 对资源的操作
   Ex:
   allow appdomain app_data_file:file rw_file_perms; 
   表示所有应用的域都允许读写类型为 app_data_file的文件,rw_file_perms = class {read,write}
SEAndroid策略文件位置

   通用目录:
   system\sepolicy
   Qcom定制:
   device\qcom\sepolicy\\
SEAndroid策略中的一些基本语法

   主要有三类: type、class、allow
type:用来定义资源类型,即把资源类型和属性关联到一起

  Ex:
  type init,domain;
  将init关联到domain,即将domain设置为init类型的属性
  普通文件type定义在 file.te
  设备文件type 定义在 device.te
  file_contexts:保存了所有文件的安全上下文定义
class:用来定义资源类别的权限集合

   语法: class class_name [inherits common_name]{permission_name ...}
   inherits表示继承了common定义的权限,然后额外实现了permission_name的权限
   Ex:
   class dir inherits file 
  { 
   add_name 
   remove_name 
   reparent 
   search 
   rmdir 
   open 
   audit_access 
   execmod 
   } 即dir继承了file的操作权限集合并增加自己的操作

allow:赋予某项权限

   allowaudit:audit含义就是记录某项操作
   dontaudit:对于那些权限检测失败的操作不做记录
   neverallow:用来检查安全策略文件中是否有违反该项规则的allow语句
   Ex:
   allow init unlabeled:filesystem mount; 允许init类型对unlabeled类型的filesystem进行mount的操作
   neverallow { appdomain -unconfineddomain } kmem_device:chr_file { read write }; 
   绝对不允许app(除了有unconfineddomain属性的app)对kmem_device类型的字符设备进行读写的操作
文件类型

   *.te:类型强制规则文件 
   genfs_contexts:虚拟文件系统的安全上下文设置规则 
   seapp_contexts :用于app打type标签 
   service_contexts :系统服务安全上下文 
   property_contexts :系统属性安全上下文 
   port_contexts:网络端口安全上下文
   file_contexts:保存了所有文件的安全上下文定义
一些封装函数:

   domain 切换
   init_daemon_domain(mediaserver) 
   这个是一个复杂的TE操作宏, 简单来说就是当init fork 子进程执行mediaserver_exec 这个类型的执行档时, 其domain 从init 切换到mediaserver.
   允许 mediaserver 访问init 的property socket
   unix_socket_connect(mediaserver, property, init)
   允许mediaserver 读取sdcard_type 类型的目录和文件
   r_dir_file(mediaserver, sdcard_type)
   允许mediaserver 使用binder 服务 和发起 binder call.
   binder_use(mediaserver) 
   binder_call(mediaserver, binderservicedomain) 
   binder_call(mediaserver, appdomain) 
   binder_service(mediaserver)

log分析:

   Ex:
    <5> type=1400 audit: avc: denied { read write } for pid=177 comm=”rmt_storage” name=”mem” dev=”tmpfs” ino=6004 scontext=u:r:rmt:s0 
   tcontext=u:object_r:kmem_device:s0 tclass=chr_file
   操作 - 试图进行的操作使用括号突出显示:read write 或 setenforce。 avc:denied {read write}
   操作方 - scontext(来源环境)条目表示操作方;在该示例中为 rmt 守护进程。
   对象 - tcontext(目标环境)条目表示正在对哪个对象执行操作;在该示例中为 kmem_device。
   结果 - tclass(目标类别)条目表示当前操作对象的类型;在该示例中为 chr_file(字符设备)。
   log分析:rmt_storeage进程使用rmt的context访问字符设备kmem_device,并进行read write操作时,被SELinux拒绝
  解决: 在相关的te文件中加入 allow rmt kmem_device:chr_file {read write}

你可能感兴趣的:(子类_驱动技巧篇)