Kaynağa Gözat

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.
Nicolas Van Bossuyt 5 yıl önce
ebeveyn
işleme
81c4dcadf1
3 değiştirilmiş dosya ile 14 ekleme ve 1 silme
  1. 5 0
      Kernel/Console.cpp
  2. 1 0
      Kernel/Console.h
  3. 8 1
      Kernel/kprintf.cpp

+ 5 - 0
Kernel/Console.cpp

@@ -13,6 +13,11 @@ Console& Console::the()
     return *s_the;
     return *s_the;
 }
 }
 
 
+bool Console::is_initialized()
+{
+    return s_the != nullptr;
+}
+
 Console::Console()
 Console::Console()
     : CharacterDevice(5, 1)
     : CharacterDevice(5, 1)
 {
 {

+ 1 - 0
Kernel/Console.h

@@ -14,6 +14,7 @@ class Console final : public CharacterDevice {
     AK_MAKE_ETERNAL
     AK_MAKE_ETERNAL
 public:
 public:
     static Console& the();
     static Console& the();
+    static bool is_initialized();
 
 
     Console();
     Console();
     virtual ~Console() override;
     virtual ~Console() override;

+ 8 - 1
Kernel/kprintf.cpp

@@ -70,7 +70,14 @@ static void console_putch(char*&, char ch)
 {
 {
     if (serial_debug)
     if (serial_debug)
         serial_putch(ch);
         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, ...)
 int kprintf(const char* fmt, ...)