1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 12:28:12 +00:00

Kernel: Assert that copy_to/from_user() are called with user addresses

This will panic the kernel immediately if these functions are misused
so we can catch it and fix the misuse.

This patch fixes a couple of misuses:

    - create_signal_trampolines() writes to a user-accessible page
      above the 3GB address mark. We should really get rid of this
      page but that's a whole other thing.

    - CoW faults need to use copy_from_user rather than copy_to_user
      since it's the *source* pointer that points to user memory.

    - Inode faults need to use memcpy rather than copy_to_user since
      we're copying a kernel stack buffer into a quickmapped page.

This should make the copy_to/from_user() functions slightly less useful
for exploitation. Before this, they were essentially just glorified
memcpy() with SMAP disabled. :^)
This commit is contained in:
Andreas Kling 2020-01-19 09:14:14 +01:00
parent 2cd212e5df
commit f7b394e9a1
6 changed files with 33 additions and 15 deletions

View file

@ -30,6 +30,7 @@
#include <Kernel/Arch/i386/CPU.h>
#include <Kernel/Heap/kmalloc.h>
#include <Kernel/StdLib.h>
#include <Kernel/VM/MemoryManager.h>
String copy_string_from_user(const char* user_str, size_t user_str_size)
{
@ -40,16 +41,18 @@ String copy_string_from_user(const char* user_str, size_t user_str_size)
extern "C" {
void* copy_to_user(void* dest_ptr, const void* src_ptr, size_t n)
void copy_to_user(void* dest_ptr, const void* src_ptr, size_t n)
{
ASSERT(is_user_range(VirtualAddress(dest_ptr), n));
SmapDisabler disabler;
auto* ptr = memcpy(dest_ptr, src_ptr, n);
return ptr;
memcpy(dest_ptr, src_ptr, n);
}
void* copy_from_user(void* dest_ptr, const void* src_ptr, size_t n)
void copy_from_user(void* dest_ptr, const void* src_ptr, size_t n)
{
return copy_to_user(dest_ptr, src_ptr, n);
ASSERT(is_user_range(VirtualAddress(src_ptr), n));
SmapDisabler disabler;
memcpy(dest_ptr, src_ptr, n);
}
void* memcpy(void* dest_ptr, const void* src_ptr, size_t n)
@ -105,11 +108,11 @@ char* strncpy(char* dest, const char* src, size_t n)
return dest;
}
void* memset_user(void* dest_ptr, int c, size_t n)
void memset_user(void* dest_ptr, int c, size_t n)
{
ASSERT(is_user_range(VirtualAddress(dest_ptr), n));
SmapDisabler disabler;
auto* ptr = memset(dest_ptr, c, n);
return ptr;
memset(dest_ptr, c, n);
}
void* memset(void* dest_ptr, int c, size_t n)