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;
