From 56882bf9b41dc7f8b98f1dea82633144546450b2 Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Thu, 9 Feb 2012 13:36:21 -0500 Subject: [PATCH] Support the setting of file security contexts in OTA and update packages. Pass the file_contexts configuration to the releasetools scripts so that the security contexts of files can be properly set for OTA and update packages. Requires Ica5fb73d6f2ffb981b74d1896538988dbc4d9b24 Change-Id: I5a63fd61a7e74d386d0803946d06bcf2fa8a857e --- core/Makefile | 10 ++++++---- tools/releasetools/edify_generator.py | 4 ++-- tools/releasetools/img_from_target_files | 22 ++++++++++++++++++++-- tools/releasetools/ota_from_target_files | 22 ++++++++++++++++++---- 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/core/Makefile b/core/Makefile index 279dd8c700..b657b48a56 100644 --- a/core/Makefile +++ b/core/Makefile @@ -1164,12 +1164,13 @@ INTERNAL_OTA_PACKAGE_TARGET := $(PRODUCT_OUT)/$(name).zip $(INTERNAL_OTA_PACKAGE_TARGET): KEY_CERT_PAIR := $(DEFAULT_KEY_CERT_PAIR) -$(INTERNAL_OTA_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) $(OTATOOLS) +$(INTERNAL_OTA_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) $(OTATOOLS) $(SELINUX_DEPENDS) @echo "Package OTA: $@" $(hide) ./build/tools/releasetools/ota_from_target_files -v \ + $(if $(filter true, $(strip $(HAVE_SELINUX))),-S $(TARGET_ROOT_OUT)/file_contexts) \ -p $(HOST_OUT) \ - -k $(KEY_CERT_PAIR) \ - $(BUILT_TARGET_FILES_PACKAGE) $@ + -k $(KEY_CERT_PAIR) \ + $(BUILT_TARGET_FILES_PACKAGE) $@ .PHONY: otapackage otapackage: $(INTERNAL_OTA_PACKAGE_TARGET) @@ -1192,11 +1193,12 @@ else $(INTERNAL_UPDATE_PACKAGE_TARGET): extensions := $(TARGET_RELEASETOOLS_EXTENSIONS) endif -$(INTERNAL_UPDATE_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) $(OTATOOLS) +$(INTERNAL_UPDATE_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) $(OTATOOLS) $(SELINUX_DEPENDS) @echo "Package: $@" $(hide) ./build/tools/releasetools/img_from_target_files -v \ -s $(extensions) \ -p $(HOST_OUT) \ + $(if $(filter true, $(strip $(HAVE_SELINUX))),-S $(TARGET_ROOT_OUT)/file_contexts) \ $(BUILT_TARGET_FILES_PACKAGE) $@ .PHONY: updatepackage diff --git a/tools/releasetools/edify_generator.py b/tools/releasetools/edify_generator.py index d7b924b68e..12bb48ba40 100644 --- a/tools/releasetools/edify_generator.py +++ b/tools/releasetools/edify_generator.py @@ -165,9 +165,9 @@ class EdifyGenerator(object): fstab = self.info.get("fstab", None) if fstab: p = fstab[partition] - self.script.append('format("%s", "%s", "%s", "%s");' % + self.script.append('format("%s", "%s", "%s", "%s", "%s");' % (p.fs_type, common.PARTITION_TYPES[p.fs_type], - p.device, p.length)) + p.device, p.length, p.mount_point)) def DeleteFiles(self, file_list): """Delete all files in file_list.""" diff --git a/tools/releasetools/img_from_target_files b/tools/releasetools/img_from_target_files index c5b98868b5..ad03398b1a 100755 --- a/tools/releasetools/img_from_target_files +++ b/tools/releasetools/img_from_target_files @@ -27,6 +27,10 @@ Usage: img_from_target_files [flags] input_target_files output_image_zip Include only the bootable images (eg 'boot' and 'recovery') in the output. + -S (--file_context) + the file contexts configuration used to assign SELinux file + context attributes. + """ import sys @@ -50,6 +54,7 @@ if not hasattr(os, "SEEK_SET"): import common OPTIONS = common.OPTIONS +OPTIONS.selinux_fc = None def AddUserdata(output_zip): """Create an empty userdata image and store it in output_zip.""" @@ -74,6 +79,8 @@ def AddUserdata(output_zip): fstab["/data"].fs_type, "data"]) if "userdata_size" in OPTIONS.info_dict: build_command.append(str(OPTIONS.info_dict["userdata_size"])) + if OPTIONS.selinux_fc is not None: + build_command.append(OPTIONS.selinux_fc) else: build_command = ["mkyaffs2image", "-f"] extra = OPTIONS.info_dict.get("mkyaffs2_extra_flags", None) @@ -81,6 +88,9 @@ def AddUserdata(output_zip): build_command.extend(extra.split()) build_command.append(user_dir) build_command.append(img.name) + if OPTIONS.selinux_fc is not None: + build_command.append(OPTIONS.selinux_fc) + build_command.append("/data") p = common.Run(build_command); p.communicate() @@ -126,6 +136,8 @@ def AddSystem(output_zip): fstab["/system"].fs_type, "system"]) if "system_size" in OPTIONS.info_dict: build_command.append(str(OPTIONS.info_dict["system_size"])) + if OPTIONS.selinux_fc is not None: + build_command.append(OPTIONS.selinux_fc) else: build_command = ["mkyaffs2image", "-f"] extra = OPTIONS.info_dict.get("mkyaffs2_extra_flags", None) @@ -133,6 +145,9 @@ def AddSystem(output_zip): build_command.extend(extra.split()) build_command.append(os.path.join(OPTIONS.input_tmp, "system")) build_command.append(img.name) + if OPTIONS.selinux_fc is not None: + build_command.append(OPTIONS.selinux_fc) + build_command.append("/system") p = common.Run(build_command) p.communicate() @@ -160,14 +175,17 @@ def main(argv): pass # deprecated if o in ("-z", "--bootable_zip"): bootable_only[0] = True + if o in ("-S", "--file_context"): + OPTIONS.selinux_fc = a else: return False return True args = common.ParseOptions(argv, __doc__, - extra_opts="b:z", + extra_opts="b:zS:", extra_long_opts=["board_config=", - "bootable_zip"], + "bootable_zip", + "file_context="], extra_option_handler=option_handler) bootable_only = bootable_only[0] diff --git a/tools/releasetools/ota_from_target_files b/tools/releasetools/ota_from_target_files index 1514ea7953..f838c220e5 100755 --- a/tools/releasetools/ota_from_target_files +++ b/tools/releasetools/ota_from_target_files @@ -51,6 +51,11 @@ Usage: ota_from_target_files [flags] input_target_files output_ota_package -a (--aslr_mode) Specify whether to turn on ASLR for the package (on by default). + + -S (--file_context) + the file contexts configuration used to assign SELinux file + context attributes + """ import sys @@ -87,6 +92,7 @@ OPTIONS.omit_prereq = False OPTIONS.extra_script = None OPTIONS.aslr_mode = True OPTIONS.worker_threads = 3 +OPTIONS.selinux_fc = None def MostPopularKey(d, default): """Given a dict, return the key corresponding to the largest @@ -388,6 +394,9 @@ def WriteFullOTAPackage(input_zip, output_zip): if OPTIONS.wipe_user_data: script.FormatPartition("/data") + if OPTIONS.selinux_fc is not None: + WritePolicyConfig(OPTIONS.selinux_fc, output_zip) + script.FormatPartition("/system") script.Mount("/system") script.UnpackPackageDir("recovery", "/system") @@ -426,15 +435,17 @@ def WriteFullOTAPackage(input_zip, output_zip): script.AddToZip(input_zip, output_zip) WriteMetadata(metadata, output_zip) +def WritePolicyConfig(file_context, output_zip): + f = open(file_context, 'r'); + basename = os.path.basename(file_context) + common.ZipWriteStr(output_zip, basename, f.read()) + def WriteMetadata(metadata, output_zip): common.ZipWriteStr(output_zip, "META-INF/com/android/metadata", "".join(["%s=%s\n" % kv for kv in sorted(metadata.iteritems())])) - - - def LoadSystemFiles(z): """Load all the files from SYSTEM/... in a given target-files ZipFile, and return a dict of {filename: File object}.""" @@ -753,12 +764,14 @@ def main(argv): OPTIONS.aslr_mode = False elif o in ("--worker_threads"): OPTIONS.worker_threads = int(a) + elif o in ("-S", "--file_context"): + OPTIONS.selinux_fc = a else: return False return True args = common.ParseOptions(argv, __doc__, - extra_opts="b:k:i:d:wne:a:", + extra_opts="b:k:i:d:wne:a:S:", extra_long_opts=["board_config=", "package_key=", "incremental_from=", @@ -767,6 +780,7 @@ def main(argv): "extra_script=", "worker_threads=", "aslr_mode=", + "file_context=", ], extra_option_handler=option_handler)