selinux常见neverallow项解决方法与常用命令

1. dac_override

egbin: type=1400 audit(0.0:879): avc: denied { dac_override } for capability=1 s:egbin:s0 tclass=capability permissive=1

​ 需要给egbin dac_override权限,但是该权限是Android P的neverallow规则中的,不能被添加。dac_override权限意思是容许进程旁路的所有DAC权限:uid,gid,ACL 等等,即有这个权限可以无视linux的权限中的用户、用户组。谷歌这样做的原因可能是这个dac_override权限能力范围太大,不能给普通程序这个权限,只有少数程序有这个权限。

ueventd.te(7):allow ueventd self:capability { chown mknod net_admin setgid fsetid sys_rawio dac_override fowner };
zygote.te(7):allow zygote self:capability { dac_override setgid setuid fowner chown };
netd.te(44):allow netd self:capability { dac_override chown fowner };
runas.te(14):dontaudit runas self:capability dac_override;
vold.te(20):allow vold self:capability { net_admin dac_override mknod sys_admin chown fowner fsetid };
installd.te(6):allow installd self:capability { chown dac_override fowner fsetid setgid setuid };
tee.te(9):allow tee self:capability { dac_override };

dac_override权限问题一种解法
出现这种问题可能原因是进程的组与需要访问的文件的组不同,进程没有权限访问改组的文件,需要申请dac_override权限来旁路的所有DAC权限:uid,gid使进程可以访问该文件。以egbin为例,下面为开机时egbin的rc文件,及data的user和group。

drwxrwx--x  43 system system u:object_r:system_data_file:s0  4096 1970-01-29 01:46 data

service egbin /system/bin/egbin start
    class core
    user root
    group root
    writepid /dev/stune/top-app/tasks
    seclabel u:r:egbin:s0

​ 可以看到 egbin 执行时候user是root,而data是属于system,因此导致需要申请dac_override才能访问data分区。如果不加dac_override的权限,可以将egbin的组切换为system组即可访问,rc修改如下:

service egbin /system/bin/egbin start
    class core
    user root
    group root system
    writepid /dev/stune/top-app/tasks
    seclabel u:r:egbin:s0

参考文献:https://blog.csdn.net/pen_cil/article/details/89434349

https://android-review.googlesource.com/c/platform/external/sepolicy/+/174530/5/update_engine.te#11

https://danwalsh.livejournal.com/79643.html

查看命令

man capabilities

2. entrypoint的一种解法

type=1400 audit(0.0:214): avc: denied { entrypoint } for path="/system/bin/csity_dhcplog.sh" dev="dm-2" ino=471 scontext=u:r:start-ssh:s0 tcontext=u:object_r:csity_dhcplog_system_exec:s0 tclass=file permissive=0
  • 1、首先,让init域的进程要能够执行shell_exec类型的文件

    allow init shell_exec:file execute;
    
  • 2、然后,你需要告诉SELinux,允许init域的进程切换到init_shell域

     allow init init_shell:process transition;
    
  • 3、最后,还得告诉SELinux,域切换的入口(entrypoint)是执行shell_exec类型的文件

     allow init_shell shell_exec:file entrypoint;
    

看起来挺麻烦,不过SELinux支持宏定义,我们可以定义一个宏,把上面4个步骤全部包含进来。在SEAndroid中,所有的宏都定义在te_macros文件中,其中和DT相关的宏定义如下:

# 定义domain_trans宏,$1,$2,$3代表宏的第一个,第二个…参数

