user-mode: mremap doesn't handle old_size == 0 correctly
Host environment
-
Operating system:
Ubuntu 24.04.3 LTS
-
OS/kernel version:
-
Architecture:
Linux floitsch 6.8.0-79-generic #79 (closed)-Ubuntu SMP PREEMPT_DYNAMIC Tue Aug 12 14:42:46 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
-
QEMU flavor:
qemu-riscv64
-
QEMU version:
git 6a9fa5ef
-
QEMU command line:
./qemu-riscv64 a.out
Emulated/Virtualized environment
-
Operating system:
Linux
-
OS/kernel version:
-
Architecture:
riscv64, but should be the same on others.
Description of problem
It looks like user mremap doesn't implement the special case when old-length equals 0.
Steps to reproduce
- Compile the given program to
a.out - Run it with any user emulation (architecture doesn't seem to matter): ./qemu-xxx ./a.out
Additional information
From the docs:
If the value of old_size is zero, and old_address refers to a shareable mapping (see the description of MAP_SHARED in mmap(2)), then mremap() will create a new mapping of the same pages. new_size will be the size of the new mapping and the location of the new mapping may be specified with new_address; see the description of MREMAP_FIXED below. If a new mapping is requested via this method, then the MREMAP_MAYMOVE flag must also be specified.
#define _GNU_SOURCE
#include <sys/mman.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
size_t page_size = getpagesize();
// Create a shared mapping
void *shared_ptr = mmap(NULL, page_size, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (shared_ptr == MAP_FAILED) {
perror("mmap failed");
return 1;
}
// Test mremap with old_size=0 on the shared mapping
void *new_ptr = mremap(shared_ptr, 0, page_size * 2, MREMAP_MAYMOVE);
if (new_ptr == MAP_FAILED) {
perror("mremap with old_size=0 failed");
munmap(shared_ptr, page_size);
return 1;
}
printf("SUCCESS: mremap with old_size=0 worked\n");
munmap(new_ptr, page_size * 2);
return 0;
}