Update compat generator for the new version format
* SEPolicy now follows VINTF version YYYYMM
* Adds an option to specify a pre-downloaded zip file
* Fixes libsepolwrap problem due to embedded launcher
Bug: 389524798
Test: manually run the script
Change-Id: Idcd07b0c3b3054890a33006b965c0a528c09e87a
diff --git a/tools/sepolicy_generate_compat.py b/tools/sepolicy_generate_compat.py
index a941d6f..1287670 100644
--- a/tools/sepolicy_generate_compat.py
+++ b/tools/sepolicy_generate_compat.py
@@ -20,6 +20,7 @@
import logging
import mini_parser
import os
+import pkgutil
import policy
import shutil
import subprocess
@@ -91,30 +92,34 @@
check_run(cmd)
-def extract_mapping_file_from_img(img_path, ver, destination='.'):
- """ Extracts system/etc/selinux/mapping/{ver}.cil from system.img file.
+def extract_mapping_file_from_img_zip(zip_path, ver, destination='.'):
+ """ Extracts system/etc/selinux/mapping/{ver}.cil from img.zip file.
Args:
- img_path: string, path to system.img file
+ zip_path: string, path to img.zip file
ver: string, version of designated mapping file
destination: string, destination to pull the mapping file to
Returns:
string, path to extracted mapping file
"""
+ with zipfile.ZipFile(zip_path) as zip_file:
+ logging.debug(f'Extracting system.img to {temp_dir}')
+ zip_file.extract('system.img', temp_dir)
+ system_img_path = os.path.join(temp_dir, 'system.img')
+ mapping_file_path = os.path.join(destination, f'{ver}.cil')
cmd = [
'debugfs', '-R',
- 'cat system/etc/selinux/mapping/10000.0.cil', img_path
+ f'dump system/etc/selinux/mapping/{ver}.cil {mapping_file_path}',
+ system_img_path
]
- path = os.path.join(destination, '%s.cil' % ver)
- with open(path, 'wb') as f:
- logging.debug('Extracting %s.cil to %s' % (ver, destination))
- f.write(check_output(cmd).stdout.replace(b'10000_0', ver.replace('.', '_').encode()))
- return path
+ logging.debug(f'Extracting {ver}.cil to {destination}')
+ check_run(cmd)
+ return mapping_file_path
-def download_mapping_file(branch, build, ver, destination='.'):
+def download_img_zip(branch, build, destination='.'):
""" Downloads system/etc/selinux/mapping/{ver}.cil from Android Build server.
Args:
@@ -124,7 +129,7 @@
destination: string, destination to pull build artifact to
Returns:
- string, path to extracted mapping file
+ string, path to img.zip file
"""
logging.info('Downloading %s mapping file from branch %s build %s...' %
(ver, branch, build))
@@ -132,13 +137,7 @@
fetch_artifact(branch, build, artifact_pattern, temp_dir)
# glob must succeed
- zip_path = glob.glob(os.path.join(temp_dir, artifact_pattern))[0]
- with zipfile.ZipFile(zip_path) as zip_file:
- logging.debug('Extracting system.img to %s' % temp_dir)
- zip_file.extract('system.img', temp_dir)
-
- system_img_path = os.path.join(temp_dir, 'system.img')
- return extract_mapping_file_from_img(system_img_path, ver, destination)
+ return glob.glob(os.path.join(temp_dir, artifact_pattern))[0]
def build_base_files(target_version):
@@ -167,7 +166,7 @@
dist_dir = os.path.join(build_top, 'out', 'dist')
base_policy_path = os.path.join(dist_dir, 'base_plat_sepolicy')
old_policy_path = os.path.join(dist_dir,
- '%s_plat_sepolicy' % target_version)
+ '%s_plat_policy' % target_version)
pub_policy_cil_path = os.path.join(dist_dir, 'base_plat_pub_policy.cil')
return base_policy_path, old_policy_path, pub_policy_cil_path
@@ -176,8 +175,8 @@
def change_api_level(versioned_type, api_from, api_to):
""" Verifies the API version of versioned_type, and changes it to new API level.
- For example, change_api_level("foo_32_0", "32.0", "31.0") will return
- "foo_31_0".
+ For example, change_api_level("foo_202404", "202404", "202504") will return
+ "foo_202504".
Args:
versioned_type: string, type with version suffix
@@ -187,12 +186,10 @@
Returns:
string, a new versioned type
"""
- old_suffix = api_from.replace('.', '_')
- new_suffix = api_to.replace('.', '_')
- if not versioned_type.endswith(old_suffix):
+ if not versioned_type.endswith(api_from):
raise ValueError('Version of type %s is different from %s' %
(versioned_type, api_from))
- return versioned_type.removesuffix(old_suffix) + new_suffix
+ return versioned_type.removesuffix(api_from) + api_to
def create_target_compat_modules(bp_path, target_ver):
@@ -323,17 +320,21 @@
parser = argparse.ArgumentParser()
parser.add_argument(
'--branch',
- required=True,
help='Branch to pull build from. e.g. "sc-v2-dev"')
- parser.add_argument('--build', required=True, help='Build ID, or "latest"')
+ parser.add_argument('--build',
+ default='latest',
+ help='Build ID, or "latest"')
parser.add_argument(
'--target-version',
required=True,
- help='Target version of designated mapping file. e.g. "32.0"')
+ help='Target version of designated mapping file. e.g. "202504"')
parser.add_argument(
'--latest-version',
required=True,
- help='Latest version for mapping of newer types. e.g. "31.0"')
+ help='Latest version for mapping of newer types. e.g. "202404"')
+ parser.add_argument(
+ '--img-zip',
+ help='Pre-downloaded img.zip. e.g. "aosp_arm64-img-xxxxxxxx.zip"')
parser.add_argument(
'-v',
'--verbose',
@@ -355,12 +356,13 @@
temp_dir = tempfile.mkdtemp()
try:
- libpath = os.path.join(
- os.path.dirname(os.path.realpath(__file__)), 'libsepolwrap' + SHARED_LIB_EXTENSION)
- if not os.path.exists(libpath):
- sys.exit(
- 'Error: libsepolwrap does not exist. Is this binary corrupted?\n'
- )
+ libname = "libsepolwrap" + SHARED_LIB_EXTENSION
+ libpath = os.path.join(temp_dir, libname)
+ with open(libpath, "wb") as f:
+ blob = pkgutil.get_data("sepolicy_generate_compat", libname)
+ if not blob:
+ sys.exit("Error: libsepolwrap does not exist. Is this binary corrupted?\n")
+ f.write(blob)
build_top = get_android_build_top()
sepolicy_path = os.path.join(build_top, 'system', 'sepolicy')
@@ -386,8 +388,16 @@
Path(target_ignore_file).touch()
# Step 1. Download system/etc/selinux/mapping/{ver}.cil, and remove types/typeattributes
- mapping_file = download_mapping_file(
- args.branch, args.build, args.target_version, destination=temp_dir)
+ if args.img_zip and args.branch:
+ sys.exit('Error: only one of --img-zip and --branch can be set')
+ elif args.img_zip:
+ img_zip = args.img_zip
+ elif args.branch:
+ img_zip = download_img_zip(args.branch, args.build, destination=temp_dir)
+ else:
+ sys.exit('Error: either one of --img-zip and --branch must be set')
+ mapping_file = extract_mapping_file_from_img_zip(img_zip, args.target_version,
+ destination=temp_dir)
mapping_file_cil = mini_parser.MiniCilParser(mapping_file)
mapping_file_cil.types = set()
mapping_file_cil.typeattributes = set()
@@ -507,6 +517,9 @@
logging.info('writing %s' % target_ignore_file)
f.write(ignore_cil_template %
(args.target_version, '\n '.join(sorted(target_ignored_types))))
+
+ # TODO(b/391513934): add treble tests
+ # TODO(b/391513934): add mapping files to phony modules like selinux_policy_system
finally:
logging.info('Deleting temporary dir: {}'.format(temp_dir))
shutil.rmtree(temp_dir)