summaryrefslogtreecommitdiff
path: root/kernel/arch/i386
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2023-10-31 14:18:25 +0100
committerAnton Kling <anton@kling.gg>2023-10-31 14:18:25 +0100
commitb416c3704a36f0c055fdb51ad014c9f4787aee91 (patch)
tree7ab41db8f094c02b982e77c01d51cf50ca01f3fb /kernel/arch/i386
parentbb4963089b04083220891b11255bc79d43af5f2e (diff)
Kernel: Bug fix, infinite loop when checking string memory permissions
If the string is pointed to a very exact location in memory the loop never finishes.
Diffstat (limited to 'kernel/arch/i386')
-rw-r--r--kernel/arch/i386/mmu.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/kernel/arch/i386/mmu.c b/kernel/arch/i386/mmu.c
index ccfe894..f4246d4 100644
--- a/kernel/arch/i386/mmu.c
+++ b/kernel/arch/i386/mmu.c
@@ -475,10 +475,14 @@ move_stack(uint32_t new_stack_address, uint32_t size) {
void *is_valid_user_c_string(const char *ptr, size_t *size) {
void *r = (void *)ptr;
size_t s = 0;
- for (;;) {
+ for (; ((uint32_t)ptr - (uint32_t)r) < 0x1000;) {
void *page = (void *)((uintptr_t)ptr & (uintptr_t)(~(PAGE_SIZE - 1)));
if (!is_valid_userpointer(page, PAGE_SIZE))
return NULL;
+ if (!((uintptr_t)ptr & (PAGE_SIZE - 1))) {
+ ptr++;
+ s++;
+ }
for (; (uintptr_t)ptr & (PAGE_SIZE - 1); ptr++, s++)
if (!*ptr) {
if (size)
@@ -486,6 +490,9 @@ void *is_valid_user_c_string(const char *ptr, size_t *size) {
return r;
}
}
+ // String is too long, something has probably gone wrong.
+ assert(0);
+ return NULL;
}
void *is_valid_userpointer(const void *ptr, size_t s) {