:: commit 4b057bcc88fba35a95fd76059e73a02d5ae7feb0

Mintsuki <mintsuki@protonmail.com> — 2026-04-11 19:04

parents: 959f763a9f

lib/bli: fix various bugs in timeout and entry control

diff --git a/common/lib/bli.c b/common/lib/bli.c
index 5e6c1b4c..3ceb646b 100644
--- a/common/lib/bli.c
+++ b/common/lib/bli.c
@@ -49,12 +49,17 @@ bool decwstr_to_size(const wchar_t *buf, size_t buf_size, size_t *value) {
         return false;
     }
 
+    if (buf_size == 0 || buf[0] == L'\0') {
+        return false;
+    }
+
     while (i * 2 < buf_size && buf[i]) {
         wchar_t c = buf[i];
         if (!(c >= L'0' && c <= L'9')) {
             return false;
         }
-        tmp = tmp * 10 + (c - L'0');
+        tmp = CHECKED_MUL(tmp, (size_t)10, return false);
+        tmp = CHECKED_ADD(tmp, (size_t)(c - L'0'), return false);
         i++;
     }
 
@@ -134,7 +139,7 @@ static bool handle_timeout(wchar_t *variable, bool erase, size_t *timeout, bool
                 attrs,
                 0, NULL);
         }
-        if (getvar_size == 24 && memcmp(timeout_buf, L"menu-force",24) == 0) {
+        if (getvar_size == 22 && memcmp(timeout_buf, L"menu-force", 22) == 0) {
             *skip_timeout = true;
             return true;
         }
@@ -147,6 +152,11 @@ static bool handle_timeout(wchar_t *variable, bool erase, size_t *timeout, bool
         if (!decwstr_to_size(timeout_buf, getvar_size, &t)) {
             return false;
         }
+        // For LoaderConfigTimeoutOneShot, "0" means show menu indefinitely.
+        if (erase && t == 0) {
+            *skip_timeout = true;
+            return true;
+        }
         *timeout = t;
         return true;
     }
@@ -179,7 +189,10 @@ static bool handle_entry(wchar_t *variable, bool erase, char *path, size_t buf_s
 
         size_t i;
         for (i = 0; i < buf_size-1 && i * 2 < getvar_size; i++) {
-            path[i] = wide_path[i] & 0xff; // Assume 0x00 - 0x7f
+            if (wide_path[i] > 0x7f) {
+                return false;
+            }
+            path[i] = wide_path[i] & 0x7f;
         }
         path[i] = 0;
 
@@ -198,14 +211,18 @@ bool bli_get_oneshot_entry(char *path, size_t buf_size) {
 
 void bli_set_selected_entry(const char *path) {
     wchar_t wide_path[256];
-    size_t pos = 0;
-    for (; pos < 256 && pos < strlen(path); pos++) {
+    size_t len = strlen(path);
+    if (len > 255) {
+        len = 255;
+    }
+    for (size_t pos = 0; pos < len; pos++) {
         wide_path[pos] = path[pos];
     }
+    wide_path[len] = L'\0';
     gRT->SetVariable(L"LoaderEntrySelected",
             &bli_vendor_guid,
             EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
-            strlen(path)*2 + 1,
+            (len + 1) * sizeof(wchar_t),
             wide_path);
 }
 
tab: 248 wrap: offon