From 2cda44c23eb54cebf60f90aaeda82d95ec204152 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 12 Feb 2024 17:23:59 +0100 Subject: [PATCH] efi-loader: make efi_loader_get_entries() handling missing NUL termination gracefully Our function so far assumed that the LoaderEntries's last string is or is not NUL terminated. But if it was, then we'd debug log about this, claiming there was an invalid id. sd-boot actually ends the list in a properly NUL-terminated string, hence we should just accept that. Handle that case gracefully, and add comments explaining why we have two ways why we exit the loop. This is cosmetic only, just suppresses a misleading debug log message. --- src/shared/efi-loader.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/shared/efi-loader.c b/src/shared/efi-loader.c index 758aaa13c1..7d6bda924a 100644 --- a/src/shared/efi-loader.c +++ b/src/shared/efi-loader.c @@ -102,7 +102,8 @@ int efi_loader_get_entries(char ***ret) { if (r < 0) return r; - /* The variable contains a series of individually NUL terminated UTF-16 strings. */ + /* The variable contains a series of individually NUL terminated UTF-16 strings. We gracefully + * consider the final NUL byte optional (i.e. the last string may or may not end in a NUL byte).*/ for (size_t i = 0, start = 0;; i++) { _cleanup_free_ char *decoded = NULL; @@ -116,6 +117,11 @@ int efi_loader_get_entries(char ***ret) { if (!end && entries[i] != 0) continue; + /* Empty string at the end of variable? That's the trailer, we are done (i.e. we have a final + * NUL terminator). */ + if (end && start == i) + break; + /* We reached the end of a string, let's decode it into UTF-8 */ decoded = utf16_to_utf8(entries + start, (i - start) * sizeof(char16_t)); if (!decoded) @@ -128,7 +134,8 @@ int efi_loader_get_entries(char ***ret) { } else log_debug("Ignoring invalid loader entry '%s'.", decoded); - /* We reached the end of the variable */ + /* Exit the loop if we reached the end of the variable (i.e. we do not have a final NUL + * terminator) */ if (end) break; -- 2.25.1