]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
efi-loader: make efi_loader_get_entries() handling missing NUL termination gracefully
authorLennart Poettering <lennart@poettering.net>
Mon, 12 Feb 2024 16:23:59 +0000 (17:23 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 14 Feb 2024 14:35:52 +0000 (15:35 +0100)
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

index 758aaa13c169ac09ae037ae7114d73aeca5c0ef1..7d6bda924a9a0479b46849dc7121cb12a1c7525a 100644 (file)
@@ -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;