Home > database >  MAP_FIXED_NOREPLACE not supported on Ubuntu 20
MAP_FIXED_NOREPLACE not supported on Ubuntu 20

Time:10-28

When I run this code I get "mmap: Operation not supported", according to mmap man that's because one of the flags is invalid (validated by MAP_SHARED_VALIDATE). The "bad" flag is MAP_FIXED_NOREPLACE

#include <fcntl.h>
#include <errno.h>
#include <sys/mman.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char** argv)
{
    int fd_addr = open("test", O_CREAT | O_RDWR);
    if (fd_addr == -1) {
        std::cout << "open: " << strerror(errno) << "\n";
        return EXIT_FAILURE;
    }
    if (ftruncate(fd_addr, 100) == -1) {
        std::cout << "ftruncate: " << strerror(errno) << "\n";
        return EXIT_FAILURE;
    }

    auto mem =mmap((void*)0x7f4b1618a000, 1, PROT_READ | PROT_WRITE, MAP_FIXED_NOREPLACE | MAP_SHARED_VALIDATE | MAP_LOCKED, fd_addr, 0);
    if (mem == MAP_FAILED) {
        std::cout << "mmap: " << strerror(errno) << "\n";
        return EXIT_FAILURE;
    }
}

Any sane ideas what that could be and how to figure out what the problem is? I use Ubuntu 20 (kernel 5.4.0-131-generic) and g -11 (with glibc 2.31)

g  -11 (Ubuntu 11.1.0-1ubuntu1~20.04) 11.1.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


ldd (Ubuntu GLIBC 2.31-0ubuntu9.9) 2.31
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.

Replacing MAP_FIXED_NOREPLACE with MAP_FIXED works just fine. Compiling like that:

g  -11 -g0 -Ofast -DNDEBUG -Wall -Werror --std=c  2a -march=native -flto -fno-rtti main.cpp -pthread -lrt

CodePudding user response:

The only way to answer your question is to look at the source. Taking an excerpt from do_mmap:

switch (flags & MAP_TYPE) {
        case MAP_SHARED:
            /*
             * Force use of MAP_SHARED_VALIDATE with non-legacy
             * flags. E.g. MAP_SYNC is dangerous to use with
             * MAP_SHARED as you don't know which consistency model
             * you will get. We silently ignore unsupported flags
             * with MAP_SHARED to preserve backward compatibility.
             */
            flags &= LEGACY_MAP_MASK;
            fallthrough;
        case MAP_SHARED_VALIDATE:
            if (flags & ~flags_mask)
                return -EOPNOTSUPP;

and comparing your flags against those in LEGACY_MAP_MASK, it becomes evident that MAP_FIXED_NOREPLACE is not part of LEGACY_MAP_MASK, which returns the "operation not supported" error you report.

In this case, the MAP_FIXED_NOREPLACE bits result in an extra check up front and otherwise behaves as MAP_FIXED.

Long story short: in this situation you can replace MAP_SHARED_VALIDATE with MAP_SHARED without loss of functionality.

Doing what you suggested (MAP_FIXED_NOREPLACE to MAP_FIXED) has the potential of accidentally creating overlapping memory mappings.

  • Related