Merge "Creates a combined split-sepolicy file in merge_target_files.py." am: 2793fd2e6d
Original change: https://android-review.googlesource.com/c/platform/build/+/1578904 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: I33de196cbbf5285cdfaa7a637db1ecb9381f6bf6
This commit is contained in:
commit
7f4ae8df3c
|
@ -4136,6 +4136,7 @@ INTERNAL_OTATOOLS_MODULES := \
|
||||||
mkuserimg_mke2fs \
|
mkuserimg_mke2fs \
|
||||||
ota_from_target_files \
|
ota_from_target_files \
|
||||||
repack_bootimg \
|
repack_bootimg \
|
||||||
|
secilc \
|
||||||
sefcontext_compile \
|
sefcontext_compile \
|
||||||
sgdisk \
|
sgdisk \
|
||||||
shflags \
|
shflags \
|
||||||
|
|
|
@ -451,6 +451,7 @@ python_binary_host {
|
||||||
required: [
|
required: [
|
||||||
"checkvintf",
|
"checkvintf",
|
||||||
"host_init_verifier",
|
"host_init_verifier",
|
||||||
|
"secilc",
|
||||||
],
|
],
|
||||||
target: {
|
target: {
|
||||||
darwin: {
|
darwin: {
|
||||||
|
|
|
@ -93,6 +93,7 @@ import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import zipfile
|
import zipfile
|
||||||
|
from xml.etree import ElementTree
|
||||||
|
|
||||||
import add_img_to_target_files
|
import add_img_to_target_files
|
||||||
import build_super_image
|
import build_super_image
|
||||||
|
@ -658,6 +659,80 @@ def copy_file_contexts(framework_target_files_dir, vendor_target_files_dir,
|
||||||
os.path.join(output_target_files_dir, 'META', 'vendor_file_contexts.bin'))
|
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,
|
def process_special_cases(framework_target_files_temp_dir,
|
||||||
vendor_target_files_temp_dir,
|
vendor_target_files_temp_dir,
|
||||||
output_target_files_temp_dir,
|
output_target_files_temp_dir,
|
||||||
|
@ -977,17 +1052,28 @@ def merge_target_files(temp_dir, framework_target_files, framework_item_list,
|
||||||
raise ValueError('sharedUserId APK error. See %s' %
|
raise ValueError('sharedUserId APK error. See %s' %
|
||||||
shareduid_violation_modules)
|
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 = {
|
filtered_partitions = {
|
||||||
partition: path
|
partition: path
|
||||||
for partition, path in partition_map.items()
|
for partition, path in partition_map.items()
|
||||||
# host_init_verifier checks only the following partitions:
|
|
||||||
if partition in ['system', 'system_ext', 'product', 'vendor', 'odm']
|
if partition in ['system', 'system_ext', 'product', 'vendor', 'odm']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Run host_init_verifier on the combined init rc files.
|
||||||
common.RunHostInitVerifier(
|
common.RunHostInitVerifier(
|
||||||
product_out=output_target_files_temp_dir,
|
product_out=output_target_files_temp_dir,
|
||||||
partition_map=filtered_partitions)
|
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_images(output_target_files_temp_dir, rebuild_recovery)
|
||||||
|
|
||||||
generate_super_empty_image(output_target_files_temp_dir, output_super_empty)
|
generate_super_empty_image(output_target_files_temp_dir, output_super_empty)
|
||||||
|
|
|
@ -18,12 +18,11 @@ import os.path
|
||||||
|
|
||||||
import common
|
import common
|
||||||
import test_utils
|
import test_utils
|
||||||
from merge_target_files import (validate_config_lists,
|
from merge_target_files import (
|
||||||
DEFAULT_FRAMEWORK_ITEM_LIST,
|
validate_config_lists, DEFAULT_FRAMEWORK_ITEM_LIST,
|
||||||
DEFAULT_VENDOR_ITEM_LIST,
|
DEFAULT_VENDOR_ITEM_LIST, DEFAULT_FRAMEWORK_MISC_INFO_KEYS, copy_items,
|
||||||
DEFAULT_FRAMEWORK_MISC_INFO_KEYS, copy_items,
|
item_list_to_partition_set, process_apex_keys_apk_certs_common,
|
||||||
item_list_to_partition_set,
|
compile_split_sepolicy)
|
||||||
process_apex_keys_apk_certs_common)
|
|
||||||
|
|
||||||
|
|
||||||
class MergeTargetFilesTest(test_utils.ReleaseToolsTestCase):
|
class MergeTargetFilesTest(test_utils.ReleaseToolsTestCase):
|
||||||
|
@ -235,3 +234,43 @@ class MergeTargetFilesTest(test_utils.ReleaseToolsTestCase):
|
||||||
]
|
]
|
||||||
partition_set = item_list_to_partition_set(item_list)
|
partition_set = item_list_to_partition_set(item_list)
|
||||||
self.assertEqual(set(['product', 'system', 'system_ext']), partition_set)
|
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))
|
||||||
|
|
Loading…
Reference in New Issue