Kernel: Use RDTSC instead of get_fast_random() for syscall stack noise

This was the original approach before we switched to get_fast_random()
which wasn't fast enough, so we added a buffer.

Unfortunately that buffer is racy and we can actually skid past the end
of it and continue fetching "random" offsets from the adjacent memory
for a while, until we run out of kernel data segment and trip a fault.

Instead of making this even more convoluted, let's just go back to the
pleasantly simple (RDTSC & 0xff) approach. :^)

Fixes #4912.
This commit is contained in:
Andreas Kling 2021-03-02 13:57:34 +01:00
parent 05c48cc8d8
commit dce030eefc
Notes: sideshowbarker 2024-07-18 21:46:29 +09:00

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -28,7 +28,6 @@
#include <Kernel/Arch/i386/CPU.h> #include <Kernel/Arch/i386/CPU.h>
#include <Kernel/Panic.h> #include <Kernel/Panic.h>
#include <Kernel/Process.h> #include <Kernel/Process.h>
#include <Kernel/Random.h>
#include <Kernel/ThreadTracer.h> #include <Kernel/ThreadTracer.h>
#include <Kernel/VM/MemoryManager.h> #include <Kernel/VM/MemoryManager.h>
@ -137,10 +136,6 @@ KResultOr<FlatPtr> handle(RegisterState& regs, FlatPtr function, FlatPtr arg1, F
} }
constexpr int RandomByteBufferSize = 256;
u8 g_random_byte_buffer[RandomByteBufferSize];
int g_random_byte_buffer_offset = RandomByteBufferSize;
void syscall_handler(TrapFrame* trap) void syscall_handler(TrapFrame* trap)
{ {
auto& regs = *trap->regs; auto& regs = *trap->regs;
@ -160,13 +155,11 @@ void syscall_handler(TrapFrame* trap)
// Apply a random offset in the range 0-255 to the stack pointer, // Apply a random offset in the range 0-255 to the stack pointer,
// to make kernel stacks a bit less deterministic. // to make kernel stacks a bit less deterministic.
// Since this is very hot code, request random data in chunks instead of u32 lsw;
// one byte at a time. This is a noticeable speedup. u32 msw;
if (g_random_byte_buffer_offset == RandomByteBufferSize) { read_tsc(lsw, msw);
get_fast_random_bytes(g_random_byte_buffer, RandomByteBufferSize);
g_random_byte_buffer_offset = 0; auto* ptr = (char*)__builtin_alloca(lsw & 0xff);
}
auto* ptr = (char*)__builtin_alloca(g_random_byte_buffer[g_random_byte_buffer_offset++]);
asm volatile("" asm volatile(""
: "=m"(*ptr)); : "=m"(*ptr));