On 2018-05-25 14:01, [ext] Andreas J. Reichel wrote:
From: Andreas Reichel <[email protected]>
If a config partition on the boot device has the fail-safe flag
set, only use environments on the boot device.
Signed-off-by: Andreas Reichel <[email protected]>
---
env/fatvars.c | 49 ++++++++++++++++++++++++++++++++++---
env/syspart.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++-
include/syspart.h | 7 +++++-
3 files changed, 112 insertions(+), 6 deletions(-)
diff --git a/env/fatvars.c b/env/fatvars.c
index ab1b5c4..cefff0c 100644
--- a/env/fatvars.c
+++ b/env/fatvars.c
@@ -25,6 +25,7 @@ BG_STATUS save_current_config(void)
EFI_STATUS efistatus;
UINTN numHandles = CONFIG_PARTITION_MAXCOUNT;
EFI_FILE_HANDLE *roots;
+ EFI_DEVICE_PATH **root_devices;
roots = (EFI_FILE_HANDLE *)mmalloc(sizeof(EFI_FILE_HANDLE) *
CONFIG_PARTITION_MAXCOUNT);
@@ -34,8 +35,25 @@ BG_STATUS save_current_config(void)
return BG_CONFIG_ERROR;
}
- if (EFI_ERROR(enumerate_cfg_parts(roots, &numHandles))) {
- Print(L"Error, could not enumerate config partitions.");
+ root_devices = (EFI_DEVICE_PATH **)mmalloc(sizeof(EFI_DEVICE_PATH *) *
+ CONFIG_PARTITION_MAXCOUNT);
+ if (!root_devices) {
+ Print(L"Error, could not allocate memory for config partition "
+ L"device paths.\n");
+ mfree(roots);
+ return BG_CONFIG_ERROR;
+ }
+
+ if (EFI_ERROR(enumerate_cfg_parts(roots, root_devices, &numHandles))) {
+ Print(L"Error, could not enumerate config partitions.\n");
+ mfree(root_devices);
+ mfree(roots);
+ return BG_CONFIG_ERROR;
+ }
+
+ if (EFI_ERROR(filter_cfg_parts(roots, root_devices, &numHandles))) {
+ Print(L"Error, could not filter config partitions.\n");
+ mfree(root_devices);
With that many error cases, checking them and jumping to a label that
does mfrees and return BG_CONFIG_ERROR becomes handy.
mfree(roots);
return BG_CONFIG_ERROR;
}
@@ -46,6 +64,7 @@ BG_STATUS save_current_config(void)
numHandles, ENV_NUM_CONFIG_PARTS);
/* In case of saving, this must be treated as error, to not
* overwrite another partition's config file. */
+ mfree(root_devices);
mfree(roots);
return BG_CONFIG_ERROR;
}
@@ -57,6 +76,7 @@ BG_STATUS save_current_config(void)
Print(L"Error, could not open environment file on system "
L"partition %d: %r\n",
current_partition, efistatus);
+ mfree(root_devices);
mfree(roots);
return BG_CONFIG_ERROR;
}
@@ -77,6 +97,7 @@ BG_STATUS save_current_config(void)
Print(L"Error, could not close environment config file.\n");
result = BG_CONFIG_ERROR;
}
+ mfree(root_devices);
mfree(roots);
return result;
}
@@ -86,6 +107,7 @@ BG_STATUS load_config(BG_LOADER_PARAMS *bglp)
BG_STATUS result = BG_SUCCESS;
UINTN numHandles = CONFIG_PARTITION_MAXCOUNT;
EFI_FILE_HANDLE *roots;
+ EFI_DEVICE_PATH **root_devices;
UINTN i;
int env_invalid[ENV_NUM_CONFIG_PARTS] = {0};
@@ -97,14 +119,32 @@ BG_STATUS load_config(BG_LOADER_PARAMS *bglp)
return BG_CONFIG_ERROR;
}
- if (EFI_ERROR(enumerate_cfg_parts(roots, &numHandles))) {
- Print(L"Error, could not enumerate config partitions.");
+ root_devices = (EFI_DEVICE_PATH **)mmalloc(sizeof(EFI_DEVICE_PATH *) *
+ CONFIG_PARTITION_MAXCOUNT);
+ if (!root_devices) {
+ Print(L"Error, could not allocate memory for config partition "
+ L"device paths.\n");
+ mfree(roots);
+ return BG_CONFIG_ERROR;
+ }
+
+ if (EFI_ERROR(enumerate_cfg_parts(roots, root_devices, &numHandles))) {
+ Print(L"Error, could not enumerate config partitions.\n");
+ mfree(root_devices);
+ mfree(roots);
+ return BG_CONFIG_ERROR;
+ }
+
+ if (EFI_ERROR(filter_cfg_parts(roots, root_devices, &numHandles))) {
+ Print(L"Error, could not filter config partitions.\n");
+ mfree(root_devices);
Same here.
mfree(roots);
return BG_CONFIG_ERROR;
}
if (numHandles > ENV_NUM_CONFIG_PARTS) {
Print(L"Error, too many config partitions found. Aborting.\n");
+ mfree(root_devices);
mfree(roots);
return BG_CONFIG_ERROR;
}
@@ -223,6 +263,7 @@ BG_STATUS load_config(BG_LOADER_PARAMS *bglp)
Print(L" kernel: %s\n", bglp->payload_path);
Print(L" args: %s\n", bglp->payload_options);
Print(L" timeout: %d seconds\n", bglp->timeout);
+ mfree(root_devices);
mfree(roots);
return result;
}
diff --git a/env/syspart.c b/env/syspart.c
index aa848d0..86628a0 100644
--- a/env/syspart.c
+++ b/env/syspart.c
@@ -37,7 +37,9 @@ EFI_STATUS read_cfg_file(EFI_FILE_HANDLE fh, VOID *buffer)
return uefi_call_wrapper(fh->Read, 3, fh, &readlen, buffer);
}
-EFI_STATUS enumerate_cfg_parts(EFI_FILE_HANDLE *roots, UINTN *numHandles)
+EFI_STATUS enumerate_cfg_parts(EFI_FILE_HANDLE *roots,
+ EFI_DEVICE_PATH **root_devices,
+ UINTN *numHandles)
{
EFI_STATUS status;
UINTN rootCount = 0;
@@ -57,6 +59,7 @@ EFI_STATUS enumerate_cfg_parts(EFI_FILE_HANDLE *roots, UINTN
*numHandles)
if (status == EFI_SUCCESS) {
Print(L"Config file found on volume %d.\n", index);
roots[rootCount] = volumes[index].root;
+ root_devices[rootCount] = volumes[index].devpath;
rootCount++;
status = close_cfg_file(volumes[index].root, fh);
if (EFI_ERROR(status)) {
@@ -70,3 +73,60 @@ EFI_STATUS enumerate_cfg_parts(EFI_FILE_HANDLE *roots, UINTN
*numHandles)
Print(L"%d config partitions detected.\n", rootCount);
return EFI_SUCCESS;
}
+
+EFI_STATUS filter_cfg_parts(EFI_FILE_HANDLE *roots,
+ EFI_DEVICE_PATH **root_devices, UINTN *numHandles)
+{
+ BOOLEAN only_envs_on_bootdevice = FALSE;
+
+ Print(L"Config filter: \n");
+ for (UINTN index = 0; index < *numHandles; index++) {
+ EFI_FILE_HANDLE fh = NULL;
+ EFI_STATUS status;
+ BG_ENVDATA env;
+
+ status = open_cfg_file(roots[index], &fh, EFI_FILE_MODE_READ);
+ if (EFI_ERROR(status)) {
+ return status;
+ }
+
+ status = read_cfg_file(fh, &env);
+ if (EFI_ERROR(status)) {
+ return status;
+ }
+
+ if (IsOnBootDevice(root_devices[index]) &&
+ (env.status_flags & ENV_STATUS_FAILSAFE)) {
+ only_envs_on_bootdevice = TRUE;
+ };
+
+ status = close_cfg_file(roots[index], fh);
+ if (EFI_ERROR(status)) {
+ return status;
+ }
Sometimes I like to use a Macro for these kind of repeating error checks
and returns.
+ }
+
+ if (!only_envs_on_bootdevice) {
+ // nothing to do
+ return EFI_SUCCESS;
+ }
+
+ Print(L"Fail-Safe Mode enabled.\n");
+ UINTN index = 0;
+ do {
+ if (!IsOnBootDevice(root_devices[index])) {
+ for (UINTN j = index; j < *numHandles-1; j++) {
+ roots[j] = roots[j+1];
+ root_devices[j] = root_devices[j+1];
+ }
+ mfree(roots[*numHandles-1]);
+ mfree(root_devices[*numHandles-1]);
+ (*numHandles)--;
+ Print(L"Filtered Config #%d\n", index);
+ }
+ index++;
+ } while(index < *numHandles);
+
+ Print(L"Remaining Config Partitions: %d\n", *numHandles);
+ return EFI_SUCCESS;
+}
diff --git a/include/syspart.h b/include/syspart.h
index 27caa93..269fa25 100644
--- a/include/syspart.h
+++ b/include/syspart.h
@@ -25,6 +25,11 @@ EFI_STATUS open_cfg_file(EFI_FILE_HANDLE root,
EFI_FILE_HANDLE *fh,
UINT64 mode);
EFI_STATUS close_cfg_file(EFI_FILE_HANDLE root, EFI_FILE_HANDLE fh);
EFI_STATUS read_cfg_file(EFI_FILE_HANDLE fh, VOID *buffer);
-EFI_STATUS enumerate_cfg_parts(EFI_FILE_HANDLE *roots, UINTN *maxHandles);
+EFI_STATUS enumerate_cfg_parts(EFI_FILE_HANDLE *roots,
+ EFI_DEVICE_PATH **root_devices,
+ UINTN *maxHandles);
+EFI_STATUS filter_cfg_parts(EFI_FILE_HANDLE *roots,
+ EFI_DEVICE_PATH **root_devices,
+ UINTN *maxHandles);
#endif // __H_SYSPART__
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-54 Fax: (+49)-8142-66989-80 Email: [email protected]
--
You received this message because you are subscribed to the Google Groups "EFI Boot
Guard" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/efibootguard-dev/5ab8af3c-c51b-1007-ed40-753e40d81f01%40siemens.com.
For more options, visit https://groups.google.com/d/optout.