Kernel/LibC: Implement MMAP_FIXED_NOREPLACE
This is a handy thing from linux Also fix MMAP_FIXED validation and error reporting
This commit is contained in:
@@ -33,6 +33,7 @@ namespace Kernel
|
||||
bool contains(vaddr_t address) const;
|
||||
bool contains_fully(vaddr_t address, size_t size) const;
|
||||
bool overlaps(vaddr_t address, size_t size) const;
|
||||
bool is_contained_by(vaddr_t address, size_t size) const;
|
||||
|
||||
bool writable() const { return m_flags & PageTable::Flags::ReadWrite; }
|
||||
|
||||
|
||||
@@ -50,6 +50,11 @@ namespace Kernel
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MemoryRegion::is_contained_by(vaddr_t address, size_t size) const
|
||||
{
|
||||
return address <= m_vaddr && m_vaddr + m_size <= address + size;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> MemoryRegion::mprotect(PageTable::flags_t new_page_flags)
|
||||
{
|
||||
if (m_flags == new_page_flags)
|
||||
|
||||
@@ -2221,28 +2221,33 @@ namespace Kernel
|
||||
LockGuard _(m_process_lock);
|
||||
|
||||
AddressRange address_range { .start = 0x400000, .end = USERSPACE_END };
|
||||
if (args.flags & MAP_FIXED)
|
||||
if (args.flags & (MAP_FIXED | MAP_FIXED_NOREPLACE))
|
||||
{
|
||||
const vaddr_t vaddr = reinterpret_cast<vaddr_t>(args.addr);
|
||||
if (vaddr % PAGE_SIZE)
|
||||
if (vaddr == 0 || vaddr % PAGE_SIZE)
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
if (!PageTable::is_valid_pointer(vaddr))
|
||||
return BAN::Error::from_errno(ENOMEM);
|
||||
if (!PageTable::is_valid_pointer(vaddr + args.len))
|
||||
return BAN::Error::from_errno(ENOMEM);
|
||||
address_range = {
|
||||
.start = vaddr,
|
||||
.end = vaddr + args.len,
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < m_mapped_regions.size(); i++)
|
||||
if (args.flags & MAP_FIXED_NOREPLACE)
|
||||
;
|
||||
else for (size_t i = 0; i < m_mapped_regions.size(); i++)
|
||||
{
|
||||
if (!m_mapped_regions[i]->overlaps(vaddr, args.len))
|
||||
continue;
|
||||
if (!m_mapped_regions[i]->contains_fully(vaddr, args.len))
|
||||
if (!m_mapped_regions[i]->is_contained_by(vaddr, args.len))
|
||||
derrorln("VERY BROKEN MAP_FIXED UNMAP");
|
||||
m_mapped_regions[i]->wait_not_pinned();
|
||||
m_mapped_regions.remove(i--);
|
||||
}
|
||||
}
|
||||
|
||||
if (const vaddr_t vaddr = reinterpret_cast<vaddr_t>(args.addr); vaddr == 0)
|
||||
else if (const vaddr_t vaddr = reinterpret_cast<vaddr_t>(args.addr); vaddr == 0)
|
||||
;
|
||||
else if (vaddr % PAGE_SIZE)
|
||||
;
|
||||
|
||||
Reference in New Issue
Block a user