From 29f9a38f767ee681a8130314aece5a00651d4b5a Mon Sep 17 00:00:00 2001 From: Liav A Date: Fri, 18 Jun 2021 11:37:26 +0300 Subject: [PATCH] Kernel: Don't use naked new statements in init process Instead, try to create the device objects in separate static methods, and if we fail for some odd reason to allocate memory for such devices, just panic with that reason. --- Kernel/Devices/FullDevice.cpp | 6 ++++++ Kernel/Devices/FullDevice.h | 4 +++- Kernel/Devices/MemoryDevice.cpp | 6 ++++++ Kernel/Devices/MemoryDevice.h | 3 ++- Kernel/Devices/RandomDevice.cpp | 6 ++++++ Kernel/Devices/RandomDevice.h | 4 +++- Kernel/Devices/SerialDevice.cpp | 28 ++++++++++++++++++++++++++++ Kernel/Devices/SerialDevice.h | 10 ++++------ Kernel/Devices/ZeroDevice.cpp | 6 ++++++ Kernel/Devices/ZeroDevice.h | 3 ++- Kernel/init.cpp | 16 ++++++++-------- 11 files changed, 74 insertions(+), 18 deletions(-) diff --git a/Kernel/Devices/FullDevice.cpp b/Kernel/Devices/FullDevice.cpp index 6aab209181..855d6a85f3 100644 --- a/Kernel/Devices/FullDevice.cpp +++ b/Kernel/Devices/FullDevice.cpp @@ -8,10 +8,16 @@ #include #include #include +#include #include namespace Kernel { +UNMAP_AFTER_INIT NonnullRefPtr FullDevice::must_create() +{ + return adopt_ref_if_nonnull(new FullDevice).release_nonnull(); +} + UNMAP_AFTER_INIT FullDevice::FullDevice() : CharacterDevice(1, 7) { diff --git a/Kernel/Devices/FullDevice.h b/Kernel/Devices/FullDevice.h index 037b4c7308..2fb8d4e785 100644 --- a/Kernel/Devices/FullDevice.h +++ b/Kernel/Devices/FullDevice.h @@ -13,7 +13,7 @@ namespace Kernel { class FullDevice final : public CharacterDevice { AK_MAKE_ETERNAL public: - FullDevice(); + static NonnullRefPtr must_create(); virtual ~FullDevice() override; // ^Device @@ -21,6 +21,8 @@ public: virtual String device_name() const override { return "full"; } private: + FullDevice(); + // ^CharacterDevice virtual KResultOr read(FileDescription&, u64, UserOrKernelBuffer&, size_t) override; virtual KResultOr write(FileDescription&, u64, const UserOrKernelBuffer&, size_t) override; diff --git a/Kernel/Devices/MemoryDevice.cpp b/Kernel/Devices/MemoryDevice.cpp index 37c05bf663..5e644a9d21 100644 --- a/Kernel/Devices/MemoryDevice.cpp +++ b/Kernel/Devices/MemoryDevice.cpp @@ -8,11 +8,17 @@ #include #include #include +#include #include #include namespace Kernel { +UNMAP_AFTER_INIT NonnullRefPtr MemoryDevice::must_create() +{ + return adopt_ref_if_nonnull(new MemoryDevice).release_nonnull(); +} + UNMAP_AFTER_INIT MemoryDevice::MemoryDevice() : CharacterDevice(1, 1) { diff --git a/Kernel/Devices/MemoryDevice.h b/Kernel/Devices/MemoryDevice.h index da08e9e43f..688d81275b 100644 --- a/Kernel/Devices/MemoryDevice.h +++ b/Kernel/Devices/MemoryDevice.h @@ -16,7 +16,7 @@ namespace Kernel { class MemoryDevice final : public CharacterDevice { AK_MAKE_ETERNAL public: - MemoryDevice(); + static NonnullRefPtr must_create(); ~MemoryDevice(); virtual KResultOr mmap(Process&, FileDescription&, const Range&, u64 offset, int prot, bool shared) override; @@ -26,6 +26,7 @@ public: virtual String device_name() const override { return "mem"; }; private: + MemoryDevice(); virtual const char* class_name() const override { return "MemoryDevice"; } virtual bool can_read(const FileDescription&, size_t) const override { return true; } virtual bool can_write(const FileDescription&, size_t) const override { return false; } diff --git a/Kernel/Devices/RandomDevice.cpp b/Kernel/Devices/RandomDevice.cpp index 1af96d818c..b2f0cf5e4b 100644 --- a/Kernel/Devices/RandomDevice.cpp +++ b/Kernel/Devices/RandomDevice.cpp @@ -5,10 +5,16 @@ */ #include +#include #include namespace Kernel { +UNMAP_AFTER_INIT NonnullRefPtr RandomDevice::must_create() +{ + return adopt_ref_if_nonnull(new RandomDevice).release_nonnull(); +} + UNMAP_AFTER_INIT RandomDevice::RandomDevice() : CharacterDevice(1, 8) { diff --git a/Kernel/Devices/RandomDevice.h b/Kernel/Devices/RandomDevice.h index 2d98a220ff..e553b5dc8c 100644 --- a/Kernel/Devices/RandomDevice.h +++ b/Kernel/Devices/RandomDevice.h @@ -13,7 +13,7 @@ namespace Kernel { class RandomDevice final : public CharacterDevice { AK_MAKE_ETERNAL public: - RandomDevice(); + static NonnullRefPtr must_create(); virtual ~RandomDevice() override; // ^Device @@ -21,6 +21,8 @@ public: virtual String device_name() const override { return "random"; } private: + RandomDevice(); + // ^CharacterDevice virtual KResultOr read(FileDescription&, u64, UserOrKernelBuffer&, size_t) override; virtual KResultOr write(FileDescription&, u64, const UserOrKernelBuffer&, size_t) override; diff --git a/Kernel/Devices/SerialDevice.cpp b/Kernel/Devices/SerialDevice.cpp index ef41d620be..e97f2059eb 100644 --- a/Kernel/Devices/SerialDevice.cpp +++ b/Kernel/Devices/SerialDevice.cpp @@ -7,9 +7,37 @@ #include #include +#include namespace Kernel { +#define SERIAL_COM1_ADDR 0x3F8 +#define SERIAL_COM2_ADDR 0x2F8 +#define SERIAL_COM3_ADDR 0x3E8 +#define SERIAL_COM4_ADDR 0x2E8 + +UNMAP_AFTER_INIT NonnullRefPtr SerialDevice::must_create(size_t com_number) +{ + SerialDevice* device = nullptr; + switch (com_number) { + case 0: + device = new SerialDevice(IOAddress(SERIAL_COM1_ADDR), 64); + break; + case 1: + device = new SerialDevice(IOAddress(SERIAL_COM2_ADDR), 65); + break; + case 2: + device = new SerialDevice(IOAddress(SERIAL_COM3_ADDR), 66); + break; + case 3: + device = new SerialDevice(IOAddress(SERIAL_COM4_ADDR), 67); + break; + default: + break; + } + return adopt_ref_if_nonnull(device).release_nonnull(); +} + UNMAP_AFTER_INIT SerialDevice::SerialDevice(IOAddress base_addr, unsigned minor) : CharacterDevice(4, minor) , m_base_addr(base_addr) diff --git a/Kernel/Devices/SerialDevice.h b/Kernel/Devices/SerialDevice.h index 71a860000a..fc98872586 100644 --- a/Kernel/Devices/SerialDevice.h +++ b/Kernel/Devices/SerialDevice.h @@ -11,15 +11,11 @@ namespace Kernel { -#define SERIAL_COM1_ADDR 0x3F8 -#define SERIAL_COM2_ADDR 0x2F8 -#define SERIAL_COM3_ADDR 0x3E8 -#define SERIAL_COM4_ADDR 0x2E8 - class SerialDevice final : public CharacterDevice { AK_MAKE_ETERNAL public: - SerialDevice(IOAddress base_addr, unsigned minor); + static NonnullRefPtr must_create(size_t com_number); + virtual ~SerialDevice() override; // ^CharacterDevice @@ -113,6 +109,8 @@ public: private: friend class PCISerialDevice; + SerialDevice(IOAddress base_addr, unsigned minor); + // ^CharacterDevice virtual const char* class_name() const override { return "SerialDevice"; } diff --git a/Kernel/Devices/ZeroDevice.cpp b/Kernel/Devices/ZeroDevice.cpp index 1f3fddbf07..45cbf9f802 100644 --- a/Kernel/Devices/ZeroDevice.cpp +++ b/Kernel/Devices/ZeroDevice.cpp @@ -7,9 +7,15 @@ #include "ZeroDevice.h" #include #include +#include namespace Kernel { +UNMAP_AFTER_INIT NonnullRefPtr ZeroDevice::must_create() +{ + return adopt_ref_if_nonnull(new ZeroDevice).release_nonnull(); +} + UNMAP_AFTER_INIT ZeroDevice::ZeroDevice() : CharacterDevice(1, 5) { diff --git a/Kernel/Devices/ZeroDevice.h b/Kernel/Devices/ZeroDevice.h index 861a7d40dd..df3699314a 100644 --- a/Kernel/Devices/ZeroDevice.h +++ b/Kernel/Devices/ZeroDevice.h @@ -13,7 +13,7 @@ namespace Kernel { class ZeroDevice final : public CharacterDevice { AK_MAKE_ETERNAL public: - ZeroDevice(); + static NonnullRefPtr must_create(); virtual ~ZeroDevice() override; // ^Device @@ -21,6 +21,7 @@ public: virtual String device_name() const override { return "zero"; } private: + ZeroDevice(); // ^CharacterDevice virtual KResultOr read(FileDescription&, u64, UserOrKernelBuffer&, size_t) override; virtual KResultOr write(FileDescription&, u64, const UserOrKernelBuffer&, size_t) override; diff --git a/Kernel/init.cpp b/Kernel/init.cpp index 9f057a3e77..4a7529b8f2 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -158,10 +158,10 @@ extern "C" UNMAP_AFTER_INIT [[noreturn]] void init() NullDevice::initialize(); if (!get_serial_debug()) - new SerialDevice(IOAddress(SERIAL_COM1_ADDR), 64); - new SerialDevice(IOAddress(SERIAL_COM2_ADDR), 65); - new SerialDevice(IOAddress(SERIAL_COM3_ADDR), 66); - new SerialDevice(IOAddress(SERIAL_COM4_ADDR), 67); + (void)SerialDevice::must_create(0).leak_ref(); + (void)SerialDevice::must_create(1).leak_ref(); + (void)SerialDevice::must_create(2).leak_ref(); + (void)SerialDevice::must_create(3).leak_ref(); VMWareBackdoor::the(); // don't wait until first mouse packet HIDManagement::initialize(); @@ -243,10 +243,10 @@ void init_stage2(void*) NetworkingManagement::the().initialize(); Syscall::initialize(); - new MemoryDevice; - new ZeroDevice; - new FullDevice; - new RandomDevice; + (void)MemoryDevice::must_create().leak_ref(); + (void)ZeroDevice::must_create().leak_ref(); + (void)FullDevice::must_create().leak_ref(); + (void)RandomDevice::must_create().leak_ref(); PTYMultiplexer::initialize(); SB16::detect();