SEAndroid学习笔记

SEAndroid相关 Android的权限管理:一般分为2种,一种是基于Linux的DAC模式,一种就是Android自主的manifest权限的监控。
第一种是Linux自主的基于uid和gid设置的权限监控,但是这种权限有很大的局限性,比如系统文件的所有者,如果不小心将文件的所有人权限设置为读写,如果这是一个相当敏感的权限的话,那么就会导致无法想象的后果。
第二种是基于android的,android本身就是上层了,对app层权限控制应该还是可以的,但是总是有兼顾不到的地方。

Android在4.4的时候就已经引进了更加安全的SELinux机制,但是由于不完善的原因,所以在4.4的时代,SELinux一直都是处于宽容模式——permissive模式,就是说,你如果触犯到被禁用的权限了,没关系,我也会让你使用该权限但是我会记录在小本子上。但是从5.0之后,SEAndroid正式进入了enforce时代。这是一个出了问题都不知道问题出在什么地方的时代。“妈蛋,这个地方在4.4上明明可以,为什么移植过来就完全不能用了!”

其实SELinux已经有了十多年的历史了,是一个非常稳定的权限管理系统了,SELinux区别于DAC模式的最重要的依据就是:权限不是自己可以控制的,而是需要一个第三方的地方去控制,这个就是SELinux的sepolicy了。

好了,基础的一些东西也就不说了,详细的可以去看罗升阳的blog邓凡平的blog其中,罗升阳比较注重SEAndroid的实现原理,而邓凡平则比较注重实用与理论结合。在我看来,还是两者结合着看比较好。

我说一下我工作中遇到的一些问题吧,算是对自己工作的总结吧。

首先,如果一个问题在4.4上是没有问题的,但是在5.0上却有问题了,可以尝试在adb shell中先将SEAndroid修改成permissive模式,这样进行测试,如果结果是可行的,那就说明是SEAndroid在搞鬼了,但是如果是还是无法运行通过的话,那应该就是你代码问题了。

同时你说:我发现是SEAndroid的问题了,但是log就只是简单的提示了我permission deny,那我应该怎么办。其实是这样的,SEAndroid日志是打印在内核里面的,所以你需要在shell下使用dmesg命令来打印内核log,但是内核log不像adb log那样是一直打印,它是只能打印缓冲区中的log,而缓冲区大小是固定的,所以你需要在发生permissiondeny的时候,赶快打印log,然后在log中搜索avc关键字,一般这个关键字就是对应的SEAndroid打印出来的log了,avc是什么,其实是这样,sepolicy是在根目录下的一个文件,在系统起来的时候,会将这个文件读取到内存中缓存起来,这个缓存的位置就是avc拉,这样在来查询权限的时候就会快速灵敏很多。

至于在avc打印出来的日志的话,也就是deny的日志了,这个日志会提醒你是那个进程去申请什么权限对另外一个文件。所以只要找到对应的te文件,加上对应的权限就可以了。

也需要注意的是:尽量做到权限最小化,这个也是SELinux的基本原则。比如你需要添加一个系统属性,但是只有你这个进程可以修改,你是systemapp这个domain,但是你不希望其他系统app也可以修改这个属性,你就需要单独给这个属性定义安全上下文。

然后修改好了权限之后,当然是编译进去查看一下了。因为sepolicy是编译在boot中,所以进入到源代码根目录,将环境配好后,然后执行make bootimag命令,将boot编译出来,把boot烧到手机中开机就可以了。

当然在编译的过程中也会出现问题的,比如说:会有neverallow的语句阻止你写一些allow的语句的哦。所以要注意编写sepolicy的语法和冲突问题哈。