下面的例子运行在中兴android 5.0手机上。
当我们使用root权限的python去创建socket监听端口8088时,selinux向kmsg输出了下面的记录
python-android5 对 socket 的操作 create, setopt, bind, listen等都是denied不允许的,因为目标(target)需要权限在tcontext=u:r:init:s0,但是我们的python运行在root权限下,所以scontext=u:r:init:s0满足了tcontext,我们的操作被允许permissive=1,但不是selinux子系统所希望的,并记录在kmsg。
我们既然成功在8088端口上监听了,那么是否就等同于可以接收incoming连接呢,可能你会想到防火墙过滤,我们就看一下防火墙策略 (8088端口放开了)。
那么我们向上面打开的监听端口8088发起连接,会怎么样呢?结果失败了,请看kmsg输出。
防火墙netd以scontext=u:r:netd:s0,应该是想向端口8088的socket的backlog写入,但是无奈操作socket需要权限tcontext=u:r:init:s0,防火墙对listen的sokcet的操作 { read write }被selinux子系统拒绝 permissive=0,selinux向kmsg输出日志记录。防火墙不是运行在高权限下,即使你的程序提升到root权限了,也无能为力。换句话说,如果你的程序依赖了其它进程的服务,那么你所依赖的进程的selinux权限,也将制约着你的程序。这时只好关闭selinux,但是这样就比较不安全了。
关闭selinux后,我们再次向8088端口发起连接,结果成功了,看kmsg输出。
首先我们的python程序在root权限下创建了socket,同时没有权限的防火墙netd也随selinux子系统的关闭,对socket的操作被允许,这一切都是selinux子系统所不希望的,必须在kmsg记录下日志。后面就是正常的tcp建立连接三次握手,selinux同时也在kmsg记录下日志,日志输出如下。
又一例就是screencap,你在root权限下也不能截屏。
selinux却在kmsg输出记录。
解决就是关闭selinux,通过setenforce 或 /sys/fs/selinux。这样很不安全,另外就是使用supolicy修改个别政策。