This fixes a 4 year old (non-deterministic) bug in probe_config_partitions.
How to reproduce (assuming ENV_NUM_CONFIG_PARTS=2): 1) Compile EBG with support for 2 config partitions 2) Run bg_printenv in an environment with 3 config partitions 3) If no segfault, go back to 1). Note: There is *no guarantee* that you can trigger the bug by following the above steps due to undefined behavior. Analysis: The argument `CONFIG_PART *cfgpart` is an array of size `ENV_NUM_CONFIG_PARTS`. If there are more than `ENV_NUM_CONFIG_PARTS` config partitions, the element `cfgpart[ENV_NUM_CONFIG_PARTS]` is used in probe_config_file. Although there is a NULL check in the latter function, the memory content of `cfgpart[ENV_NUM_CONFIG_PARTS]` is undefined since it is out-of-bounds. It may be NULL, in which case everything is fine - but it may also be some other (garbage) value... This is dangerous territory. For reference, below is a backtrace based on 55a1e3e (note: this is *not* the culprit commit): 0 0x00005626dd6d8aa7 in probe_config_file (cfgpart=cfgpart@entry=0x5626dd720ff0) at env/env_config_file.c:69 1 0x00005626dd6d8c10 in probe_config_partitions (cfgpart=cfgpart@entry=0x5626dd720fc0 <config_parts>) at env/env_config_partitions.c:61 2 0x00005626dd6d7c5f in bgenv_init () at env/env_api_fat.c:141 3 0x00005626dd6d70d6 in bg_printenv (argc=<optimized out>, argv=<optimized out>) at tools/bg_printenv.c:347 Signed-off-by: Michael Adler <[email protected]> --- env/env_config_partitions.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/env/env_config_partitions.c b/env/env_config_partitions.c index db3e08f..a67c468 100644 --- a/env/env_config_partitions.c +++ b/env/env_config_partitions.c @@ -53,19 +53,18 @@ bool probe_config_partitions(CONFIG_PART *cfgpart) (void)snprintf(devpath, 4096, "%s%u", dev->path, part->num); } - cfgpart[count].devpath = strdup(devpath); - if (!cfgpart[count].devpath) { + + CONFIG_PART tmp = {.devpath = strdup(devpath)}; + if (!tmp.devpath) { VERBOSE(stderr, "Out of memory."); return false; } - if (probe_config_file(&cfgpart[count])) { + if (probe_config_file(&tmp)) { printf_debug("%s", "Environment file found.\n"); - if (count >= ENV_NUM_CONFIG_PARTS) { - VERBOSE(stderr, "Error, there are " - "more than %d config " - "partitions.\n", - ENV_NUM_CONFIG_PARTS); - return false; + if (count < ENV_NUM_CONFIG_PARTS) { + cfgpart[count] = tmp; + } else { + free(tmp.devpath); } count++; } @@ -77,6 +76,13 @@ bool probe_config_partitions(CONFIG_PART *cfgpart) "Error, less than %d config partitions exist.\n", ENV_NUM_CONFIG_PARTS); return false; + } else if (count > ENV_NUM_CONFIG_PARTS) { + VERBOSE(stderr, + "Error, there are " + "more than %d config " + "partitions.\n", + ENV_NUM_CONFIG_PARTS); + return false; } return true; } -- 2.33.1 -- 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 view this discussion on the web visit https://groups.google.com/d/msgid/efibootguard-dev/20211202085943.113541-1-michael.adler%40siemens.com.
