SEAndroid

博观而约取,厚积而薄发。这篇文章主要讲述SEAndroid相关的知识,希望能为你提供帮助。
SEandroid安全机制所要保护的对象是系统中的资源,这些资源分布在各个子系统中,例如我们经常接触的文件就是分布文件子系统中的。
实际上,系统中需要保护的资源非常多,除了前面说的文件之外,还有进程、socket和IPC等等。
在用户空间中,SEAndroid包含有三个主要的模块,分别是安全上下文(Security Context)、安全策略(SEAndroid Policy)和安全服务(Security Server)
例子:
init.rc u:object_r:rootfs:s0 init.rc
init.rc这个文件的SELinux用户、SELinux角色、类型和安全级别分别为u、object_r、rootfs和s0。
mac_permissions.xml文件mac_permissions.xml给不同签名的App分配不同的seinfo字符串,例如,在AOSP源码环境下编译并且使用平台签名的App获得的seinfo为“ platform” ,使用第三方签名安装的App获得的seinfo签名为"default"。
这个seinfo描述的其实并不是安全上下文中的Type,它是用来在另外一个文件external/sepolicy/seapp_contexts中查找对应的Type的
设置ROM中的文件的安全上下文以system.img为例,生成system.img的命令在build/core/Makefile文件中:

BUILT_SYSTEMIMAGE := $(systemimage_intermediates)/system.img .......... $(BUILT_SYSTEMIMAGE): $(FULL_SYSTEMIMAGE_DEPS)$(INSTALLED_FILES_FILE) $(callbuild-systemimage-target,$@)

可见system.img是由build-systemimage-target命令生成的。
再看build-systemimage-target的定义:
define build-systemimage-target @echo "Target system fs image: $(1)" $(call create-system-vendor-symlink) @mkdir -p $(dir $(1))$(systemimage_intermediates) & & rm -rf$(systemimage_intermediates)/system_image_info.txt //call generate-userimage-prop-dictionary $(call generate-userimage-prop-dictionary,$(systemimage_intermediates)/system_image_info.txt,skip_fsck=true) $(hide) PATH=$(foreachp,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH./build/tools/releasetools/build_image.py$(TARGET_OUT) $(systemimage_intermediates)/system_image_info.txt$(1)|| ( echo "Out of space? the tree size of $(TARGET_OUT) is (MB): "1> & 2 ; du -sm $(TARGET_OUT) 1> & 2; echo "The max is $$(( $(BOARD_SYSTEMIMAGE_PARTITION_SIZE) / 1048576)) MB." 1> & 2 ; mkdir -p $(DIST_DIR); cp $(INSTALLED_FILES_FILE)$(DIST_DIR)/installed-files-rescued.txt; exit 1 ) endef

【SEAndroid】这里执行了两个命令:
第一个命令:generate-userimage-prop-dictionary,用来生成一个属性文件system_image_info.txt。它的第一个参数就是system_image_info.txt。这里面存储一下变量供mkuserimg.sh使用
比如
fs_type=ext4 system_size= userdata_size= selinux_fc=...

查看这个命令的定义,可以发现这个命令依靠一系列的echo命令来将keyvalue格式的配置写入到文件system_image_info.txt当中。该命令的定义中有一行:
$(hide) echo "selinux_fc=$(SELINUX_FC)" > > $(1)

查看变量SELINUX_FC的赋值:
SELINUX_FC :=$(TARGET_ROOT_OUT)/file_contexts。即OUT/root/file_context,这个文件就是根据external/sepolicy/file_contexts来生成的。
第二个命令:./build/tools/releasetools/build_image.py,是一个python脚本,用来制作system.img镜像文件。而且这个命令将会使用到第一个命令里生成的属性文件/system_image_info.txt。查看该命令的入口函数:
def main(argv): if len(argv) != 3: print__doc__ sys.exit(1)in_dir = argv[0] glob_dict_file =argv[1] out_file =argv[2] glob_dict =LoadGlobalDict(glob_dict_file) image_filename =os.path.basename(out_file) mount_point = "" if image_filename == "system.img": mount_point= "system" elif image_filename == "userdata.img": mount_point= "data" elif image_filename == "cache.img": mount_point= "cache" elif image_filename == "vendor.img": mount_point= "vendor" elif image_filename == "oem.img": mount_point= "oem" else: print> > sys.stderr, "error: unknown image file name ",image_filename exit(1)image_properties = ImagePropFromGlobalDict(glob_dict,mount_point) if not BuildImage(in_dir,image_properties, out_file): print> > sys.stderr, "error: failed to build %s from %s" %(out_file, in_dir) exit(1)

参数argv[1]指向的就是我们上面提到的属性文件system_image_info.txt,最终保存在本地变量glob_dict_file中。另外一个参数argv[2]指向的要输出的system.img文件路径,最终保存在本地变量out_file中。
函数LoadGlobalDict用来打开属性文件system_image_info.txt,并且将它每一行的key和value提取出来,并且保在字典glob_dict中。注意,这个字典glob_dict包含有一个key等于selinux_fc、value等于file_contexts文件路径的项。
接下来再通过os.path.basename将输出的文件路径out_file的最后一项提取出来,就可以得到image_filename的值为” system.img“ ,因此再接下来就会得到本地变量mount_point的值为” system“ ,表示我们现在正在打包的是system.img文件。
函数ImagePropFromGlobalDict用来从字典glob_dict中提取与安装点mount_point相关的项,并且保存在另外一个字典中返回给调用者,在它的实现中有:
common_props = ( "extfs_sparse_flag", "mkyaffs2_extra_flags", "selinux_fc", "skip_fsck", "verity", "verity_key", "verity_signer_cmd", "transparent_compression_method" ) for p in common_props: copy_prop(p,p)if fc_config is not None: build_command.append(fc_config) elif"selinux_fc" in prop_dict: build_command.append(prop_dict["selinux_fc"]) .............. if "selinux_fc" in prop_dict: build_command.append(prop_dict["selinux_fc"]) build_command.append(prop_dict["mount_point"])

通过这些命令,系统会编译出一个关联有安全上下文的system.img镜像文件。
mkuserimg.shmkuserimg.sh 调用make_ext4fs
-s就是生成ext4的S模式制作;
"-a system",是指这个img用于android系统,挂载点是/system,使用这个参数,make_ext4fs会根据private/android_filesystem_config.h里定义好的权限来给文件夹里的所有文件重新设置权限,如果你刷机以后发现有文件权限不对,可以手工修改android_filesystem_config.h来添加权限,重新编译make_ext4fs,
也可以不使用 “ -a system” 参数,这样就会使用文件的默认权限。
如果不使用-a参数,则可。




    推荐阅读