diff options
author | Brian Gianforcaro <bgianf@serenityos.org> | 2021-08-12 22:11:06 -0700 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-08-13 11:08:11 +0200 |
commit | ed6d842f851252be62a433f30ceafe0cfb9fd09f (patch) | |
tree | 1cf91508652e0815708b2dff827b5cade24c272f /Kernel | |
parent | 40a942d28b979f26bb3442f9ad7bbdbd7882ff93 (diff) | |
download | serenity-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.cpp | 5 |
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(); } } |