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:
Bananymous 2025-11-10 03:52:33 +02:00
parent 82c8eeb4be
commit f1d12c330e
4 changed files with 45 additions and 33 deletions

View File

@ -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; }

View File

@ -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)

View File

@ -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)
;

View File

@ -7,41 +7,42 @@
__BEGIN_DECLS
#define PROT_EXEC 0x01
#define PROT_NONE 0x02
#define PROT_READ 0x04
#define PROT_WRITE 0x08
#define PROT_EXEC 0x01
#define PROT_NONE 0x02
#define PROT_READ 0x04
#define PROT_WRITE 0x08
#define MAP_FIXED 0x01
#define MAP_PRIVATE 0x02
#define MAP_SHARED 0x04
#define MAP_ANONYMOUS 0x08
#define MAP_ANON MAP_ANONYMOUS
#define MAP_FIXED 0x01
#define MAP_PRIVATE 0x02
#define MAP_SHARED 0x04
#define MAP_ANONYMOUS 0x08
#define MAP_ANON MAP_ANONYMOUS
#define MAP_FIXED_NOREPLACE 0x10
#define MS_ASYNC 0x01
#define MS_INVALIDATE 0x02
#define MS_SYNC 0x04
#define MS_ASYNC 0x01
#define MS_INVALIDATE 0x02
#define MS_SYNC 0x04
#define MCL_CURRENT 0x01
#define MCL_FUTURE 0x01
#define MCL_CURRENT 0x01
#define MCL_FUTURE 0x01
#define MAP_FAILED ((void*)0)
#define POSIX_MADV_DONTNEED 1
#define POSIX_MADV_NORMAL 2
#define POSIX_MADV_RANDOM 3
#define POSIX_MADV_SEQUENTIAL 4
#define POSIX_MADV_WILLNEED 5
#define POSIX_MADV_DONTNEED 1
#define POSIX_MADV_NORMAL 2
#define POSIX_MADV_RANDOM 3
#define POSIX_MADV_SEQUENTIAL 4
#define POSIX_MADV_WILLNEED 5
#define MADV_DONTNEED POSIX_MADV_DONTNEED
#define MADV_NORMAL POSIX_MADV_NORMAL
#define MADV_RANDOM POSIX_MADV_RANDOM
#define MADV_SEQUENTIAL POSIX_MADV_SEQUENTIAL
#define MADV_WILLNEED POSIX_MADV_WILLNEED
#define MADV_DONTNEED POSIX_MADV_DONTNEED
#define MADV_NORMAL POSIX_MADV_NORMAL
#define MADV_RANDOM POSIX_MADV_RANDOM
#define MADV_SEQUENTIAL POSIX_MADV_SEQUENTIAL
#define MADV_WILLNEED POSIX_MADV_WILLNEED
#define POSIX_TYPED_MEM_ALLOCATE 0x01
#define POSIX_TYPED_MEM_ALLOCATE_CONTIG 0x02
#define POSIX_TYPED_MEM_MAP_ALLOCATABLE 0x04
#define POSIX_TYPED_MEM_ALLOCATE 0x01
#define POSIX_TYPED_MEM_ALLOCATE_CONTIG 0x02
#define POSIX_TYPED_MEM_MAP_ALLOCATABLE 0x04
#define __need_mode_t
#define __need_off_t