diff --git a/Kernel/Memory/Region.h b/Kernel/Memory/Region.h index 3383d1aaa96..f2807a4cbe6 100644 --- a/Kernel/Memory/Region.h +++ b/Kernel/Memory/Region.h @@ -102,6 +102,9 @@ public: m_mmapped_from_writable = description_was_writable; } + [[nodiscard]] bool is_initially_loaded_executable_segment() const { return m_initially_loaded_executable_segment.was_set(); } + void set_initially_loaded_executable_segment() { m_initially_loaded_executable_segment.set(); } + [[nodiscard]] bool is_write_combine() const { return m_write_combine; } ErrorOr set_write_combine(bool); @@ -250,6 +253,7 @@ private: bool m_mmapped_from_writable : 1 { false }; SetOnce m_immutable; + SetOnce m_initially_loaded_executable_segment; IntrusiveRedBlackTreeNode> m_tree_node; IntrusiveListNode m_vmobject_list_node; diff --git a/Kernel/Syscalls/execve.cpp b/Kernel/Syscalls/execve.cpp index 0e9cdccfb02..140a49337d6 100644 --- a/Kernel/Syscalls/execve.cpp +++ b/Kernel/Syscalls/execve.cpp @@ -347,6 +347,8 @@ static ErrorOr load_elf_object(Memory::AddressSpace& new_space, Open size_t rounded_range_end = TRY(Memory::page_round_up(program_header.vaddr().offset(load_offset).offset(program_header.size_in_memory()).get())); auto range_end = VirtualAddress { rounded_range_end }; auto region = TRY(new_space.allocate_region_with_vmobject(Memory::RandomizeVirtualAddress::Yes, range_base, range_end.get() - range_base.get(), program_header.alignment(), *vmobject, program_header.offset(), elf_name->view(), prot, true)); + if (program_header.is_executable()) + region->set_initially_loaded_executable_segment(); if (should_allow_syscalls == ShouldAllowSyscalls::Yes) region->set_syscall_region(true); diff --git a/Kernel/Syscalls/mmap.cpp b/Kernel/Syscalls/mmap.cpp index 72a849f165e..eb07ad386d8 100644 --- a/Kernel/Syscalls/mmap.cpp +++ b/Kernel/Syscalls/mmap.cpp @@ -542,7 +542,7 @@ ErrorOr Process::sys$annotate_mapping(Userspace address, int fla if (!region) return EINVAL; - if (!region->is_mmap()) + if (!region->is_mmap() && !region->is_initially_loaded_executable_segment()) return EINVAL; if (region->is_immutable()) return EPERM;