Sign in or sign up before continuing. Don't have an account yet? Register now to get started.
Register now

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

  1. Compile the given program to a.out
  2. 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;
}
Assignee Loading
Time tracking Loading