diff options
-rw-r--r-- | core/Makefile | 53 | ||||
-rw-r--r-- | core/clang/TARGET_arm.mk | 4 | ||||
-rw-r--r-- | core/clang/TARGET_arm64.mk | 4 | ||||
-rw-r--r-- | core/clang/config.mk | 4 | ||||
-rw-r--r-- | core/config_sanitizers.mk | 9 | ||||
-rw-r--r-- | core/definitions.mk | 70 | ||||
-rw-r--r-- | core/main.mk | 18 | ||||
-rw-r--r-- | core/proguard_basic_keeps.flags | 5 | ||||
-rw-r--r-- | target/board/generic_arm64/BoardConfig.mk | 2 | ||||
-rw-r--r-- | target/board/generic_mips64/BoardConfig.mk | 2 | ||||
-rwxr-xr-x | target/board/generic_x86_64/BoardConfig.mk | 4 | ||||
-rwxr-xr-x | tools/releasetools/add_img_to_target_files.py | 12 | ||||
-rwxr-xr-x | tools/releasetools/build_image.py | 8 | ||||
-rw-r--r-- | tools/releasetools/common.py | 57 | ||||
-rwxr-xr-x | tools/releasetools/img_from_target_files.py | 13 | ||||
-rwxr-xr-x | tools/releasetools/ota_from_target_files.py | 10 | ||||
-rwxr-xr-x | tools/releasetools/sign_target_files_apks.py | 16 | ||||
-rw-r--r-- | tools/releasetools/test_common.py | 211 |
18 files changed, 310 insertions, 192 deletions
diff --git a/core/Makefile b/core/Makefile index b119e96..b5cb727 100644 --- a/core/Makefile +++ b/core/Makefile @@ -67,7 +67,9 @@ ADDITIONAL_DEFAULT_PROPERTIES += \ ADDITIONAL_DEFAULT_PROPERTIES := $(call uniq-pairs-by-first-component, \ $(ADDITIONAL_DEFAULT_PROPERTIES),=) -$(INSTALLED_DEFAULT_PROP_TARGET): +intermediate_system_build_prop := $(call intermediates-dir-for,ETC,system_build_prop)/build.prop + +$(INSTALLED_DEFAULT_PROP_TARGET): $(intermediate_system_build_prop) @echo Target buildinfo: $@ @mkdir -p $(dir $@) $(hide) echo "#" > $@; \ @@ -75,7 +77,13 @@ $(INSTALLED_DEFAULT_PROP_TARGET): echo "#" >> $@; $(hide) $(foreach line,$(ADDITIONAL_DEFAULT_PROPERTIES), \ echo "$(line)" >> $@;) - build/tools/post_process_props.py $@ + $(hide) echo "#" >> $@; \ + echo "# BOOTIMAGE_BUILD_PROPERTIES" >> $@; \ + echo "#" >> $@; + $(hide) echo ro.bootimage.build.date=`date`>>$@ + $(hide) echo ro.bootimage.build.date.utc=`date +%s`>>$@ + $(hide) echo ro.bootimage.build.fingerprint="$(BUILD_FINGERPRINT)">>$@ + $(hide) build/tools/post_process_props.py $@ # ----------------------------------------------------------------- # build.prop @@ -107,7 +115,7 @@ BUILD_VERSION_TAGS := $(subst $(space),$(comma),$(sort $(BUILD_VERSION_TAGS))) # A human-readable string that descibes this build in detail. build_desc := $(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT) $(PLATFORM_VERSION) $(BUILD_ID) $(BUILD_NUMBER) $(BUILD_VERSION_TAGS) -$(INSTALLED_BUILD_PROP_TARGET): PRIVATE_BUILD_DESC := $(build_desc) +$(intermediate_system_build_prop): PRIVATE_BUILD_DESC := $(build_desc) # The string used to uniquely identify the combined build and product; used by the OTA server. ifeq (,$(strip $(BUILD_FINGERPRINT))) @@ -171,7 +179,7 @@ system_prop_file := $(TARGET_SYSTEM_PROP) else system_prop_file := $(wildcard $(TARGET_DEVICE_DIR)/system.prop) endif -$(INSTALLED_BUILD_PROP_TARGET): $(BUILDINFO_SH) $(INTERNAL_BUILD_ID_MAKEFILE) $(BUILD_SYSTEM)/version_defaults.mk $(system_prop_file) $(INSTALLED_ANDROID_INFO_TXT_TARGET) +$(intermediate_system_build_prop): $(BUILDINFO_SH) $(INTERNAL_BUILD_ID_MAKEFILE) $(BUILD_SYSTEM)/version_defaults.mk $(system_prop_file) $(INSTALLED_ANDROID_INFO_TXT_TARGET) @echo Target buildinfo: $@ @mkdir -p $(dir $@) $(hide) echo > $@ @@ -231,6 +239,19 @@ endif build_desc := +ifeq (,$(filter true, $(TARGET_NO_KERNEL) $(TARGET_NO_RECOVERY))) +INSTALLED_RECOVERYIMAGE_TARGET := $(PRODUCT_OUT)/recovery.img +else +INSTALLED_RECOVERYIMAGE_TARGET := +endif + +$(INSTALLED_BUILD_PROP_TARGET): $(intermediate_system_build_prop) $(INSTALLED_RECOVERYIMAGE_TARGET) + @echo "Target build info: $@" + $(hide) cat $(intermediate_system_build_prop) > $@ +ifdef INSTALLED_RECOVERYIMAGE_TARGET + $(hide) echo ro.expect.recovery_id=`cat $(RECOVERYIMAGE_ID_FILE)` >> $@ +endif + # ----------------------------------------------------------------- # vendor build.prop # @@ -248,19 +269,6 @@ $(INSTALLED_VENDOR_BUILD_PROP_TARGET): $(INSTALLED_BUILD_PROP_TARGET) endif # ---------------------------------------------------------------- -# boot.img build.prop -# as with vendor build.prop above, for verifying that the bootimage -# build is what we think it is - -INSTALLED_BOOTIMAGE_BUILD_PROP_TARGET := $(TARGET_ROOT_OUT)/build.prop -ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_BOOTIMAGE_BUILD_PROP_TARGET) -$(INSTALLED_BOOTIMAGE_BUILD_PROP_TARGET): $(INSTALLED_BUILD_PROP_TARGET) - @echo Target bootimage buildinfo: $@ - @mkdir -p $(dir $@) - $(hide) echo > $@ - $(hide) echo ro.bootimage.build.date=`date`>>$@ - $(hide) echo ro.bootimage.build.date.utc=`date +%s`>>$@ - $(hide) echo ro.bootimage.build.fingerprint="$(BUILD_FINGERPRINT)">>$@ # ----------------------------------------------------------------- # sdk-build.prop @@ -750,10 +758,7 @@ endef # ----------------------------------------------------------------- # Recovery image -# If neither TARGET_NO_KERNEL nor TARGET_NO_RECOVERY are true -ifeq (,$(filter true, $(TARGET_NO_KERNEL) $(TARGET_NO_RECOVERY))) - -INSTALLED_RECOVERYIMAGE_TARGET := $(PRODUCT_OUT)/recovery.img +ifdef INSTALLED_RECOVERYIMAGE_TARGET INTERNAL_RECOVERYIMAGE_FILES := $(filter $(TARGET_RECOVERY_OUT)/%, \ $(ALL_DEFAULT_INSTALLED_MODULES)) @@ -762,7 +767,7 @@ recovery_initrc := $(call include-path-for, recovery)/etc/init.rc recovery_sepolicy := $(call intermediates-dir-for,ETC,sepolicy.recovery)/sepolicy.recovery recovery_kernel := $(INSTALLED_KERNEL_TARGET) # same as a non-recovery system recovery_ramdisk := $(PRODUCT_OUT)/ramdisk-recovery.img -recovery_build_prop := $(INSTALLED_BUILD_PROP_TARGET) +recovery_build_prop := $(intermediate_system_build_prop) recovery_resources_common := $(call include-path-for, recovery)/res # Set recovery_density to the density bucket of the device. @@ -846,6 +851,7 @@ $(RECOVERY_INSTALL_OTA_KEYS): $(OTA_PUBLIC_KEYS) $(DUMPKEY_JAR) $(extra_keys) @mkdir -p $(dir $@) java -jar $(DUMPKEY_JAR) $(PRIVATE_OTA_PUBLIC_KEYS) $(extra_keys) > $@ +RECOVERYIMAGE_ID_FILE := $(PRODUCT_OUT)/recovery.id # $(1): output file define build-recoveryimage-target @echo ----- Making recovery image ------ @@ -873,7 +879,7 @@ define build-recoveryimage-target $(hide) $(MKBOOTFS) $(TARGET_RECOVERY_ROOT_OUT) | $(MINIGZIP) > $(recovery_ramdisk) $(if $(filter true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT)), \ $(hide) $(MKBOOTIMG) $(INTERNAL_RECOVERYIMAGE_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(1).unsigned, \ - $(hide) $(MKBOOTIMG) $(INTERNAL_RECOVERYIMAGE_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(1)) + $(hide) $(MKBOOTIMG) $(INTERNAL_RECOVERYIMAGE_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(1) --id > $(RECOVERYIMAGE_ID_FILE)) $(if $(filter true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_BOOT_SIGNER)),\ $(BOOT_SIGNER) /recovery $(1) $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).pk8 $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).x509.pem $(1)) $(if $(filter true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT)), \ @@ -903,7 +909,6 @@ recoveryimage-nodeps: $(call build-recoveryimage-target, $(INSTALLED_RECOVERYIMAGE_TARGET)) else -INSTALLED_RECOVERYIMAGE_TARGET := RECOVERY_RESOURCE_ZIP := endif diff --git a/core/clang/TARGET_arm.mk b/core/clang/TARGET_arm.mk index 6f6d624..62ce242 100644 --- a/core/clang/TARGET_arm.mk +++ b/core/clang/TARGET_arm.mk @@ -66,3 +66,7 @@ $(clang_2nd_arch_prefix)RS_TRIPLE_CFLAGS := $(clang_2nd_arch_prefix)RS_COMPAT_TRIPLE := armv7-none-linux-gnueabi $(clang_2nd_arch_prefix)TARGET_LIBPROFILE_RT := $(LLVM_RTLIB_PATH)/libclang_rt.profile-arm-android.a + +# Address sanitizer clang config +$(clang_2nd_arch_prefix)ADDRESS_SANITIZER_RUNTIME_LIBRARY := libclang_rt.asan-arm-android +$(clang_2nd_arch_prefix)ADDRESS_SANITIZER_RPATH := /system/lib/asan diff --git a/core/clang/TARGET_arm64.mk b/core/clang/TARGET_arm64.mk index b67d458..ea4d937 100644 --- a/core/clang/TARGET_arm64.mk +++ b/core/clang/TARGET_arm64.mk @@ -64,3 +64,7 @@ RS_TRIPLE_CFLAGS := RS_COMPAT_TRIPLE := aarch64-linux-android TARGET_LIBPROFILE_RT := $(LLVM_RTLIB_PATH)/libclang_rt.profile-aarch64-android.a + +# Address sanitizer clang config +ADDRESS_SANITIZER_RUNTIME_LIBRARY := libclang_rt.asan-arm64-android +ADDRESS_SANITIZER_RPATH := /system/lib64/asan diff --git a/core/clang/config.mk b/core/clang/config.mk index 6da90ec..dfad7ec 100644 --- a/core/clang/config.mk +++ b/core/clang/config.mk @@ -149,12 +149,10 @@ clang_2nd_arch_prefix := $(TARGET_2ND_ARCH_VAR_PREFIX) include $(BUILD_SYSTEM)/clang/TARGET_$(TARGET_2ND_ARCH).mk endif -# Address sanitizer clang config -ADDRESS_SANITIZER_RUNTIME_LIBRARY := libclang_rt.asan_$(TARGET_ARCH)_android ADDRESS_SANITIZER_CONFIG_EXTRA_CFLAGS := -fno-omit-frame-pointer ADDRESS_SANITIZER_CONFIG_EXTRA_LDFLAGS := -Wl,-u,__asan_preinit -ADDRESS_SANITIZER_CONFIG_EXTRA_SHARED_LIBRARIES := libdl $(ADDRESS_SANITIZER_RUNTIME_LIBRARY) +ADDRESS_SANITIZER_CONFIG_EXTRA_SHARED_LIBRARIES := libdl ADDRESS_SANITIZER_CONFIG_EXTRA_STATIC_LIBRARIES := libasan # This allows us to use the superset of functionality that compiler-rt diff --git a/core/config_sanitizers.mk b/core/config_sanitizers.mk index 210d442..7eb1c89 100644 --- a/core/config_sanitizers.mk +++ b/core/config_sanitizers.mk @@ -78,10 +78,15 @@ ifneq ($(filter address,$(my_sanitize)),) ifdef LOCAL_IS_HOST_MODULE # -nodefaultlibs (provided with libc++) prevents the driver from linking # libraries needed with -fsanitize=address. http://b/18650275 (WAI) - my_ldlibs += -ldl -lpthread + my_ldlibs += -lm -ldl -lpthread + my_ldflags += -Wl,--no-as-needed else - my_shared_libraries += $(ADDRESS_SANITIZER_CONFIG_EXTRA_SHARED_LIBRARIES) + # ASan runtime library must be the first in the link order. + my_shared_libraries := $($(LOCAL_2ND_ARCH_VAR_PREFIX)ADDRESS_SANITIZER_RUNTIME_LIBRARY) \ + $(my_shared_libraries) \ + $(ADDRESS_SANITIZER_CONFIG_EXTRA_SHARED_LIBRARIES) my_static_libraries += $(ADDRESS_SANITIZER_CONFIG_EXTRA_STATIC_LIBRARIES) + my_ldflags += -Wl,-rpath,$($(LOCAL_2ND_ARCH_VAR_PREFIX)ADDRESS_SANITIZER_RPATH) endif endif diff --git a/core/definitions.mk b/core/definitions.mk index fc18ee3..bbc4b06 100644 --- a/core/definitions.mk +++ b/core/definitions.mk @@ -1671,12 +1671,6 @@ else xlint_unchecked := -Xlint:unchecked endif -ifeq (true, $(ENABLE_INCREMENTALJAVAC)) -incremental_dex := --incremental -else -incremental_dex := -endif - # emit-line, <word list>, <output file> define emit-line $(if $(1),echo -n '$(strip $(1)) ' >> $(2)) @@ -1936,69 +1930,6 @@ $(if $(PRIVATE_JAR_EXCLUDE_PACKAGES), $(hide) echo unsupported options JAR_EXCLU $(if $(PRIVATE_JAR_MANIFEST), $(hide) echo unsupported options JAR_MANIFEST in $@; exit 53) endef -# Override the above definitions if we want to do incremetal javac -ifeq (true, $(ENABLE_INCREMENTALJAVAC)) -define compile-java -$(hide) mkdir -p $(dir $@) -$(hide) mkdir -p $(PRIVATE_CLASS_INTERMEDIATES_DIR) -$(hide) touch $(PRIVATE_CLASS_INTERMEDIATES_DIR)/newstamp -$(call unzip-jar-files,$(PRIVATE_STATIC_JAVA_LIBRARIES),$(PRIVATE_CLASS_INTERMEDIATES_DIR)) -$(hide) if [ -e $(PRIVATE_CLASS_INTERMEDIATES_DIR)/stamp ] ; then \ - newerFlag=$$(echo -n "-newer $(PRIVATE_CLASS_INTERMEDIATES_DIR)/stamp") ; \ - fi ; \ - find $(PRIVATE_JAVA_SOURCES) $$newerFlag > $(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list ; \ - if [ -d "$(PRIVATE_SOURCE_INTERMEDIATES_DIR)" ]; then \ - find $(PRIVATE_SOURCE_INTERMEDIATES_DIR) -name '*.java' $$newerFlag >> $(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list; \ - fi -$(hide) tr ' ' '\n' < $(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list \ - | sort -u > $(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list-uniq -@echo "(Incremental) build source files:" -@cat $(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list-uniq -$(hide) if [ -s $(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list-uniq ] ; then \ - $(1) -encoding UTF-8 \ - $(strip $(PRIVATE_JAVAC_DEBUG_FLAGS)) \ - $(if $(findstring true,$(PRIVATE_WARNINGS_ENABLE)),$(xlint_unchecked),) \ - $(2) \ - $(addprefix -classpath ,$(strip \ - $(call normalize-path-list,$(PRIVATE_ALL_JAVA_LIBRARIES) $(PRIVATE_CLASS_INTERMEDIATES_DIR)))) \ - $(if $(findstring true,$(PRIVATE_WARNINGS_ENABLE)),$(xlint_unchecked),) \ - -extdirs "" -d $(PRIVATE_CLASS_INTERMEDIATES_DIR) \ - $(PRIVATE_JAVACFLAGS) \ - \@$(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list-uniq \ - || ( exit 41 ) \ -fi -$(hide) rm -f $(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list -$(hide) rm -f $(PRIVATE_CLASS_INTERMEDIATES_DIR)/java-source-list-uniq -$(hide) rm -f $@ -$(if $(PRIVATE_JAR_EXCLUDE_FILES), $(hide) find $(PRIVATE_CLASS_INTERMEDIATES_DIR) \ - -name $(word 1, $(PRIVATE_JAR_EXCLUDE_FILES)) \ - $(addprefix -o -name , $(wordlist 2, 999, $(PRIVATE_JAR_EXCLUDE_FILES))) \ - | xargs rm -rf) -$(if $(PRIVATE_JAR_PACKAGES), \ - $(hide) find $(PRIVATE_CLASS_INTERMEDIATES_DIR) -mindepth 1 -type f \ - $(foreach pkg, $(PRIVATE_JAR_PACKAGES), \ - -not -path $(PRIVATE_CLASS_INTERMEDIATES_DIR)/$(subst .,/,$(pkg))/\*) -delete ; \ - find $(PRIVATE_CLASS_INTERMEDIATES_DIR) -empty -delete) -$(if $(PRIVATE_JAR_EXCLUDE_PACKAGES), $(hide) rm -rf \ - $(foreach pkg, $(PRIVATE_JAR_EXCLUDE_PACKAGES), \ - $(PRIVATE_CLASS_INTERMEDIATES_DIR)/$(subst .,/,$(pkg)))) -$(if $(PRIVATE_RMTYPEDEFS), $(hide) $(RMTYPEDEFS) -v $(PRIVATE_CLASS_INTERMEDIATES_DIR)) -$(if $(PRIVATE_JAR_MANIFEST), \ - $(hide) sed -e 's/%BUILD_NUMBER%/$(BUILD_NUMBER)/' \ - $(PRIVATE_JAR_MANIFEST) > $(dir $@)/manifest.mf && \ - jar -cfm $@ $(dir $@)/manifest.mf \ - -C $(PRIVATE_CLASS_INTERMEDIATES_DIR) ., \ - $(hide) jar -cf $@ -C $(PRIVATE_CLASS_INTERMEDIATES_DIR) .) -$(if $(PRIVATE_EXTRA_JAR_ARGS),$(call add-java-resources-to,$@)) -$(hide) mv $(PRIVATE_CLASS_INTERMEDIATES_DIR)/newstamp $(PRIVATE_CLASS_INTERMEDIATES_DIR)/stamp -endef - -define transform-java-to-classes.jar -@echo "target Java: $(PRIVATE_MODULE) ($(PRIVATE_CLASS_INTERMEDIATES_DIR))" -$(call compile-java,$(TARGET_JAVAC),$(PRIVATE_BOOTCLASSPATH)) -endef -endif # ENABLE_INCREMENTALJAVAC - define transform-classes.jar-to-emma $(hide) java -classpath $(EMMA_JAR) emma instr -outmode fullcopy -outfile \ $(PRIVATE_EMMA_COVERAGE_FILE) -ip $< -d $(PRIVATE_EMMA_INTERMEDIATES_DIR) \ @@ -2015,7 +1946,6 @@ $(hide) rm -f $(dir $@)classes*.dex $(hide) $(DX) \ $(if $(findstring windows,$(HOST_OS)),,-JXms16M -JXmx2048M) \ --dex --output=$(dir $@) \ - $(incremental_dex) \ $(if $(NO_OPTIMIZE_DX), \ --no-optimize) \ $(if $(GENERATE_DEX_DEBUG), \ diff --git a/core/main.mk b/core/main.mk index 3bf9cae..e04c4c7 100644 --- a/core/main.mk +++ b/core/main.mk @@ -234,23 +234,7 @@ endif # These are the modifier targets that don't do anything themselves, but # change the behavior of the build. # (must be defined before including definitions.make) -INTERNAL_MODIFIER_TARGETS := showcommands all incrementaljavac - -.PHONY: incrementaljavac -incrementaljavac: ; - -# WARNING: -# ENABLE_INCREMENTALJAVAC should NOT be enabled by default, because change of -# a Java source file won't trigger rebuild of its dependent Java files. -# You can only enable it by adding "incrementaljavac" to your make command line. -# You are responsible for the correctness of the incremental build. -# This may decrease incremental build time dramatically for large Java libraries, -# such as core.jar, framework.jar, etc. -ENABLE_INCREMENTALJAVAC := -ifneq (,$(filter incrementaljavac, $(MAKECMDGOALS))) -ENABLE_INCREMENTALJAVAC := true -MAKECMDGOALS := $(filter-out incrementaljavac, $(MAKECMDGOALS)) -endif +INTERNAL_MODIFIER_TARGETS := showcommands all # EMMA_INSTRUMENT_STATIC merges the static emma library to each emma-enabled module. ifeq (true,$(EMMA_INSTRUMENT_STATIC)) diff --git a/core/proguard_basic_keeps.flags b/core/proguard_basic_keeps.flags index 6b3715a..4de5221 100644 --- a/core/proguard_basic_keeps.flags +++ b/core/proguard_basic_keeps.flags @@ -40,6 +40,11 @@ java.lang.Object readResolve(); } +# Keep Throwable's constructor that takes a String argument. +-keepclassmembers class * extends java.lang.Throwable { + <init>(java.lang.String); +} + # Please specify classes to be kept explicitly in your package's configuration. # -keep class * extends android.app.Activity # -keep class * extends android.view.View diff --git a/target/board/generic_arm64/BoardConfig.mk b/target/board/generic_arm64/BoardConfig.mk index c98624d..4b6136d 100644 --- a/target/board/generic_arm64/BoardConfig.mk +++ b/target/board/generic_arm64/BoardConfig.mk @@ -82,3 +82,5 @@ BOARD_CACHEIMAGE_PARTITION_SIZE := 69206016 BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4 BOARD_FLASH_BLOCK_SIZE := 512 TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true + +BOARD_SEPOLICY_DIRS += build/target/board/generic/sepolicy diff --git a/target/board/generic_mips64/BoardConfig.mk b/target/board/generic_mips64/BoardConfig.mk index 7fe6cd3..5c13447 100644 --- a/target/board/generic_mips64/BoardConfig.mk +++ b/target/board/generic_mips64/BoardConfig.mk @@ -71,3 +71,5 @@ BOARD_CACHEIMAGE_PARTITION_SIZE := 69206016 BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4 BOARD_FLASH_BLOCK_SIZE := 512 TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true + +BOARD_SEPOLICY_DIRS += build/target/board/generic/sepolicy diff --git a/target/board/generic_x86_64/BoardConfig.mk b/target/board/generic_x86_64/BoardConfig.mk index 192bbb2..55bafd5 100755 --- a/target/board/generic_x86_64/BoardConfig.mk +++ b/target/board/generic_x86_64/BoardConfig.mk @@ -47,3 +47,7 @@ BOARD_CACHEIMAGE_PARTITION_SIZE := 69206016 BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4 BOARD_FLASH_BLOCK_SIZE := 512 TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true + +BOARD_SEPOLICY_DIRS += \ + build/target/board/generic/sepolicy \ + build/target/board/generic_x86/sepolicy diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py index 7984ad6..eab8113 100755 --- a/tools/releasetools/add_img_to_target_files.py +++ b/tools/releasetools/add_img_to_target_files.py @@ -33,10 +33,6 @@ import os import tempfile import zipfile -# missing in Python 2.4 and before -if not hasattr(os, "SEEK_SET"): - os.SEEK_SET = 0 - import build_image import common @@ -189,7 +185,7 @@ def AddUserdata(output_zip, prefix="IMAGES/"): assert succ, "build userdata.img image failed" common.CheckSize(img.name, "userdata.img", OPTIONS.info_dict) - output_zip.write(img.name, prefix + "userdata.img") + common.ZipWrite(output_zip, img.name, prefix + "userdata.img") img.close() os.rmdir(user_dir) os.rmdir(temp_dir) @@ -226,7 +222,7 @@ def AddCache(output_zip, prefix="IMAGES/"): assert succ, "build cache.img image failed" common.CheckSize(img.name, "cache.img", OPTIONS.info_dict) - output_zip.write(img.name, prefix + "cache.img") + common.ZipWrite(output_zip, img.name, prefix + "cache.img") img.close() os.rmdir(user_dir) os.rmdir(temp_dir) @@ -252,7 +248,7 @@ def AddImagesToTargetFiles(filename): OPTIONS.info_dict["selinux_fc"] = os.path.join( OPTIONS.input_tmp, "BOOT", "RAMDISK", "file_contexts") - input_zip.close() + common.ZipClose(input_zip) output_zip = zipfile.ZipFile(filename, "a", compression=zipfile.ZIP_DEFLATED) @@ -297,7 +293,7 @@ def AddImagesToTargetFiles(filename): banner("cache") AddCache(output_zip) - output_zip.close() + common.ZipClose(output_zip) def main(argv): def option_handler(o, _): diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py index 04ced09..cbcad6d 100755 --- a/tools/releasetools/build_image.py +++ b/tools/releasetools/build_image.py @@ -205,8 +205,8 @@ def BuildImage(in_dir, prop_dict, out_file): Returns: True iff the image is built successfully. """ - # system_root_image=true: build a system.img that combines the contents of /system - # and the ramdisk, and can be mounted at the root of the file system. + # system_root_image=true: build a system.img that combines the contents of + # /system and the ramdisk, and can be mounted at the root of the file system. origin_in = in_dir fs_config = prop_dict.get("fs_config") if (prop_dict.get("system_root_image") == "true" @@ -375,8 +375,8 @@ def ImagePropFromGlobalDict(glob_dict, mount_point): copy_prop("system_size", "partition_size") copy_prop("system_journal_size", "journal_size") copy_prop("system_verity_block_device", "verity_block_device") - copy_prop("system_root_image","system_root_image") - copy_prop("ramdisk_dir","ramdisk_dir") + copy_prop("system_root_image", "system_root_image") + copy_prop("ramdisk_dir", "ramdisk_dir") elif mount_point == "data": # Copy the generic fs type first, override with specific one if available. copy_prop("fs_type", "fs_type") diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py index e05ee3c..ab58fa7 100644 --- a/tools/releasetools/common.py +++ b/tools/releasetools/common.py @@ -32,10 +32,7 @@ import zipfile import blockimgdiff import rangelib -try: - from hashlib import sha1 as sha1 -except ImportError: - from sha import sha as sha1 +from hashlib import sha1 as sha1 class Options(object): @@ -384,6 +381,10 @@ def BuildBootableImage(sourcedir, fs_config_file, info_dict=None): p.communicate() assert p.returncode == 0, "vboot_signer of %s image failed" % path + # Clean up the temp files. + img_unsigned.close() + img_keyblock.close() + img.seek(os.SEEK_SET, 0) data = img.read() @@ -861,16 +862,50 @@ def ZipWrite(zip_file, filename, arcname=None, perms=0o644, zipfile.ZIP64_LIMIT = saved_zip64_limit -def ZipWriteStr(zip_file, filename, data, perms=0o644, compression=None): - # use a fixed timestamp so the output is repeatable. - zinfo = zipfile.ZipInfo(filename=filename, - date_time=(2009, 1, 1, 0, 0, 0)) - if compression is None: +def ZipWriteStr(zip_file, zinfo_or_arcname, data, perms=0o644, + compress_type=None): + """Wrap zipfile.writestr() function to work around the zip64 limit. + + Even with the ZIP64_LIMIT workaround, it won't allow writing a string + longer than 2GiB. It gives 'OverflowError: size does not fit in an int' + when calling crc32(bytes). + + But it still works fine to write a shorter string into a large zip file. + We should use ZipWrite() whenever possible, and only use ZipWriteStr() + when we know the string won't be too long. + """ + + saved_zip64_limit = zipfile.ZIP64_LIMIT + zipfile.ZIP64_LIMIT = (1 << 32) - 1 + + if not isinstance(zinfo_or_arcname, zipfile.ZipInfo): + zinfo = zipfile.ZipInfo(filename=zinfo_or_arcname) zinfo.compress_type = zip_file.compression else: - zinfo.compress_type = compression + zinfo = zinfo_or_arcname + + # If compress_type is given, it overrides the value in zinfo. + if compress_type is not None: + zinfo.compress_type = compress_type + + # Use a fixed timestamp so the output is repeatable. zinfo.external_attr = perms << 16 + zinfo.date_time = (2009, 1, 1, 0, 0, 0) + zip_file.writestr(zinfo, data) + zipfile.ZIP64_LIMIT = saved_zip64_limit + + +def ZipClose(zip_file): + # http://b/18015246 + # zipfile also refers to ZIP64_LIMIT during close() when it writes out the + # central directory. + saved_zip64_limit = zipfile.ZIP64_LIMIT + zipfile.ZIP64_LIMIT = (1 << 32) - 1 + + zip_file.close() + + zipfile.ZIP64_LIMIT = saved_zip64_limit class DeviceSpecificParams(object): @@ -976,7 +1011,7 @@ class File(object): return t def AddToZip(self, z, compression=None): - ZipWriteStr(z, self.name, self.data, compression=compression) + ZipWriteStr(z, self.name, self.data, compress_type=compression) DIFF_PROGRAM_BY_EXT = { ".gz" : "imgdiff", diff --git a/tools/releasetools/img_from_target_files.py b/tools/releasetools/img_from_target_files.py index 8c5acd8..c486992 100755 --- a/tools/releasetools/img_from_target_files.py +++ b/tools/releasetools/img_from_target_files.py @@ -43,8 +43,9 @@ OPTIONS = common.OPTIONS def CopyInfo(output_zip): """Copy the android-info.txt file from the input to the output.""" - output_zip.write(os.path.join(OPTIONS.input_tmp, "OTA", "android-info.txt"), - "android-info.txt") + common.ZipWrite( + output_zip, os.path.join(OPTIONS.input_tmp, "OTA", "android-info.txt"), + "android-info.txt") def main(argv): @@ -133,13 +134,7 @@ def main(argv): finally: print "cleaning up..." - # http://b/18015246 - # See common.py for context. zipfile also refers to ZIP64_LIMIT during - # close() when it writes out the central directory. - saved_zip64_limit = zipfile.ZIP64_LIMIT - zipfile.ZIP64_LIMIT = (1 << 32) - 1 - output_zip.close() - zipfile.ZIP64_LIMIT = saved_zip64_limit + common.ZipClose(output_zip) shutil.rmtree(OPTIONS.input_tmp) print "done." diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py index eab3daa..900eaec 100755 --- a/tools/releasetools/ota_from_target_files.py +++ b/tools/releasetools/ota_from_target_files.py @@ -92,7 +92,6 @@ if sys.hexversion < 0x02070000: print >> sys.stderr, "Python 2.7 or newer is required." sys.exit(1) -import copy import multiprocessing import os import tempfile @@ -371,6 +370,7 @@ def CopyPartitionFiles(itemset, input_zip, output_zip=None, substitute=None): symlinks.append((input_zip.read(info.filename), "/" + partition + "/" + basefilename)) else: + import copy info2 = copy.copy(info) fn = info2.filename = partition + "/" + basefilename if substitute and fn in substitute and substitute[fn] is None: @@ -380,7 +380,7 @@ def CopyPartitionFiles(itemset, input_zip, output_zip=None, substitute=None): data = substitute[fn] else: data = input_zip.read(info.filename) - output_zip.writestr(info2, data) + common.ZipWriteStr(output_zip, info2, data) if fn.endswith("/"): itemset.Get(fn[:-1], is_dir=True) else: @@ -1581,6 +1581,7 @@ def main(argv): OPTIONS.package_key = OPTIONS.info_dict.get( "default_system_dev_certificate", "build/target/product/security/testkey") + common.ZipClose(output_zip) break else: @@ -1601,15 +1602,14 @@ def main(argv): common.DumpInfoDict(OPTIONS.source_info_dict) try: WriteIncrementalOTAPackage(input_zip, source_zip, output_zip) + common.ZipClose(output_zip) break except ValueError: if not OPTIONS.fallback_to_full: raise print "--- failed to build incremental; falling back to full ---" OPTIONS.incremental_source = None - output_zip.close() - - output_zip.close() + common.ZipClose(output_zip) if not OPTIONS.no_signing: SignOutput(temp_zip_file.name, args[1]) diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py index d47cc4f..ec49112 100755 --- a/tools/releasetools/sign_target_files_apks.py +++ b/tools/releasetools/sign_target_files_apks.py @@ -196,23 +196,23 @@ def ProcessTargetFiles(input_tf_zip, output_tf_zip, misc_info, if key not in common.SPECIAL_CERT_STRINGS: print " signing: %-*s (%s)" % (maxsize, name, key) signed_data = SignApk(data, key, key_passwords[key]) - output_tf_zip.writestr(out_info, signed_data) + common.ZipWriteStr(output_tf_zip, out_info, signed_data) else: # an APK we're not supposed to sign. print "NOT signing: %s" % (name,) - output_tf_zip.writestr(out_info, data) + common.ZipWriteStr(output_tf_zip, out_info, data) elif info.filename in ("SYSTEM/build.prop", "VENDOR/build.prop", "RECOVERY/RAMDISK/default.prop"): print "rewriting %s:" % (info.filename,) new_data = RewriteProps(data, misc_info) - output_tf_zip.writestr(out_info, new_data) + common.ZipWriteStr(output_tf_zip, out_info, new_data) if info.filename == "RECOVERY/RAMDISK/default.prop": write_to_temp(info.filename, info.external_attr, new_data) elif info.filename.endswith("mac_permissions.xml"): print "rewriting %s with new keys." % (info.filename,) new_data = ReplaceCerts(data) - output_tf_zip.writestr(out_info, new_data) + common.ZipWriteStr(output_tf_zip, out_info, new_data) elif info.filename in ("SYSTEM/recovery-from-boot.p", "SYSTEM/bin/install-recovery.sh"): rebuild_recovery = True @@ -229,7 +229,7 @@ def ProcessTargetFiles(input_tf_zip, output_tf_zip, misc_info, pass else: # a non-APK file; copy it verbatim - output_tf_zip.writestr(out_info, data) + common.ZipWriteStr(output_tf_zip, out_info, data) if OPTIONS.replace_ota_keys: new_recovery_keys = ReplaceOtaKeys(input_tf_zip, output_tf_zip, misc_info) @@ -243,7 +243,7 @@ def ProcessTargetFiles(input_tf_zip, output_tf_zip, misc_info, "boot.img", "boot.img", tmpdir, "BOOT", info_dict=misc_info) def output_sink(fn, data): - output_tf_zip.writestr("SYSTEM/"+fn, data) + common.ZipWriteStr(output_tf_zip, "SYSTEM/" + fn, data) common.MakeRecoveryPatch(tmpdir, output_sink, recovery_img, boot_img, info_dict=misc_info) @@ -488,8 +488,8 @@ def main(argv): ProcessTargetFiles(input_zip, output_zip, misc_info, apk_key_map, key_passwords) - input_zip.close() - output_zip.close() + common.ZipClose(input_zip) + common.ZipClose(output_zip) add_img_to_target_files.AddImagesToTargetFiles(args[1]) diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py index 5fdc132..f28934d 100644 --- a/tools/releasetools/test_common.py +++ b/tools/releasetools/test_common.py @@ -29,15 +29,54 @@ def random_string_with_holes(size, block_size, step_size): data[begin:end] = os.urandom(block_size) return "".join(data) +def get_2gb_string(): + kilobytes = 1024 + megabytes = 1024 * kilobytes + gigabytes = 1024 * megabytes + + size = int(2 * gigabytes + 1) + block_size = 4 * kilobytes + step_size = 4 * megabytes + two_gb_string = random_string_with_holes( + size, block_size, step_size) + return two_gb_string + class CommonZipTest(unittest.TestCase): + def _verify(self, zip_file, zip_file_name, arcname, contents, + test_file_name=None, expected_stat=None, expected_mode=0o644, + expected_compress_type=zipfile.ZIP_STORED): + # Verify the stat if present. + if test_file_name is not None: + new_stat = os.stat(test_file_name) + self.assertEqual(int(expected_stat.st_mode), int(new_stat.st_mode)) + self.assertEqual(int(expected_stat.st_mtime), int(new_stat.st_mtime)) + + # Reopen the zip file to verify. + zip_file = zipfile.ZipFile(zip_file_name, "r") + + # Verify the timestamp. + info = zip_file.getinfo(arcname) + self.assertEqual(info.date_time, (2009, 1, 1, 0, 0, 0)) + + # Verify the file mode. + mode = (info.external_attr >> 16) & 0o777 + self.assertEqual(mode, expected_mode) + + # Verify the compress type. + self.assertEqual(info.compress_type, expected_compress_type) + + # Verify the zip contents. + self.assertEqual(zip_file.read(arcname), contents) + self.assertIsNone(zip_file.testzip()) + def _test_ZipWrite(self, contents, extra_zipwrite_args=None): extra_zipwrite_args = dict(extra_zipwrite_args or {}) test_file = tempfile.NamedTemporaryFile(delete=False) - zip_file = tempfile.NamedTemporaryFile(delete=False) - test_file_name = test_file.name + + zip_file = tempfile.NamedTemporaryFile(delete=False) zip_file_name = zip_file.name # File names within an archive strip the leading slash. @@ -52,31 +91,100 @@ class CommonZipTest(unittest.TestCase): test_file.write(contents) test_file.close() - old_stat = os.stat(test_file_name) + expected_stat = os.stat(test_file_name) expected_mode = extra_zipwrite_args.get("perms", 0o644) - + expected_compress_type = extra_zipwrite_args.get("compress_type", + zipfile.ZIP_STORED) time.sleep(5) # Make sure the atime/mtime will change measurably. common.ZipWrite(zip_file, test_file_name, **extra_zipwrite_args) + common.ZipClose(zip_file) - new_stat = os.stat(test_file_name) - self.assertEqual(int(old_stat.st_mode), int(new_stat.st_mode)) - self.assertEqual(int(old_stat.st_mtime), int(new_stat.st_mtime)) - self.assertIsNone(zip_file.testzip()) - - zip_file.close() - zip_file = zipfile.ZipFile(zip_file_name, "r") - info = zip_file.getinfo(arcname) - - self.assertEqual(info.date_time, (2009, 1, 1, 0, 0, 0)) - mode = (info.external_attr >> 16) & 0o777 - self.assertEqual(mode, expected_mode) - self.assertEqual(zip_file.read(arcname), contents) - self.assertIsNone(zip_file.testzip()) + self._verify(zip_file, zip_file_name, arcname, contents, test_file_name, + expected_stat, expected_mode, expected_compress_type) finally: os.remove(test_file_name) os.remove(zip_file_name) + def _test_ZipWriteStr(self, zinfo_or_arcname, contents, extra_args=None): + extra_args = dict(extra_args or {}) + + zip_file = tempfile.NamedTemporaryFile(delete=False) + zip_file_name = zip_file.name + zip_file.close() + + zip_file = zipfile.ZipFile(zip_file_name, "w") + + try: + expected_compress_type = extra_args.get("compress_type", + zipfile.ZIP_STORED) + time.sleep(5) # Make sure the atime/mtime will change measurably. + + if not isinstance(zinfo_or_arcname, zipfile.ZipInfo): + zinfo = zipfile.ZipInfo(filename=zinfo_or_arcname) + else: + zinfo = zinfo_or_arcname + arcname = zinfo.filename + + common.ZipWriteStr(zip_file, zinfo, contents, **extra_args) + common.ZipClose(zip_file) + + self._verify(zip_file, zip_file_name, arcname, contents, + expected_compress_type=expected_compress_type) + finally: + os.remove(zip_file_name) + + def _test_ZipWriteStr_large_file(self, large, small, extra_args=None): + extra_args = dict(extra_args or {}) + + zip_file = tempfile.NamedTemporaryFile(delete=False) + zip_file_name = zip_file.name + + test_file = tempfile.NamedTemporaryFile(delete=False) + test_file_name = test_file.name + + arcname_large = test_file_name + arcname_small = "bar" + + # File names within an archive strip the leading slash. + if arcname_large[0] == "/": + arcname_large = arcname_large[1:] + + zip_file.close() + zip_file = zipfile.ZipFile(zip_file_name, "w") + + try: + test_file.write(large) + test_file.close() + + expected_stat = os.stat(test_file_name) + expected_mode = 0o644 + expected_compress_type = extra_args.get("compress_type", + zipfile.ZIP_STORED) + time.sleep(5) # Make sure the atime/mtime will change measurably. + + common.ZipWrite(zip_file, test_file_name, **extra_args) + common.ZipWriteStr(zip_file, arcname_small, small, **extra_args) + common.ZipClose(zip_file) + + # Verify the contents written by ZipWrite(). + self._verify(zip_file, zip_file_name, arcname_large, large, + test_file_name, expected_stat, expected_mode, + expected_compress_type) + + # Verify the contents written by ZipWriteStr(). + self._verify(zip_file, zip_file_name, arcname_small, small, + expected_compress_type=expected_compress_type) + finally: + os.remove(zip_file_name) + os.remove(test_file_name) + + def _test_reset_ZIP64_LIMIT(self, func, *args): + default_limit = (1 << 31) - 1 + self.assertEqual(default_limit, zipfile.ZIP64_LIMIT) + func(*args) + self.assertEqual(default_limit, zipfile.ZIP64_LIMIT) + def test_ZipWrite(self): file_contents = os.urandom(1024) self._test_ZipWrite(file_contents) @@ -88,23 +196,64 @@ class CommonZipTest(unittest.TestCase): "perms": 0o777, "compress_type": zipfile.ZIP_DEFLATED, }) + self._test_ZipWrite(file_contents, { + "arcname": "foobar", + "perms": 0o700, + "compress_type": zipfile.ZIP_STORED, + }) def test_ZipWrite_large_file(self): - kilobytes = 1024 - megabytes = 1024 * kilobytes - gigabytes = 1024 * megabytes - - size = int(2 * gigabytes + 1) - block_size = 4 * kilobytes - step_size = 4 * megabytes - file_contents = random_string_with_holes( - size, block_size, step_size) + file_contents = get_2gb_string() self._test_ZipWrite(file_contents, { "compress_type": zipfile.ZIP_DEFLATED, }) def test_ZipWrite_resets_ZIP64_LIMIT(self): - default_limit = (1 << 31) - 1 - self.assertEqual(default_limit, zipfile.ZIP64_LIMIT) - self._test_ZipWrite('') - self.assertEqual(default_limit, zipfile.ZIP64_LIMIT) + self._test_reset_ZIP64_LIMIT(self._test_ZipWrite, "") + + def test_ZipWriteStr(self): + random_string = os.urandom(1024) + # Passing arcname + self._test_ZipWriteStr("foo", random_string) + + # Passing zinfo + zinfo = zipfile.ZipInfo(filename="foo") + self._test_ZipWriteStr(zinfo, random_string) + + # Timestamp in the zinfo should be overwritten. + zinfo.date_time = (2015, 3, 1, 15, 30, 0) + self._test_ZipWriteStr(zinfo, random_string) + + def test_ZipWriteStr_with_opts(self): + random_string = os.urandom(1024) + # Passing arcname + self._test_ZipWriteStr("foo", random_string, { + "compress_type": zipfile.ZIP_DEFLATED, + }) + self._test_ZipWriteStr("foo", random_string, { + "compress_type": zipfile.ZIP_STORED, + }) + + # Passing zinfo + zinfo = zipfile.ZipInfo(filename="foo") + self._test_ZipWriteStr(zinfo, random_string, { + "compress_type": zipfile.ZIP_DEFLATED, + }) + self._test_ZipWriteStr(zinfo, random_string, { + "compress_type": zipfile.ZIP_STORED, + }) + + def test_ZipWriteStr_large_file(self): + # zipfile.writestr() doesn't work when the str size is over 2GiB even with + # the workaround. We will only test the case of writing a string into a + # large archive. + long_string = get_2gb_string() + short_string = os.urandom(1024) + self._test_ZipWriteStr_large_file(long_string, short_string, { + "compress_type": zipfile.ZIP_DEFLATED, + }) + + def test_ZipWriteStr_resets_ZIP64_LIMIT(self): + self._test_reset_ZIP64_LIMIT(self._test_ZipWriteStr, "foo", "") + zinfo = zipfile.ZipInfo(filename="foo") + self._test_reset_ZIP64_LIMIT(self._test_ZipWriteStr, zinfo, "") |