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);
                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);
                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;
+               }
+       }
+
+       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__
-- 
2.17.0

-- 
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/20180525120108.31055-10-andreas.reichel.ext%40siemens.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to