define(`domain_trans', 
     allow $1 $2:file { getattr open read execute };
     allow $1 $3:process transition;
     allow $3 $2:file { entrypoint open read execute getattr };
	...
 ')

# 定义domain_auto_trans宏,这个宏才是我们在te中直接使用的:

 define(`domain_auto_trans', `
     \# Allow the necessary permissions.
     domain_trans($1,$2,$3)
     \# Make the transition occur by default.
     type_transition $1 $2:process $3;
 ')

呵呵,是不是简单多了,domain_trnas宏在DT需要的最小权限的基础上还增加了一些权限,在te文件中可以直接用domain_auto_trans宏来显示声明域转换,如下:

 domain_auto_trans(init, shell_exec, init_shell)
  1. init_daemon_domain(study)

程执行一个type为zygote_exec的文件时,将该子进程的domain设置为zygote,而不是继承父进程的domain。并且给与zygote这个domain,所有定义在tmpfs_domain宏中的权限。

# init_daemon_domain(domain)
# Set up a transition from init to thedaemon domain
# upon executing its binary.
define(`init_daemon_domain', `
domain_auto_trans(init, $1_exec, $1)
tmpfs_domain($1)
')

init_daemon_domain(study)是一个宏,声明当一个domain为init的进程创建一个子进程执行一个type为study_exec的文件时,将该子进程的domain设置为study,而不是继承父进程的domain。并且给与study这个domain,所有定义在tmpfs_domain宏中的权限。

To exec or transition that is the question:https://danwalsh.livejournal.com/72287.html

3 DAC_READ_SEARCH

当我们在执行sh命令(如ls)时,可能会遇到selinux报有关 DAC_READ_SEARCH 的权限为问题。

07-05 18:38:00.268 I/ls  ( 4276): type=1400 audit(0.0:598): avc: denied { dac_read_search } for capability=2 scontext=u:r:hello_t:s0 tcontext=u:r:hello_t:s0 tclass=capability permissive=1

首先我们来了解一下 capability 中的DAC_READ_SEARCH是什么?

在Linux中,root被分为64中不同的capabilities。比如加载内核模块的能力、绑定到1024以下端口的能力,我们这里的DAC_READ_SEARCH就是其中的一个。

DAC代表自由访问控制,大多数人将其理解为 standard Linux permissions,每个进程都有所有者/组。 为所有文件系统对象分配了所有者,组和权限标志。 DAC_READ_SEARCH允许特权进程忽略DAC的某些部分以进行读取和搜索。

在linux系统上,输入man capabilities可以看到有关DAC_READ_SEARCH的说明:

CAP_DAC_READ_SEARCH

  • Bypass file read permission checks and directory read and execute permission checks;*

There is another CAPABILITY called DAC_OVERRIDE

CAP_DAC_OVERRIDE

  • Bypass file read, write, and execute permission checks.

man capabilities

从上面的说明我们可以看到,DAC_OVERRIDEDAC_READ_SEARCH的权限更大,因为它可以忽略DAC规则来编写和执行内容,而不仅仅是读取内容。

据资料显示,DAC_READ_SEARCH的出现源于内核的改变,这种改变使内核变得更加安全了。

为了理解这句话,我们结合一个例子来进行讲解:

假设有一个叫 hello(hello_t)的小程序,登录到系统后最终会执行。 该程序需要读取/etc/shadow。 在Linux系统上(比如Fedora / RHEL / CentOS以及其他 ),/etc /shadow 具有0000模式。 这意味着,即使系统没有以根用户身份运行(UID = 0),也不允许它们读取/写入/etc/shadow,除非它们具有DAC功能。

随着策略的发展,由于hello需要读取 /etc/shadow,它生成了DAC_OVERIDE AVC,加入我们在编写sepolicy时,将它的sepolicy文件命名为hello_t, 多年以来,一切工作正常,直到内核发生了变化……

如果某个进程尝试读取/etc/shadow,则允许该进程具有DAC_OVERRIDEDAC_READ_SEARCH

在老版本的kernel里面有类似这样一段代码:

if DAC_OVERRIDE or DAC_READ_SEARCH:
	Read a file with 0000 mode.

但是,在新的kernel中,已经改成下面的形式:

if DAC_READ_SEARCH or DAC_OVERRIDE
	Read a file with 0000 mode.

假如在老的版本,你已经为 hello_t 添加了 DAC_OVERRIDE的权限,但是它从来不检查DAC_READ_SEARCH。

但是在新版本中,它首先检查DAC_READ_SEARCH,因此即使允许最终访问,我们也看到正在生成AVC。但是我们可以看到,虽然会生成avc打印,但是事实上,仍然允许访问。

在前面讲到,由于DAC_OVERRIDE权限比较大,在不需要的情况下,如果需要添加DAC_READ_SEARCH的时候,建议可以去掉DAC_OVERRIDE。因为其实hello_t并不需要更改/etc/shadow,而只是读取而已,这样可以更加安全。

最后,消除DAC_READ_SEARCH最简单的方法,可以在我们的te文件里加上下面这一句:

dontaudit hello_t self:capability { dac_read_search };

https://danwalsh.livejournal.com/77140.html

4 SYS_PTRACE

当我们运行ps 、top等命令时,经常会碰到selinux报 SYS_PTRACE 的权限问题。

通常,当我们的应用运行 ps 或者读取 /proc的内容时,会提示 SYS_PTRACE 的问题。

https://bugzilla.redhat.com/show_bug.cgi?id=1202043

比如selinux的打印可能像下面这样:

type=AVC msg=audit(1426354432.990:29008): avc:  denied  { sys_ptrace } for  pid=14391 comm="ps" capability=19  scontext=unconfined_u:unconfined_r:mozilla_plugin_t:s0-s0:c0.c1023 tcontext=unconfined_u:unconfined_r:mozilla_plugin_t:s0-s0:c0.c1023 tclass=capability permissive=0

sys_ptrace通常指示一个进程正在尝试查看具有不同UID的另一个进程的内存。

通过man 命令 man capabilities 查看sys_ptrace的说明:

CAP_SYS_PTRACE

  • Trace arbitrary processes using ptrace(2);
  • apply get_robust_list(2) to arbitrary processes;
  • transfer data to or from the memory of arbitrary processes
    using process_vm_readv(2) and process_vm_writev(2).
  • inspect processes using kcmp(2).

这些访问类型可能应该处理为: dontaudited

运行ps命令是特权进程,可能会导致sys_ptrace发生。

/proc下有一些特殊数据,特权进程可以通过运行ps命令来访问这些数据,运行ps的进程几乎从未真正需要此数据,调试工具使用了该数据,来看看在哪里设置了进程的一些随机内存。

因此最容易的修改方法是处理为:dontaudit

dontaudit:表示不记录违反规则的决策信息,且违反规则不影响运行(允许操作且不记录)

dontaudit mozilla_plugin_t self:capability { sys_ptrace };

https://danwalsh.livejournal.com/71981.html

5 execute和execute_no_trans

当我们通过sh脚本或者bin文件运行系统命令(比如ls、ps等 )时,可能会遇到下面的selinux avc提示:

avc: denied { execute } for comm="hello.sh" name="toolbox" dev="dm-1" ino=223 scontext=u:r:hello:s0 tcontext=u:object_r:vendor_toolbox_exec:s0 tclass=file permissive=0

avc: denied { execute_no_trans } for comm="hello.sh" path="/vendor/bin/toolbox" dev="dm-1" ino=223 scontext=u:r:hello:s0 tcontext=u:object_r:vendor_toolbox_exec:s0 tclass=file permissive=0

通常我们会按照sepolicy的规则,添加规则下面的规则到te文件:

allow hello vendor_toolbox_exec:file { execute execute_no_trans };

这时,我们编译工程时,可能会遇到编译失败的问题,提示neverallow:

libsepol.report_failure: neverallow on line 952 of system/sepolicy/public/domain.te (or line 12401 of policy.conf) violated by allow hello vendor_toolbox_exec:file { execute execute_no_trans };

我遇到的情况有一个/system/bin/hello的可执行文件,执行ntpdate命令时,出现这个avc。而/system分区下没有ntpdate命令,因此会自动去执行/vendor/bin/ntpdate命令。

当我们添加sepolicy规则时,之所以出现neverallow,就在于我们是通过/system分区去执行/vendor分区命令。由于Google启动的Treble计划,为实现分区可独立升级,为防止分区升级造成分区调用出现问题。因此,是禁止分区之间调用的。

经过一段时间的尝试之后,通过两种方法解决了这个问题:

  • /vendor/bin/ntpdate移植到/system/bin/下,当然因为在/system/bin/下的这个bin文件只有我们自己使用,为安全起见,可以给文件名改名处理,比如/system/bin/ntpdate_my

  • 通过hidl机制,做一个服务去执行/vendor/bin/ntpdate,然后将结果返回给/system分区,不过这种做法比较适合只取一次结果的情况,不适合像top、ping之类的命令。

6 udp_socket ioctl

ifconfig: type=1400 audit(0.0:485): avc: denied { ioctl } for path="socket:[34115]" dev="sockfs" ino=34115 ioctlcmd=0x8927 scontext=u:r:start-ssh:s0 tcontext=u:r:start-ssh:s0 tclass=udp_socket permissive=1
tcpdump : type=1400 audit(0.0:766): avc: denied { ioctl } for path="socket:[35389]" dev="sockfs" ino=35389 ioctlcmd=0x8994 scontext=u:r:start-ssh:s0 tcontext=u:r:start-ssh:s0 tclass=udp_socket permissive=1

setenfoce 0和配置allow system_app self:udp_socket ioctl; 后操作依然被denied,这是由于ioctl的控制在底层划分的更细,需要允许对应ioctlcmd操作。

具体方法为:

1、查找android/system/sepolicy/public/ioctl_defines中对应的ioctlcmdioctl_defines中的定义,如上文中的ioctlcmd=0x8927,对应的是SIOCGIFHWADDRioctlcmd=0x8994对应的是SIOCBONDINFOQUERY

2、在对应的te文件加入如下的配置:

allowxperm start-ssh self:udp_socket ioctl { SIOCGIFHWADDR SIOCBONDINFOQUERY };

这样,在ioctl操作时,对应的ioctlcmd就会被允许了。

相关命令

SELinux是经过安全强化的Linux操作系统,一些原有的命令都进行了扩展,另外还增加了一些新的命令,下面让我们看看经常用到的几个命令:

1)ls -Z命令

查看文件,目录的安全属性:

root@xxx:/ # ls –Z

drwxr-x–x root sdcard_r u:object_r:rootfs:s0 storage

dr-xr-xr-x root root u:object_r:sysfs:s0 sys

drwxr-xr-x root root u:object_r:system_file:s0 system

… …

2)ps -Z命令

