mmap(), mprotect(), munmap(): Check more stuff
This commit is contained in:
parent
c2ecc4fe95
commit
a2c05de604
@ -3,6 +3,7 @@
|
|||||||
#include "errno.h"
|
#include "errno.h"
|
||||||
#include "interrupts/Context.h"
|
#include "interrupts/Context.h"
|
||||||
#include "log/Log.h"
|
#include "log/Log.h"
|
||||||
|
#include "memory/Memory.h"
|
||||||
#include "memory/MemoryManager.h"
|
#include "memory/MemoryManager.h"
|
||||||
#include "memory/VMM.h"
|
#include "memory/VMM.h"
|
||||||
#include "misc/utils.h"
|
#include "misc/utils.h"
|
||||||
@ -50,6 +51,12 @@ void sys_mmap(Context* context, void* address, size_t size, int prot)
|
|||||||
if (address)
|
if (address)
|
||||||
{
|
{
|
||||||
kdbgln("mmap(): %ld pages at address %p, %s", size / PAGE_SIZE, address, format_prot(prot));
|
kdbgln("mmap(): %ld pages at address %p, %s", size / PAGE_SIZE, address, format_prot(prot));
|
||||||
|
if (Memory::is_kernel_address((uintptr_t)address))
|
||||||
|
{
|
||||||
|
kwarnln("munmap() failed: attempted to unmap a kernel page");
|
||||||
|
context->rax = MAP_FAIL(ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (VMM::get_physical((uint64_t)address) != (uint64_t)-1) // Address is already used.
|
if (VMM::get_physical((uint64_t)address) != (uint64_t)-1) // Address is already used.
|
||||||
{
|
{
|
||||||
kwarnln("attempt to map an already mapped address");
|
kwarnln("attempt to map an already mapped address");
|
||||||
@ -67,7 +74,7 @@ void sys_mmap(Context* context, void* address, size_t size, int prot)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
kwarnln("mmap() failed");
|
kwarnln("mmap() failed: failed to allocate physical memory");
|
||||||
context->rax = MAP_FAIL(ENOMEM);
|
context->rax = MAP_FAIL(ENOMEM);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -75,6 +82,12 @@ void sys_mmap(Context* context, void* address, size_t size, int prot)
|
|||||||
kdbgln("mmap(): %ld pages at any address, %s", Utilities::get_blocks_from_size(PAGE_SIZE, size), format_prot(prot));
|
kdbgln("mmap(): %ld pages at any address, %s", Utilities::get_blocks_from_size(PAGE_SIZE, size), format_prot(prot));
|
||||||
uint64_t ptr =
|
uint64_t ptr =
|
||||||
Scheduler::current_task()->allocator.request_virtual_pages(Utilities::get_blocks_from_size(PAGE_SIZE, size));
|
Scheduler::current_task()->allocator.request_virtual_pages(Utilities::get_blocks_from_size(PAGE_SIZE, size));
|
||||||
|
if (!ptr)
|
||||||
|
{
|
||||||
|
kwarnln("mmap() failed: failed to allocate virtual address");
|
||||||
|
context->rax = MAP_FAIL(ENOMEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
void* result = MemoryManager::get_pages_at(ptr, Utilities::get_blocks_from_size(PAGE_SIZE, size), real_flags);
|
void* result = MemoryManager::get_pages_at(ptr, Utilities::get_blocks_from_size(PAGE_SIZE, size), real_flags);
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
@ -84,7 +97,7 @@ void sys_mmap(Context* context, void* address, size_t size, int prot)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
kwarnln("mmap() failed");
|
kwarnln("mmap() failed: failed to allocate physical memory");
|
||||||
context->rax = MAP_FAIL(ENOMEM);
|
context->rax = MAP_FAIL(ENOMEM);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -111,10 +124,16 @@ void sys_munmap(Context* context, void* address, size_t size)
|
|||||||
context->rax = -EINVAL;
|
context->rax = -EINVAL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint64_t flags = VMM::get_flags((uint64_t)address);
|
if (Memory::is_kernel_address((uintptr_t)address))
|
||||||
if (!(flags & MAP_USER))
|
|
||||||
{
|
{
|
||||||
kwarnln("munmap() failed: attempted to unmap a non-existent or kernel page");
|
kwarnln("munmap() failed: attempted to unmap a kernel page");
|
||||||
|
context->rax = -EINVAL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint64_t phys = VMM::get_physical((uint64_t)address);
|
||||||
|
if (phys == (uint64_t)-1)
|
||||||
|
{
|
||||||
|
kwarnln("munmap() failed: attempted to unmap a non-existent page");
|
||||||
context->rax = -EINVAL;
|
context->rax = -EINVAL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -145,15 +164,20 @@ void sys_mprotect(Context* context, void* address, size_t size, int prot)
|
|||||||
}
|
}
|
||||||
if (!address)
|
if (!address)
|
||||||
{
|
{
|
||||||
kwarnln("mprotect() failed: attempted to unmap page 0");
|
kwarnln("mprotect() failed: attempted to protect page 0");
|
||||||
context->rax = -EINVAL;
|
context->rax = -EINVAL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (Memory::is_kernel_address((uintptr_t)address))
|
||||||
uint64_t flags = VMM::get_flags((uint64_t)address);
|
|
||||||
if (!(flags & MAP_USER))
|
|
||||||
{
|
{
|
||||||
kwarnln("mprotect() failed: attempted to protect a non-existent or kernel page");
|
kwarnln("mprotect() failed: attempted to protect a kernel page");
|
||||||
|
context->rax = -EINVAL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint64_t phys = VMM::get_physical((uint64_t)address);
|
||||||
|
if (phys == (uint64_t)-1)
|
||||||
|
{
|
||||||
|
kwarnln("mprotect() failed: attempted to protect a non-existent page");
|
||||||
context->rax = -EINVAL;
|
context->rax = -EINVAL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user