vm_map with PROT_WRITE only
There is a call during the mmap tests of stress-ng to mmap:
mmap(NULL, page_size, PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
This results in a vm_map_entry within the task with VM_PROT_WRITE as
expected.
The write page fault raised when attempting to write to a page in this
region is merged with VM_PROT_READ (user_trap in i386/i386/trap.c) but
then when the map entry is found the protection requested does not then
match that in the entry when tested in vm_map_lookup. The mapping
request fails silently and then unsurprisingly stress-ng receives SIGSEGV.
It seems sensible to merge VM_PROT_READ when a write is required as
occurs in the trap handling.
What would the correct fix be for this scenario ? As a workaround I
applied the following:
diff --git a/vm/vm_user.c b/vm/vm_user.c
index 7f706d71..aa5fc534 100644
--- a/vm/vm_user.c
+++ b/vm/vm_user.c
@@ -348,10 +348,17 @@ kern_return_t vm_map(
*address = trunc_page(*address);
size = round_page(size);
+ if (max_protection & VM_PROT_WRITE)
+ max_protection |= VM_PROT_READ;
+
+ if (cur_protection & VM_PROT_WRITE)
+ cur_protection |= VM_PROT_READ;
+
if (!IP_VALID(memory_object)) {
object = VM_OBJECT_NULL;
offset = 0;
copy = FALSE;
+
} else if ((object = vm_object_enter(memory_object, size, FALSE))
== VM_OBJECT_NULL)
{
Reply to: