Kernel: Request random numbers for syscall stack noise in larger chunks (#3125)

Cuts time needed for `disasm /bin/id` from 2.5s to 1s -- identical
to the time it needs when not doing the random adjustment at all.

The downside is that it's now very easy to get the random offsets
with out-of-bounds reads, so it does make this mitigation less
effective.
This commit is contained in:
Nico Weber 2020-08-13 15:05:08 -04:00 committed by GitHub
parent 6d9b59f1b7
commit df62e54d1e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
Notes: sideshowbarker 2024-07-19 03:40:06 +09:00

View file

@ -120,6 +120,10 @@ int handle(RegisterState& regs, u32 function, u32 arg1, u32 arg2, u32 arg3)
}
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;
@ -135,7 +139,13 @@ 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.
auto* ptr = (char*)__builtin_alloca(get_fast_random<u8>());
// 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++]);
asm volatile(""
: "=m"(*ptr));