Merge "Generate FlatConfig objects from GenericConfig objects."
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
new file mode 100644
index 0000000..ce75150
--- /dev/null
+++ b/PREUPLOAD.cfg
@@ -0,0 +1,2 @@
+[Hook Scripts]
+do_not_use_DO_NOT_MERGE = ${REPO_ROOT}/build/soong/scripts/check_do_not_merge.sh ${PREUPLOAD_COMMIT}
diff --git a/core/Makefile b/core/Makefile
index a7553f0..6019452 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -4136,6 +4136,7 @@
mkuserimg_mke2fs \
ota_from_target_files \
repack_bootimg \
+ secilc \
sefcontext_compile \
sgdisk \
shflags \
diff --git a/core/app_prebuilt_internal.mk b/core/app_prebuilt_internal.mk
index cb1b453..ad96b5b 100644
--- a/core/app_prebuilt_internal.mk
+++ b/core/app_prebuilt_internal.mk
@@ -104,17 +104,19 @@
my_enforced_uses_libraries :=
ifdef LOCAL_ENFORCE_USES_LIBRARIES
- my_enforced_uses_libraries := $(intermediates.COMMON)/enforce_uses_libraries.timestamp
+ my_enforced_uses_libraries := $(intermediates.COMMON)/enforce_uses_libraries.status
$(my_enforced_uses_libraries): PRIVATE_USES_LIBRARIES := $(LOCAL_USES_LIBRARIES)
$(my_enforced_uses_libraries): PRIVATE_OPTIONAL_USES_LIBRARIES := $(LOCAL_OPTIONAL_USES_LIBRARIES)
+ $(my_enforced_uses_libraries): PRIVATE_RELAX_CHECK := $(RELAX_USES_LIBRARY_CHECK)
$(my_enforced_uses_libraries): $(BUILD_SYSTEM)/verify_uses_libraries.sh $(AAPT)
$(my_enforced_uses_libraries): $(my_prebuilt_src_file)
@echo Verifying uses-libraries: $<
+ rm -f $@
aapt_binary=$(AAPT) \
uses_library_names="$(strip $(PRIVATE_USES_LIBRARIES))" \
optional_uses_library_names="$(strip $(PRIVATE_OPTIONAL_USES_LIBRARIES))" \
- $(BUILD_SYSTEM)/verify_uses_libraries.sh $<
- touch $@
+ relax_check="$(strip $(PRIVATE_RELAX_CHECK))" \
+ $(BUILD_SYSTEM)/verify_uses_libraries.sh $< $@
$(built_module) : $(my_enforced_uses_libraries)
endif
diff --git a/core/config.mk b/core/config.mk
index dce347a..3bd3622 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -479,6 +479,17 @@
USE_D8 := true
.KATI_READONLY := USE_D8
+# Whether to fail immediately if verify_uses_libraries check fails, or to keep
+# going and restrict dexpreopt to not compile any code for the failed module.
+#
+# The intended use case for this flag is to have a smoother migration path for
+# the Java modules that need to add <uses-library> information in their build
+# files. The flag allows to quickly silence build errors. This flag should be
+# used with caution and only as a temporary measure, as it masks real errors
+# and affects performance.
+RELAX_USES_LIBRARY_CHECK ?= false
+.KATI_READONLY := RELAX_USES_LIBRARY_CHECK
+
#
# Tools that are prebuilts for TARGET_BUILD_USE_PREBUILT_SDKS
#
diff --git a/core/dex_preopt_config.mk b/core/dex_preopt_config.mk
index 06e2fb7..dda7de0 100644
--- a/core/dex_preopt_config.mk
+++ b/core/dex_preopt_config.mk
@@ -105,6 +105,7 @@
$(call add_json_bool, IsEng, $(filter eng,$(TARGET_BUILD_VARIANT)))
$(call add_json_bool, SanitizeLite, $(SANITIZE_LITE))
$(call add_json_bool, DefaultAppImages, $(WITH_DEX_PREOPT_APP_IMAGE))
+ $(call add_json_bool, RelaxUsesLibraryCheck, $(filter true,$(RELAX_USES_LIBRARY_CHECK)))
$(call add_json_str, Dex2oatXmx, $(DEX2OAT_XMX))
$(call add_json_str, Dex2oatXms, $(DEX2OAT_XMS))
$(call add_json_str, EmptyDirectory, $(OUT_DIR)/empty)
diff --git a/core/dex_preopt_odex_install.mk b/core/dex_preopt_odex_install.mk
index f9a9ba7..cbd3069 100644
--- a/core/dex_preopt_odex_install.mk
+++ b/core/dex_preopt_odex_install.mk
@@ -278,6 +278,7 @@
$(call add_json_list, PreoptFlags, $(LOCAL_DEX_PREOPT_FLAGS))
$(call add_json_str, ProfileClassListing, $(if $(my_process_profile),$(LOCAL_DEX_PREOPT_PROFILE)))
$(call add_json_bool, ProfileIsTextListing, $(my_profile_is_text_listing))
+ $(call add_json_str, EnforceUsesLibrariesStatusFile, $(intermediates.COMMON)/enforce_uses_libraries.status)
$(call add_json_bool, EnforceUsesLibraries, $(LOCAL_ENFORCE_USES_LIBRARIES))
$(call add_json_str, ProvidesUsesLibrary, $(firstword $(LOCAL_PROVIDES_USES_LIBRARY) $(LOCAL_MODULE)))
$(call add_json_map, ClassLoaderContexts)
@@ -345,6 +346,9 @@
$(call intermediates-dir-for,JAVA_LIBRARIES,$(lib),,COMMON)/javalib.jar)
my_dexpreopt_deps += $(my_dexpreopt_images_deps)
my_dexpreopt_deps += $(DEXPREOPT_BOOTCLASSPATH_DEX_FILES)
+ ifeq ($(LOCAL_ENFORCE_USES_LIBRARIES),true)
+ my_dexpreopt_deps += $(intermediates.COMMON)/enforce_uses_libraries.status
+ endif
$(my_dexpreopt_zip): PRIVATE_MODULE := $(LOCAL_MODULE)
$(my_dexpreopt_zip): $(my_dexpreopt_deps)
diff --git a/core/verify_uses_libraries.sh b/core/verify_uses_libraries.sh
index dde0447..1bd0a2c 100755
--- a/core/verify_uses_libraries.sh
+++ b/core/verify_uses_libraries.sh
@@ -21,6 +21,7 @@
set -e
local_apk=$1
+status_file=$2
badging=$(${aapt_binary} dump badging "${local_apk}")
export sdk_version=$(echo "${badging}" | grep "sdkVersion" | sed -n "s/sdkVersion:'\(.*\)'/\1/p")
# Export target_sdk_version to the caller.
@@ -28,20 +29,28 @@
uses_libraries=$(echo "${badging}" | grep "uses-library" | sed -n "s/uses-library:'\(.*\)'/\1/p")
optional_uses_libraries=$(echo "${badging}" | grep "uses-library-not-required" | sed -n "s/uses-library-not-required:'\(.*\)'/\1/p")
+errmsg=
+
# Verify that the uses libraries match exactly.
# Currently we validate the ordering of the libraries since it matters for resolution.
single_line_libs=$(echo "${uses_libraries}" | tr '\n' ' ' | awk '{$1=$1}1')
if [[ "${single_line_libs}" != "${uses_library_names}" ]]; then
- echo "LOCAL_USES_LIBRARIES (${uses_library_names})" \
- "do not match (${single_line_libs}) in manifest for ${local_apk}"
- exit 1
+ errmsg="LOCAL_USES_LIBRARIES (${uses_library_names}) do not match (${single_line_libs}) in manifest for ${local_apk}"
fi
# Verify that the optional uses libraries match exactly.
single_line_optional_libs=$(echo "${optional_uses_libraries}" | tr '\n' ' ' | awk '{$1=$1}1')
if [[ "${single_line_optional_libs}" != "${optional_uses_library_names}" ]]; then
- echo "LOCAL_OPTIONAL_USES_LIBRARIES (${optional_uses_library_names}) " \
- "do not match (${single_line_optional_libs}) in manifest for ${local_apk}"
- exit 1
+ errmsg="LOCAL_OPTIONAL_USES_LIBRARIES (${optional_uses_library_names}) do not match (${single_line_optional_libs}) in manifest for ${local_apk}"
fi
+if [[ ! -z "${errmsg}" ]]; then
+ echo "${errmsg}" > "${status_file}"
+ if [[ "${relax_check}" != true ]]; then
+ # fail immediately
+ echo "${errmsg}"
+ exit 1
+ fi
+else
+ touch "${status_file}"
+fi
diff --git a/envsetup.sh b/envsetup.sh
index a5f6b6d..15d6fb4 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -27,7 +27,7 @@
- mangrep: Greps on all local AndroidManifest.xml files.
- mgrep: Greps on all local Makefiles and *.bp files.
- owngrep: Greps on all local OWNERS files.
-- rgrep: Greps on all local Rust files.
+- rsgrep: Greps on all local Rust files.
- sepgrep: Greps on all local sepolicy files.
- sgrep: Greps on all local source files.
- godir: Go to the directory containing a file.
@@ -1038,7 +1038,7 @@
-exec grep --color -n "$@" {} +
}
-function rgrep()
+function rsgrep()
{
find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.rs" \
-exec grep --color -n "$@" {} +
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
index 81528ae..6d88249 100644
--- a/tools/releasetools/Android.bp
+++ b/tools/releasetools/Android.bp
@@ -451,6 +451,7 @@
required: [
"checkvintf",
"host_init_verifier",
+ "secilc",
],
target: {
darwin: {
diff --git a/tools/releasetools/merge_target_files.py b/tools/releasetools/merge_target_files.py
index 3d9c717..16cab4f 100755
--- a/tools/releasetools/merge_target_files.py
+++ b/tools/releasetools/merge_target_files.py
@@ -93,6 +93,7 @@
import subprocess
import sys
import zipfile
+from xml.etree import ElementTree
import add_img_to_target_files
import build_super_image
@@ -658,6 +659,80 @@
os.path.join(output_target_files_dir, 'META', 'vendor_file_contexts.bin'))
+def compile_split_sepolicy(product_out, partition_map, output_policy):
+ """Uses secilc to compile a split sepolicy file.
+
+ Depends on various */etc/selinux/* and */etc/vintf/* files within partitions.
+
+ Args:
+ product_out: PRODUCT_OUT directory, containing partition directories.
+ partition_map: A map of partition name -> relative path within product_out.
+ output_policy: The name of the output policy created by secilc.
+
+ Returns:
+ A command list that can be executed to create the compiled sepolicy.
+ """
+
+ def get_file(partition, path):
+ if partition not in partition_map:
+ logger.warning('Cannot load SEPolicy files for missing partition %s',
+ partition)
+ return None
+ return os.path.join(product_out, partition_map[partition], path)
+
+ # Load the kernel sepolicy version from the FCM. This is normally provided
+ # directly to selinux.cpp as a build flag, but is also available in this file.
+ fcm_file = get_file('system', 'etc/vintf/compatibility_matrix.device.xml')
+ if not fcm_file or not os.path.exists(fcm_file):
+ raise ExternalError('Missing required file for loading sepolicy: %s', fcm)
+ kernel_sepolicy_version = ElementTree.parse(fcm_file).getroot().find(
+ 'sepolicy/kernel-sepolicy-version').text
+
+ # Load the vendor's plat sepolicy version. This is the version used for
+ # locating sepolicy mapping files.
+ vendor_plat_version_file = get_file('vendor',
+ 'etc/selinux/plat_sepolicy_vers.txt')
+ if not vendor_plat_version_file or not os.path.exists(
+ vendor_plat_version_file):
+ raise ExternalError('Missing required sepolicy file %s',
+ vendor_plat_version_file)
+ with open(vendor_plat_version_file) as f:
+ vendor_plat_version = f.read().strip()
+
+ # Use the same flags and arguments as selinux.cpp OpenSplitPolicy().
+ cmd = ['secilc', '-m', '-M', 'true', '-G', '-N']
+ cmd.extend(['-c', kernel_sepolicy_version])
+ cmd.extend(['-o', output_policy])
+ cmd.extend(['-f', '/dev/null'])
+
+ required_policy_files = (
+ ('system', 'etc/selinux/plat_sepolicy.cil'),
+ ('system', 'etc/selinux/mapping/%s.cil' % vendor_plat_version),
+ ('vendor', 'etc/selinux/vendor_sepolicy.cil'),
+ ('vendor', 'etc/selinux/plat_pub_versioned.cil'),
+ )
+ for policy in (map(lambda partition_and_path: get_file(*partition_and_path),
+ required_policy_files)):
+ if not policy or not os.path.exists(policy):
+ raise ExternalError('Missing required sepolicy file %s', policy)
+ cmd.append(policy)
+
+ optional_policy_files = (
+ ('system', 'etc/selinux/mapping/%s.compat.cil' % vendor_plat_version),
+ ('system_ext', 'etc/selinux/system_ext_sepolicy.cil'),
+ ('system_ext', 'etc/selinux/mapping/%s.cil' % vendor_plat_version),
+ ('product', 'etc/selinux/product_sepolicy.cil'),
+ ('product', 'etc/selinux/mapping/%s.cil' % vendor_plat_version),
+ ('odm', 'etc/selinux/odm_sepolicy.cil'),
+ )
+ for policy in (map(lambda partition_and_path: get_file(*partition_and_path),
+ optional_policy_files)):
+ if policy and os.path.exists(policy):
+ cmd.append(policy)
+
+ return cmd
+
+
def process_special_cases(framework_target_files_temp_dir,
vendor_target_files_temp_dir,
output_target_files_temp_dir,
@@ -977,17 +1052,28 @@
raise ValueError('sharedUserId APK error. See %s' %
shareduid_violation_modules)
- # Run host_init_verifier on the combined init rc files.
+ # host_init_verifier and secilc check only the following partitions:
filtered_partitions = {
partition: path
for partition, path in partition_map.items()
- # host_init_verifier checks only the following partitions:
if partition in ['system', 'system_ext', 'product', 'vendor', 'odm']
}
+
+ # Run host_init_verifier on the combined init rc files.
common.RunHostInitVerifier(
product_out=output_target_files_temp_dir,
partition_map=filtered_partitions)
+ # Check that the split sepolicy from the multiple builds can compile.
+ split_sepolicy_cmd = compile_split_sepolicy(
+ product_out=output_target_files_temp_dir,
+ partition_map=filtered_partitions,
+ output_policy=os.path.join(output_target_files_temp_dir,
+ 'META/combined.policy'))
+ logger.info('Compiling split sepolicy: %s', ' '.join(split_sepolicy_cmd))
+ common.RunAndCheckOutput(split_sepolicy_cmd)
+ # TODO(b/178864050): Run tests on the combined.policy file.
+
generate_images(output_target_files_temp_dir, rebuild_recovery)
generate_super_empty_image(output_target_files_temp_dir, output_super_empty)
diff --git a/tools/releasetools/test_merge_target_files.py b/tools/releasetools/test_merge_target_files.py
index 7ea7f96..072bb01 100644
--- a/tools/releasetools/test_merge_target_files.py
+++ b/tools/releasetools/test_merge_target_files.py
@@ -18,12 +18,11 @@
import common
import test_utils
-from merge_target_files import (validate_config_lists,
- DEFAULT_FRAMEWORK_ITEM_LIST,
- DEFAULT_VENDOR_ITEM_LIST,
- DEFAULT_FRAMEWORK_MISC_INFO_KEYS, copy_items,
- item_list_to_partition_set,
- process_apex_keys_apk_certs_common)
+from merge_target_files import (
+ validate_config_lists, DEFAULT_FRAMEWORK_ITEM_LIST,
+ DEFAULT_VENDOR_ITEM_LIST, DEFAULT_FRAMEWORK_MISC_INFO_KEYS, copy_items,
+ item_list_to_partition_set, process_apex_keys_apk_certs_common,
+ compile_split_sepolicy)
class MergeTargetFilesTest(test_utils.ReleaseToolsTestCase):
@@ -235,3 +234,43 @@
]
partition_set = item_list_to_partition_set(item_list)
self.assertEqual(set(['product', 'system', 'system_ext']), partition_set)
+
+ def test_compile_split_sepolicy(self):
+ product_out_dir = common.MakeTempDir()
+
+ def write_temp_file(path, data=''):
+ full_path = os.path.join(product_out_dir, path)
+ if not os.path.exists(os.path.dirname(full_path)):
+ os.makedirs(os.path.dirname(full_path))
+ with open(full_path, 'w') as f:
+ f.write(data)
+
+ write_temp_file(
+ 'system/etc/vintf/compatibility_matrix.device.xml', """
+ <compatibility-matrix>
+ <sepolicy>
+ <kernel-sepolicy-version>30</kernel-sepolicy-version>
+ </sepolicy>
+ </compatibility-matrix>""")
+ write_temp_file('vendor/etc/selinux/plat_sepolicy_vers.txt', '30.0')
+
+ write_temp_file('system/etc/selinux/plat_sepolicy.cil')
+ write_temp_file('system/etc/selinux/mapping/30.0.cil')
+ write_temp_file('product/etc/selinux/mapping/30.0.cil')
+ write_temp_file('vendor/etc/selinux/vendor_sepolicy.cil')
+ write_temp_file('vendor/etc/selinux/plat_pub_versioned.cil')
+
+ cmd = compile_split_sepolicy(product_out_dir, {
+ 'system': 'system',
+ 'product': 'product',
+ 'vendor': 'vendor',
+ }, os.path.join(product_out_dir, 'policy'))
+ self.assertEqual(' '.join(cmd),
+ ('secilc -m -M true -G -N -c 30 '
+ '-o {OTP}/policy -f /dev/null '
+ '{OTP}/system/etc/selinux/plat_sepolicy.cil '
+ '{OTP}/system/etc/selinux/mapping/30.0.cil '
+ '{OTP}/vendor/etc/selinux/vendor_sepolicy.cil '
+ '{OTP}/vendor/etc/selinux/plat_pub_versioned.cil '
+ '{OTP}/product/etc/selinux/mapping/30.0.cil').format(
+ OTP=product_out_dir))