summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Van Bossuyt <nicolas.van.bossuyt@gmail.com>2019-11-03 13:17:55 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-11-03 13:17:55 +0100
commit81c4dcadf142b3d428230c6faa194596be8f3017 (patch)
treef3efb72e25769015acfa4625397c233d6f5b0023
parent8216019b2e8df1edcc2c1f4d7e0c88f69fc2b601 (diff)
downloadserenity-81c4dcadf142b3d428230c6faa194596be8f3017.zip
Kernel: Prevent kprintf() from asserting in Console::the() (#718)
This triggered a stack overflow because ubsan can call kprintf() at any time, even before Console is initialized.
-rw-r--r--Kernel/Console.cpp5
-rw-r--r--Kernel/Console.h1
-rw-r--r--Kernel/kprintf.cpp9
3 files changed, 14 insertions, 1 deletions
diff --git a/Kernel/Console.cpp b/Kernel/Console.cpp
index 91ddfd56cd..c405418942 100644
--- a/Kernel/Console.cpp
+++ b/Kernel/Console.cpp
@@ -13,6 +13,11 @@ Console& Console::the()
return *s_the;
}
+bool Console::is_initialized()
+{
+ return s_the != nullptr;
+}
+
Console::Console()
: CharacterDevice(5, 1)
{
diff --git a/Kernel/Console.h b/Kernel/Console.h
index be43380bc8..a9c89f5df7 100644
--- a/Kernel/Console.h
+++ b/Kernel/Console.h
@@ -14,6 +14,7 @@ class Console final : public CharacterDevice {
AK_MAKE_ETERNAL
public:
static Console& the();
+ static bool is_initialized();
Console();
virtual ~Console() override;
diff --git a/Kernel/kprintf.cpp b/Kernel/kprintf.cpp
index 69dffbcf7e..333929d1a0 100644
--- a/Kernel/kprintf.cpp
+++ b/Kernel/kprintf.cpp
@@ -70,7 +70,14 @@ static void console_putch(char*&, char ch)
{
if (serial_debug)
serial_putch(ch);
- Console::the().put_char(ch);
+
+ // It would be bad to reach the assert in Console()::the() and do a stack overflow
+
+ if (Console::is_initialized()) {
+ Console::the().put_char(ch);
+ } else {
+ IO::out8(0xe9, ch);
+ }
}
int kprintf(const char* fmt, ...)