From 530dbad92500807c06b2ed5b87abe9d6874ce9ad Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 30 Dec 2025 15:42:48 +0100 Subject: [PATCH] Read current options from a shadow file rather than the config file The list of current options needs to be up-to-date, so we can't just use historical data. Users may edit the default config file (`include/tf-psa-crypto/crypto_config.h` or `include/mbedtls/mbedtls_config.h`). One of the reasons we use the list of config options is to prevent users from defining internal macros in their config file (in code generated by `generated_config_checks.py`). An internal macro is one that isn't listed in the official config file. So we need to know what macros are listed in the official config file, regardless of edits to the current config file. Hence we read a "shadow file" which contains the official list of options, rather than the "live" config file. This file will need to be kept up-to-date during development, but is not user-editable. Signed-off-by: Gilles Peskine --- scripts/mbedtls_framework/config_macros.py | 26 ++++++++++++++++------ 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/scripts/mbedtls_framework/config_macros.py b/scripts/mbedtls_framework/config_macros.py index 80c68fed6..a048670f4 100644 --- a/scripts/mbedtls_framework/config_macros.py +++ b/scripts/mbedtls_framework/config_macros.py @@ -26,10 +26,19 @@ class ConfigMacros: """The set of internal option-like macros in this product.""" return self._internal + @staticmethod + def _load_file(filename: str) -> FrozenSet[str]: + """Load macro names from the given file.""" + with open(filename, encoding='ascii') as input_: + return frozenset(line.strip() + for line in input_) + class Current(ConfigMacros): """Information about config-like macros parsed from the source code.""" + _SHADOW_FILE = 'scripts/data_files/config-options-current.txt' + _PUBLIC_CONFIG_HEADERS = [ 'include/mbedtls/mbedtls_config.h', 'include/psa/crypto_config.h', @@ -63,6 +72,10 @@ class Current(ConfigMacros): for filename in self._list_files(patterns) for element in self._search_file(filename)) + def shadow_file_path(self) -> str: + """The path to the option list shadow file.""" + return os.path.join(self._root, self._submodule, self._SHADOW_FILE) + def __init__(self, submodule: str = '') -> None: """Look for macros defined in the given submodule's source tree. @@ -70,7 +83,8 @@ class Current(ConfigMacros): """ self._root = build_tree.guess_project_root() self._submodule = submodule - public = self._search_files(self._PUBLIC_CONFIG_HEADERS) + shadow_file = self.shadow_file_path() + public = self._load_file(shadow_file) adjusted = self._search_files(self._ADJUST_CONFIG_HEADERS) super().__init__(public, adjusted) @@ -81,12 +95,10 @@ class History(ConfigMacros): Load files created by ``framework/scripts/save_config_history.sh``. """ - def _load_file(self, basename: str) -> FrozenSet[str]: + def _load_history_file(self, basename: str) -> FrozenSet[str]: """Load macro names from the given file in the history directory.""" filename = os.path.join(self._history_dir, basename) - with open(filename, encoding='ascii') as input_: - return frozenset(line.strip() - for line in input_) + return self._load_file(filename) def __init__(self, project: str, version: str) -> None: """Read information about the given project at the given version. @@ -94,6 +106,6 @@ class History(ConfigMacros): The information must be present in history files in the framework. """ self._history_dir = os.path.join(build_tree.framework_root(), 'history') - public = self._load_file(f'config-options-{project}-{version}.txt') - adjusted = self._load_file(f'config-adjust-{project}-{version}.txt') + public = self._load_history_file(f'config-options-{project}-{version}.txt') + adjusted = self._load_history_file(f'config-adjust-{project}-{version}.txt') super().__init__(public, adjusted)