diff options
-rw-r--r-- | Kernel/Process.cpp | 34 | ||||
-rw-r--r-- | Kernel/Syscall.h | 3 | ||||
-rw-r--r-- | Libraries/LibC/mman.cpp | 12 |
3 files changed, 23 insertions, 26 deletions
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 826a59d5b6..4249f45139 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -267,22 +267,24 @@ Vector<Region*, 2> Process::split_region_around_range(const Region& source_regio return new_regions; } -void* Process::sys$mmap(const Syscall::SC_mmap_params* params) +void* Process::sys$mmap(const Syscall::SC_mmap_params* user_params) { - if (!validate_read(params, sizeof(Syscall::SC_mmap_params))) + if (!validate_read_typed(user_params)) return (void*)-EFAULT; - SmapDisabler disabler; - void* addr = (void*)params->addr; - size_t size = params->size; - int prot = params->prot; - int flags = params->flags; - int fd = params->fd; - int offset = params->offset; - const char* name = params->name; + Syscall::SC_mmap_params params; + copy_from_user(¶ms, user_params, sizeof(params)); + + void* addr = (void*)params.addr; + size_t size = params.size; + int prot = params.prot; + int flags = params.flags; + int fd = params.fd; + int offset = params.offset; - if (name && !validate_read_str(name)) + if (params.name && !validate_read(params.name, params.name_length)) return (void*)-EFAULT; + auto name = copy_string_from_user(params.name, params.name_length); if (size == 0) return (void*)-EINVAL; @@ -312,13 +314,13 @@ void* Process::sys$mmap(const Syscall::SC_mmap_params* params) if (map_purgeable) { auto vmobject = PurgeableVMObject::create_with_size(size); - region = allocate_region_with_vmobject(VirtualAddress((u32)addr), size, vmobject, 0, name ? name : "mmap (purgeable)", prot); + region = allocate_region_with_vmobject(VirtualAddress((u32)addr), size, vmobject, 0, !name.is_null() ? name : "mmap (purgeable)", prot); if (!region && (!map_fixed && addr != 0)) - region = allocate_region_with_vmobject({}, size, vmobject, 0, name ? name : "mmap (purgeable)", prot); + region = allocate_region_with_vmobject({}, size, vmobject, 0, !name.is_null() ? name : "mmap (purgeable)", prot); } else if (map_anonymous) { - region = allocate_region(VirtualAddress((u32)addr), size, name ? name : "mmap", prot, false); + region = allocate_region(VirtualAddress((u32)addr), size, !name.is_null() ? name : "mmap", prot, false); if (!region && (!map_fixed && addr != 0)) - region = allocate_region({}, size, name ? name : "mmap", prot, false); + region = allocate_region({}, size, !name.is_null() ? name : "mmap", prot, false); } else { if (offset < 0) return (void*)-EINVAL; @@ -346,7 +348,7 @@ void* Process::sys$mmap(const Syscall::SC_mmap_params* params) region->set_shared(true); if (map_stack) region->set_stack(true); - if (name) + if (!name.is_null()) region->set_name(name); return region->vaddr().as_ptr(); } diff --git a/Kernel/Syscall.h b/Kernel/Syscall.h index c8f462caad..0ef7089ce7 100644 --- a/Kernel/Syscall.h +++ b/Kernel/Syscall.h @@ -196,7 +196,8 @@ struct SC_mmap_params { int32_t flags; int32_t fd; int32_t offset; // FIXME: 64-bit off_t? - const char* name { nullptr }; + const char* name; + size_t name_length; }; struct SC_open_params { diff --git a/Libraries/LibC/mman.cpp b/Libraries/LibC/mman.cpp index 777af713b1..7bad81dd70 100644 --- a/Libraries/LibC/mman.cpp +++ b/Libraries/LibC/mman.cpp @@ -8,22 +8,16 @@ extern "C" { void* mmap(void* addr, size_t size, int prot, int flags, int fd, off_t offset) { - Syscall::SC_mmap_params params { (u32)addr, size, prot, flags, fd, offset, nullptr }; - int rc = syscall(SC_mmap, ¶ms); - if (rc < 0 && -rc < EMAXERRNO) { - errno = -rc; - return (void*)-1; - } - return (void*)rc; + return mmap_with_name(addr, size, prot, flags, fd, offset, nullptr); } void* mmap_with_name(void* addr, size_t size, int prot, int flags, int fd, off_t offset, const char* name) { - Syscall::SC_mmap_params params { (u32)addr, size, prot, flags, fd, offset, name }; + Syscall::SC_mmap_params params { (u32)addr, size, prot, flags, fd, offset, name, name ? strlen(name) : 0 }; int rc = syscall(SC_mmap, ¶ms); if (rc < 0 && -rc < EMAXERRNO) { errno = -rc; - return (void*)-1; + return MAP_FAILED; } return (void*)rc; } |