Android P版本seLinux导致U盘无法挂载的问题
- 问题背景
- 添加seLinux权限
- Vold挂载文件的contexts
问题背景
简单的描述一下问题背景。某平台上,在打开了selinux后的版本上,测试同学提了一个bug,U盘无法挂载。问题滞留时间太长,本来该模块不是我负责的,属于帮忙分析问题,可能理解不太专业,大家有啥可以指出来。
添加seLinux权限
从抓取的日志中,发现有一条关于fsck的seLinux权限,通过转成allow权限就是
allow fsck_untrusted system_file:file entrypoint;
。想着难道这条权限加上就能解决了?就先尝试了添加这条权限。
添加上这条权限之后,编译报错了
解决完这个编译报错之后真正的问题来了,我们再次编译的时候发现有如下问题
关于这点限制简单的说下,是在android O版本之后,seLinux 分成了两部分,位于 /system/etc/selinux 下的 platform 部分和位于 /vendor/etc/selinux 下的 vendor 部分。coredomain 是 attribute,属于 domain (针对进程)或者 type(针对对象,如文件等)的集合。coremain 可以理解为包含 system 下可执行文件和 apps 所运行的 domain 或者说包含所有属于 Android 的 domain。
然后我将报错部分的coredomain 从 fsck_untrusted 的ypeattribute 中去掉,接着编译,结果还是报错了
这两个报错就很尴尬了,加coredomain也不是,不加也不是。明显加的这条selinux不符合规则,fsck_untrusted.te中也有注释# Only allow entry from vold via fsck binaries
,只是没有太注意。
按照目前的情况来看,通过添加、修改selinux规则来解决这个bug的工作量就有点大了,经大佬指点就换了一个思路和方向。需要看下为什么会用到fsck_untrusted,正常都应该只会用到fsck的contexts才对。
Vold挂载文件的contexts
无法挂载的U盘,看了一下为exfat文件系统。然后去看了一眼系统的源码,system/vold/model/PublicVolume.cpp
看下exfat用到的哪个bin文件去参与挂载阶段的工作
status_t PublicVolume::doMount() {
readMetadata();
LOG(INFO) << "PublicVolume::doMount: mFsType = " << mFsType.c_str();
if (mFsType == "vfat" && vfat::IsSupported()) {
if (vfat::Check(mDevPath)) {
LOG(ERROR) << getId() << " failed filesystem check";
return -EIO;
}
} else if (mFsType == "exfat" && exfat::IsSupported()) {
if (exfat::Check(mDevPath)) {
LOG(ERROR) << getId() << " failed filesystem check";
return -EIO;
}
} else if (mFsType == "ntfs" && ntfs::IsSupported()) {
if (ntfs::Check(mDevPath)) {
LOG(ERROR) << getId() << " failed filesystem check";
return -EIO;
}
} else {
LOG(ERROR) << getId() << " unsupported filesystem " << mFsType;
return -EIO;
}
//省略...
}
我们紧跟着进了exfat::Check函数
从这我们可以看到用的是/system/bin/fsck.exfat
这个binary文件,然后我们就进机器看下这个文件对应的contexts是什么(ls -lZ)
然后就惊奇的发现fsck.exfat该bin文件的contexts和其他的有点不一样,使用的是u:object_r:system_file:s0
,猜想一波,是不是由于这个文件的contexts不对,然后导致没有按照指定的规则,通过fsck.te的规则校验,而是找到了fsck_untrusted.te的规则。
接下来验证一波猜想,通过命令 chcon u:object_r:fsck_exec:s0 fsck.exfat
改变一下该文件的contexts。插上U盘,发现可以正常挂载了,说明问题点就在这里。那么接下来的就是给相对的bin文件加上正确的contexts就好system/sepolicy/private/file_contexts
最后整编一个ROM,验证ok