From ed6d842f851252be62a433f30ceafe0cfb9fd09f Mon Sep 17 00:00:00 2001 From: Brian Gianforcaro Date: Thu, 12 Aug 2021 22:11:06 -0700 Subject: [PATCH] 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 :^). --- Kernel/Syscalls/debug.cpp | 5 +++-- 1 file 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 Process::sys$dbgputstr(Userspace 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(); } }