Kernel: Prevent userspace from overwriting CPU load memory
This commit is contained in:
parent
51bfe4252d
commit
5e8fdc997a
|
@ -60,6 +60,7 @@ namespace Kernel
|
|||
static void wait_until_processors_ready();
|
||||
|
||||
static void toggle_should_print_cpu_load() { s_should_print_cpu_load = !s_should_print_cpu_load; }
|
||||
static bool get_should_print_cpu_load() { return s_should_print_cpu_load; }
|
||||
|
||||
static ProcessorID bsb_id() { return s_bsb_id; }
|
||||
static bool current_is_bsb() { return current_id() == bsb_id(); }
|
||||
|
|
|
@ -3,11 +3,14 @@
|
|||
#include <kernel/Device/FramebufferDevice.h>
|
||||
#include <kernel/FS/DevFS/FileSystem.h>
|
||||
#include <kernel/Memory/Heap.h>
|
||||
#include <kernel/Terminal/TerminalDriver.h>
|
||||
|
||||
#include <sys/framebuffer.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/sysmacros.h>
|
||||
|
||||
extern Kernel::TerminalDriver* g_terminal_driver;
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
|
@ -250,16 +253,21 @@ namespace Kernel
|
|||
{
|
||||
if (flags != MS_SYNC)
|
||||
return BAN::Error::from_errno(ENOTSUP);
|
||||
if (vaddr % (BANAN_FB_BPP / 8))
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
|
||||
if (vaddr < m_vaddr)
|
||||
vaddr = m_vaddr;
|
||||
if (vaddr + size > m_vaddr + m_size)
|
||||
size = (vaddr - m_vaddr) + m_size;
|
||||
if (auto rem = size % (BANAN_FB_BPP / 8))
|
||||
size += (BANAN_FB_BPP / 8) - rem;
|
||||
|
||||
m_framebuffer->sync_pixels_linear(
|
||||
(vaddr - m_vaddr) / (BANAN_FB_BPP / 8),
|
||||
BAN::Math::div_round_up<uint32_t>((vaddr % (BANAN_FB_BPP / 8)) + size, (BANAN_FB_BPP / 8))
|
||||
const vaddr_t start = BAN::Math::max(vaddr, m_vaddr);
|
||||
const size_t end = BAN::Math::min(vaddr + size, m_vaddr + m_size);
|
||||
if (start < end)
|
||||
{
|
||||
do_msync(
|
||||
(start - m_vaddr) / (BANAN_FB_BPP / 8),
|
||||
(end - start) / (BANAN_FB_BPP / 8)
|
||||
);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
@ -300,6 +308,53 @@ namespace Kernel
|
|||
, m_framebuffer(framebuffer)
|
||||
{ }
|
||||
|
||||
void do_msync(uint32_t first_pixel, uint32_t pixel_count)
|
||||
{
|
||||
if (!Processor::get_should_print_cpu_load())
|
||||
return m_framebuffer->sync_pixels_linear(first_pixel, pixel_count);
|
||||
|
||||
const uint32_t fb_width = m_framebuffer->width();
|
||||
|
||||
const auto& font = g_terminal_driver->font();
|
||||
|
||||
const uint32_t x = first_pixel % fb_width;
|
||||
const uint32_t y = first_pixel / fb_width;
|
||||
|
||||
const uint32_t load_w = 16 * font.width();
|
||||
const uint32_t load_h = Processor::count() * font.height();
|
||||
|
||||
if (y >= load_h || x + pixel_count <= fb_width - load_w)
|
||||
return m_framebuffer->sync_pixels_linear(first_pixel, pixel_count);
|
||||
|
||||
if (x >= fb_width - load_w && x + pixel_count <= fb_width)
|
||||
return;
|
||||
|
||||
if (x < fb_width - load_w)
|
||||
m_framebuffer->sync_pixels_linear(first_pixel, fb_width - load_w - x);
|
||||
|
||||
if (x + pixel_count > fb_width)
|
||||
{
|
||||
const uint32_t past_last_pixel = first_pixel + pixel_count;
|
||||
|
||||
first_pixel = (y + 1) * fb_width;
|
||||
pixel_count = past_last_pixel - first_pixel;
|
||||
|
||||
const uint32_t cpu_load_end = load_h * fb_width;
|
||||
|
||||
while (pixel_count && first_pixel < cpu_load_end)
|
||||
{
|
||||
m_framebuffer->sync_pixels_linear(first_pixel, BAN::Math::min(pixel_count, fb_width - load_w));
|
||||
|
||||
const uint32_t advance = BAN::Math::min(pixel_count, fb_width);
|
||||
pixel_count -= advance;
|
||||
first_pixel += advance;
|
||||
}
|
||||
|
||||
if (pixel_count)
|
||||
m_framebuffer->sync_pixels_linear(first_pixel, pixel_count);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
BAN::RefPtr<FramebufferDevice> m_framebuffer;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue