From 51258613cc07ca8f6def8d0d15f6152d85a4c652 Mon Sep 17 00:00:00 2001 From: Alejandro Sirgo Rica Date: Thu, 12 Sep 2024 14:08:53 +0200 Subject: src: verify the fields of the efibootmgr json in /refresh Don't send the efi data in the /refresh payload if efibootmgr is missing any of the json keys. Log the missing keys in case of missing some. --- src/live/ogOperations.py | 6 +++--- src/utils/uefi.py | 31 +++++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/live/ogOperations.py b/src/live/ogOperations.py index 9c32cce..c51215c 100644 --- a/src/live/ogOperations.py +++ b/src/live/ogOperations.py @@ -164,7 +164,7 @@ class OgLiveOperations: return data try: - efibootmgr_out = run_efibootmgr_json() + efibootmgr_out = run_efibootmgr_json(validate=True) except Exception as e: logging.warning(e) return data @@ -172,8 +172,8 @@ class OgLiveOperations: data['entries'] = [] for idx, entry_name in enumerate(efibootmgr_out['BootOrder']): entry_name = 'Boot' + entry_name - for entry in efibootmgr_out['vars']: - if entry['name'] == entry_name: + for entry in efibootmgr_out.get('vars', []): + if entry.get('name', '') == entry_name: entry['order'] = idx data['entries'].append(entry) break diff --git a/src/utils/uefi.py b/src/utils/uefi.py index 5ca8270..c0bc958 100644 --- a/src/utils/uefi.py +++ b/src/utils/uefi.py @@ -54,21 +54,44 @@ def _check_efibootmgr_json(): def is_uefi_supported(): return os.path.exists("/sys/firmware/efi") +def _validate_efibootmgr_json(dict_json): + missing_fields = [] + if not 'BootOrder' in dict_json: + missing_fields.append('BootOrder') -def run_efibootmgr_json(): + if not 'vars' in dict_json: + missing_fields.append('vars') + + for i, entry in enumerate(dict_json.get('vars', [])): + if not 'name' in entry: + missing_fields.append(f'vars[{i}].name') + + if not 'active' in entry: + missing_fields.append('vars[{i}].active') + + if not 'description' in entry: + missing_fields.append('vars[{i}].description') + + if missing_fields: + raise OgError('Missing required efibootmgr fields: ' + ', '.join(missing_fields)) + +def run_efibootmgr_json(validate): if _check_efibootmgr_json() is False: raise OgError(f'{EFIBOOTMGR_BIN} not available') proc = subprocess.run([EFIBOOTMGR_BIN, '--json'], capture_output=True, text=True) dict_json = json.loads(proc.stdout) + if validate: + _validate_efibootmgr_json(dict_json) + return dict_json def efibootmgr_bootnext(description): logging.info(f'Setting BootNext to value from boot entry with label {description}') bootnext_cmd = '{efibootmgr} -n {bootnum}' - boot_entries = run_efibootmgr_json().get('vars', []) + boot_entries = run_efibootmgr_json(validate=False).get('vars', []) entry = _find_bootentry(boot_entries, description) num = _strip_boot_prefix(entry) # efibootmgr output uses BootXXXX for each entry, remove the "Boot" prefix. @@ -78,7 +101,7 @@ def efibootmgr_bootnext(description): def efibootmgr_delete_bootentry(label): - dict_json = run_efibootmgr_json() + dict_json = run_efibootmgr_json(validate=False) efibootmgr_cmd = '{efibootmgr} -q -b {bootnum} -B' for entry in dict_json.get('vars', []): @@ -92,7 +115,7 @@ def efibootmgr_delete_bootentry(label): def efibootmgr_create_bootentry(disk, part, loader, label, add_to_bootorder=True): - entries = run_efibootmgr_json().get('vars', []) + entries = run_efibootmgr_json(validate=False).get('vars', []) create_opt = '-c' if add_to_bootorder else '-C' index_opt = f'-I {len(entries)}' # Requires efibootmgr version 18 efibootmgr_cmd = f'{EFIBOOTMGR_BIN} {create_opt} {index_opt} -d {disk} -p {part} -L {label} -l {loader}' -- cgit v1.2.3-18-g5258