Hello,
Sorry for the delay, I could test this more than just booting, and
confirm that this fixes the numerous map entries for successive mallocs
in processes :)
Applied, thanks!
Samuel
Sergey Bugaev, le mer. 05 juil. 2023 17:16:36 +0300, a ecrit:
> This is the remaining patches from "Forward merging entries and other
> VM shenanigans" (specifically the vm_map_coalesce_entry part), with
> that one issue fixed. And here's a reproducer that fails with v1 and
> works now:
>
> Sergey
>
>
> #define _GNU_SOURCE
>
> #include <stdio.h>
> #include <mach.h>
> #include <error.h>
> #include <errno.h>
> #include <unistd.h>
> #include <spawn.h>
> #include <sys/wait.h>
>
> int
> main ()
> {
> error_t err;
> vm_offset_t offset;
> extern char **environ;
> pid_t pid;
> int *ptr;
> char *child_argv[] = { "vminfo", NULL, NULL };
>
> asprintf (&child_argv[1], "%d", getpid ());
>
> /* Allocate space for four pages. */
> err = vm_allocate (mach_task_self (), &offset, vm_page_size * 4, 1);
> if (err)
> error (1, err, "vm_allocate space");
>
> printf ("Allocated at %p\n", (void *) (offset + vm_page_size));
>
> /* Deallocate them back! */
> err = vm_deallocate (mach_task_self (), offset, vm_page_size * 4);
> if (err)
> error (1, err, "vm_deallocate space");
>
> offset += vm_page_size;
>
> /* Allocate the two pages. */
> err = vm_allocate (mach_task_self (), &offset, vm_page_size * 2, 0);
> if (err)
> error (1, err, "vm_allocate");
>
> ptr = (int *) (offset + vm_page_size);
>
> /* Realize the object. */
> *ptr = 1234;
>
> /* Deallocate the first page, and reallocate it
> with a different protection. */
> err = vm_deallocate (mach_task_self (), offset, vm_page_size);
> if (err)
> error (1, err, "vm_deallocate page");
>
> err = vm_map (mach_task_self (), &offset, vm_page_size, 0, 0,
> MACH_PORT_NULL, 0, 0, VM_PROT_ALL, VM_PROT_ALL,
> VM_INHERIT_COPY);
> if (err)
> error (1, err, "vm_map");
>
> printf ("====== Before coalescing ======\n");
> fflush (stdout);
> posix_spawn (&pid, "/bin/vminfo", NULL, NULL, child_argv, environ);
> wait (NULL);
>
> /* Coalesce the two entries back together. */
> err = vm_protect (mach_task_self (), offset,
> vm_page_size, 0, VM_PROT_DEFAULT);
> if (err)
> error (1, err, "vm_protect (VM_PROT_DEFAULT)");
>
> printf ("====== After coalescing ======\n");
> fflush (stdout);
> posix_spawn (&pid, "/bin/vminfo", NULL, NULL, child_argv, environ);
> wait (NULL);
>
> /* Check whether the data is still there. */
> printf ("%d\n", *(const int *) (offset + vm_page_size));
> }
>
--
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.