diff options
author | Nicolas Van Bossuyt <nicolas.van.bossuyt@gmail.com> | 2019-11-03 13:17:55 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-11-03 13:17:55 +0100 |
commit | 81c4dcadf142b3d428230c6faa194596be8f3017 (patch) | |
tree | f3efb72e25769015acfa4625397c233d6f5b0023 | |
parent | 8216019b2e8df1edcc2c1f4d7e0c88f69fc2b601 (diff) | |
download | serenity-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.cpp | 5 | ||||
-rw-r--r-- | Kernel/Console.h | 1 | ||||
-rw-r--r-- | Kernel/kprintf.cpp | 9 |
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, ...) |