Skip to content

Commit

Permalink
Kernel: Use RDTSC instead of get_fast_random() for syscall stack noise
Browse files Browse the repository at this point in the history
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 SerenityOS#4912.
  • Loading branch information
awesomekling committed Mar 2, 2021
1 parent 05c48cc commit dce030e
Showing 1 changed file with 6 additions and 13 deletions.
19 changes: 6 additions & 13 deletions Kernel/Syscall.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <[email protected]>
* Copyright (c) 2018-2021, Andreas Kling <[email protected]>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -28,7 +28,6 @@
#include <Kernel/Arch/i386/CPU.h>
#include <Kernel/Panic.h>
#include <Kernel/Process.h>
#include <Kernel/Random.h>
#include <Kernel/ThreadTracer.h>
#include <Kernel/VM/MemoryManager.h>

Expand Down Expand Up @@ -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)
{
auto& regs = *trap->regs;
Expand All @@ -160,13 +155,11 @@ void syscall_handler(TrapFrame* trap)

// Apply a random offset in the range 0-255 to the stack pointer,
// to make kernel stacks a bit less deterministic.
// Since this is very hot code, request random data in chunks instead of
// one byte at a time. This is a noticeable speedup.
if (g_random_byte_buffer_offset == RandomByteBufferSize) {
get_fast_random_bytes(g_random_byte_buffer, RandomByteBufferSize);
g_random_byte_buffer_offset = 0;
}
auto* ptr = (char*)__builtin_alloca(g_random_byte_buffer[g_random_byte_buffer_offset++]);
u32 lsw;
u32 msw;
read_tsc(lsw, msw);

auto* ptr = (char*)__builtin_alloca(lsw & 0xff);
asm volatile(""
: "=m"(*ptr));

Expand Down

0 comments on commit dce030e

Please sign in to comment.