设置文件安全上下文的代码实现 ---- SEAndroid in android 5.x

一.设置ROM中的文件的安全上下文
 
     以system.img为例,生成system.img的命令在build/core/Makefile文件中:
BUILT_SYSTEMIMAGE := $(systemimage_intermediates)/system.img
..........
$(BUILT_SYSTEMIMAGE): $(FULL_SYSTEMIMAGE_DEPS)$(INSTALLED_FILES_FILE)
    $(call build-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,$(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
      这里执行了两个命令:
      第一个命令: generate-userimage-prop-dictionary,用来生成一个属性文件/system_image_info.txt。它的第一个参数就是system_image_info.txt。
      查看这个命令的定义,可以发现这个命令依靠一系列的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)

       也就是说,该函数返回给调用者的字典包含一个以selinux_fc为key值的项,它的值指向上述分析的file_contexts文件。
       main函数的最后调用了函数BuildImage来生成最终的system.img文件,在它的实现中有:
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镜像文件。

二.设置虚拟文件系统的安全上下文
       以selinux虚拟文件系统的安装过程为例。在SEAndroid的安全策略,是由external/sepolicy/目录下的文件生成的。查看编译脚本Android.mk,其中有:
sepolicy_build_files := security_classes \
                       initial_sids \
        

你可能感兴趣的:(SEAndroid)