mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-23 08:00:20 +00:00
ed6d842f85
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 :^).
50 lines
1.1 KiB
C++
50 lines
1.1 KiB
C++
/*
|
|
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <Kernel/KSyms.h>
|
|
#include <Kernel/Process.h>
|
|
#include <Kernel/UserOrKernelBuffer.h>
|
|
#include <Kernel/kstdio.h>
|
|
|
|
namespace Kernel {
|
|
|
|
KResultOr<FlatPtr> Process::sys$dump_backtrace()
|
|
{
|
|
VERIFY_NO_PROCESS_BIG_LOCK(this);
|
|
dump_backtrace();
|
|
return 0;
|
|
}
|
|
|
|
KResultOr<FlatPtr> Process::sys$dbgputch(u8 ch)
|
|
{
|
|
VERIFY_NO_PROCESS_BIG_LOCK(this);
|
|
dbgputch(ch);
|
|
return 0;
|
|
}
|
|
|
|
KResultOr<FlatPtr> Process::sys$dbgputstr(Userspace<const char*> characters, size_t size)
|
|
{
|
|
VERIFY_NO_PROCESS_BIG_LOCK(this);
|
|
if (size == 0)
|
|
return 0;
|
|
|
|
if (size <= 1024) {
|
|
char buffer[1024];
|
|
if (!copy_from_user(buffer, characters, size))
|
|
return EFAULT;
|
|
dbgputstr(buffer, size);
|
|
return size;
|
|
}
|
|
|
|
auto result = try_copy_kstring_from_user(characters, size);
|
|
if (result.is_error())
|
|
return result.error();
|
|
auto string = result.release_value();
|
|
dbgputstr(string->view());
|
|
return string->length();
|
|
}
|
|
|
|
}
|