summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorBrian Gianforcaro <bgianf@serenityos.org>2021-08-12 22:11:06 -0700
committerAndreas Kling <kling@serenityos.org>2021-08-13 11:08:11 +0200
commited6d842f851252be62a433f30ceafe0cfb9fd09f (patch)
tree1cf91508652e0815708b2dff827b5cade24c272f /Kernel
parent40a942d28b979f26bb3442f9ad7bbdbd7882ff93 (diff)
downloadserenity-ed6d842f851252be62a433f30ceafe0cfb9fd09f.zip
Kernel: Fix OOB read in sys$dbgputstr(..) during fuzzing
The implementation uses try_copy_kstring_from_user to allocate a kernel string using, but does not use the length of the resulting string. The size parameter to the syscall is untrusted, as try copy kstring will attempt to perform a `safe_strlen(..)` on the user mode string and use that value for the allocated length of the KString instead. The bug is that we are printing the kstring, but with the usermode size argument. During fuzzing this resulted in us walking off the end of the allocated KString buffer printing garbage (or any kernel data!), until we stumbled in to the KSym region and hit a fatal page fault. This is technically a kernel information disclosure, but (un)fortunately the disclosure only happens to the Bochs debug port, and or the serial port if serial debugging is enabled. As far as I can tell it's not actually possible for an untrusted attacker to use this to do something nefarious, as they would need access to the host. If they have host access then they can already do much worse things :^).
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/Syscalls/debug.cpp5
1 files changed, 3 insertions, 2 deletions
diff --git a/Kernel/Syscalls/debug.cpp b/Kernel/Syscalls/debug.cpp
index 5f34084266..30e0312efd 100644
--- a/Kernel/Syscalls/debug.cpp
+++ b/Kernel/Syscalls/debug.cpp
@@ -42,8 +42,9 @@ KResultOr<FlatPtr> Process::sys$dbgputstr(Userspace<const char*> characters, siz
auto result = try_copy_kstring_from_user(characters, size);
if (result.is_error())
return result.error();
- dbgputstr(result.value()->characters(), size);
- return size;
+ auto string = result.release_value();
+ dbgputstr(string->view());
+ return string->length();
}
}