查看进程的安全属性:

root@xxx:/ # ls -Z

u:r:rild:s0 radio 272 1 /system/bin/rild

u:r:drmserver:s0 drm 273 1 /system/bin/drmserver

u:r:mediaserver:s0 media 274 1 /system/bin/mediaserver

u:r:installd:s0 install 283 1 /system/bin/installd

**
3)chcon命令**

更改文件的安全属性

root@xxx:/ # ls -Z /dev/tfa9890 crw-rw---- media media u:object_r:audio_device:s0 tfa9890root@xxx:/ # chcon u:object_r:device:s0 /dev/tfa9890root@xxx:/ # ls -Z /dev/tfa9890 crw-rw---- media media u:object_r: device:s0 tfa9890

**
**

4)restorecon命令

当文件的安全属性在安全策略配置文件里面有定义时,使用restorecon命令,可以恢复原来的安全属性

root@xxx:/ # restorecon /dev/tfa9890 SELinux: Loaded file_contexts from /file_contextsroot@xxx:/ # ls -Z /dev/tfa9890 crw-rw---- media media u:object_r:audio_device:s0 tfa9890

**
**

5)id命令

使用id命令,能确认自己的SecurityContext

root@xxx:/ # iduid=0(root) gid=0(root) groups=1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats) context=u:r:su:s0

**
**

6)getenforce命令

得到当前SELinux的模式值

root@xxx:/ # getenforce Enforcing

**
**

7)setenforce命令

更改当前的SELINUX的模式值,后面可以跟 enforcing,permissive 或者1,0。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值