diff options
author | Anton Kling <anton@kling.gg> | 2023-10-31 14:18:25 +0100 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2023-10-31 14:18:25 +0100 |
commit | b416c3704a36f0c055fdb51ad014c9f4787aee91 (patch) | |
tree | 7ab41db8f094c02b982e77c01d51cf50ca01f3fb /kernel/arch/i386 | |
parent | bb4963089b04083220891b11255bc79d43af5f2e (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.c | 9 |
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) { |