:: commit 69050a091693feb0e9eb8bf553cbcb38ff7d70ba

Mintsuki <mintsuki@protonmail.com> — 2026-01-11 21:03

parents: e4c3fe1526

misc: Add bounds checking to get_absolute_path()

diff --git a/common/lib/misc.h b/common/lib/misc.h
index c92c3aa4..623a293e 100644
--- a/common/lib/misc.h
+++ b/common/lib/misc.h
@@ -44,7 +44,7 @@ extern uint64_t usec_at_bootloader_entry;
 
 bool parse_resolution(size_t *width, size_t *height, size_t *bpp, const char *buf);
 
-void get_absolute_path(char *path_ptr, const char *path, const char *pwd);
+bool get_absolute_path(char *path_ptr, const char *path, const char *pwd, size_t size);
 
 uint32_t oct2bin(uint8_t *str, uint32_t max);
 uint32_t hex2bin(uint8_t *str, uint32_t size);
diff --git a/common/lib/misc.s2.c b/common/lib/misc.s2.c
index c4b3646b..61847198 100644
--- a/common/lib/misc.s2.c
+++ b/common/lib/misc.s2.c
@@ -53,17 +53,24 @@ uint64_t strtoui(const char *s, const char **end, int base) {
     return n;
 }
 
-void get_absolute_path(char *path_ptr, const char *path, const char *pwd) {
+bool get_absolute_path(char *path_ptr, const char *path, const char *pwd, size_t size) {
     char *orig_ptr = path_ptr;
+    char *end_ptr = path_ptr + size - 1;
+
+    if (size == 0) return false;
 
     if (!*path) {
-        strcpy(path_ptr, pwd);
-        return;
+        size_t pwd_len = strlen(pwd);
+        if (pwd_len >= size) return false;
+        memcpy(path_ptr, pwd, pwd_len + 1);
+        return true;
     }
 
     if (*path != '/') {
-        strcpy(path_ptr, pwd);
-        path_ptr += strlen(path_ptr);
+        size_t pwd_len = strlen(pwd);
+        if (pwd_len >= size) return false;
+        memcpy(path_ptr, pwd, pwd_len + 1);
+        path_ptr += pwd_len;
     } else {
         *path_ptr = '/';
         path_ptr++;
@@ -100,6 +107,7 @@ first_run:
                     continue;
                 }
                 if (((path_ptr - 1) != orig_ptr) && (*(path_ptr - 1) != '/')) {
+                    if (path_ptr >= end_ptr) return false;
                     *path_ptr = '/';
                     path_ptr++;
                 }
@@ -109,8 +117,9 @@ term:
                 if ((*(path_ptr - 1) == '/') && ((path_ptr - 1) != orig_ptr))
                     path_ptr--;
                 *path_ptr = 0;
-                return;
+                return true;
             default:
+                if (path_ptr >= end_ptr) return false;
                 *path_ptr = *path;
                 path++;
                 path_ptr++;
diff --git a/common/protos/limine.c b/common/protos/limine.c
index 9404b492..19a659d8 100644
--- a/common/protos/limine.c
+++ b/common/protos/limine.c
@@ -1179,7 +1179,10 @@ FEAT_START
             module_path_abs_p += k_root_len;
             memcpy(module_path_abs_p, "):", 2);
             module_path_abs_p += 2;
-            get_absolute_path(module_path_abs_p, module_path, k_path);
+            size_t remaining_size = 1024 - (module_path_abs_p - module_path_abs);
+            if (!get_absolute_path(module_path_abs_p, module_path, k_path, remaining_size)) {
+                panic(true, "limine: Internal module path too long");
+            }
 
             module_path = module_path_abs;
             module_path_allocated = true;
tab: 248 wrap: offon