mmap

title: mmap(2)

text:
# mmap(2)

## NAME
mmap, munmap - map or unmap files or devices into memory

## LIBRARY
Standard C library (libc, -lc)

## SYNOPSIS

```
#include <sys/mman.h>
```

```
void *mmap(void addr[.length], size_t length, int prot, int flags,
           int fd, off_t offset);
int munmap(void addr[.length], size_t length);
```

See NOTES for information on feature test macro requirements.

## DESCRIPTION
mmap() creates a new mapping in the virtual address space of the calling process. The starting address for the new mapping is specified in addr. The length argument specifies the length of the mapping (which must be greater than 0).

If addr is NULL, then the kernel chooses the (page-aligned) address at which to create the mapping; this is the most portable method of creating a new mapping. If addr is not NULL, then the kernel takes it as a hint about where to place the mapping; on Linux, the kernel will pick a nearby page boundary (but always above or equal to the value specified by /proc/sys/vm/mmap_min_addr) and attempt to create the mapping there. If another mapping already exists there, the kernel picks a new address that may or may not depend on the hint. The address of the new mapping is returned as the result of the call.

The contents of a file mapping (as opposed to an anonymous mapping; see MAP_ANONYMOUS below), are initialized using length bytes starting at offset offset in the file (or other object) referred to by the file descriptor fd. offset must be a multiple of the page size as returned by sysconf(_SC_PAGE_SIZE).

After the mmap() call has returned, the file descriptor, fd, can be closed immediately without invalidating the mapping.

The prot argument describes the desired memory protection of the mapping (and must not conflict with the open mode of the file). It is either PROT_NONE or the bitwise OR of one or more of the following flags:

PROT_EXEC

Pages may be executed.

PROT_READ

Pages may be read.

PROT_WRITE

Pages may be written.

PROT_NONE

Pages may not be accessed.

### The flags argument
The flags argument determines whether updates to the mapping are visible to other processes mapping the same region, and whether updates are carried through to the underlying file. This behavior is determined by including exactly one of the following values in flags:

MAP_SHARED

Share this mapping. Updates to the mapping are visible to other processes mapping the same region, and (in the case of file-backed mappings) are carried through to the underlying file. (To precisely control when updates are carried through to the underlying file requires the use of msync(2).)

MAP_SHARED_VALIDATE (since Linux 4.15)

This flag provides the same behavior as MAP_SHARED except that MAP_SHARED mappings ignore unknown flags in flags. By contrast, when creating a mapping using MAP_SHARED_VALIDATE, the kernel verifies all passed flags are known and fails the mapping with the error EOPNOTSUPP for unknown flags. This mapping type is also required to be able to use some mapping flags (e.g., MAP_SYNC).

MAP_PRIVATE

Create a private copy-on-write mapping. Updates to the mapping are not visible to other processes mapping the same file, and are not carried through to the underlying file. It is unspecified whether changes made to the file after the mmap() call are visible in the mapped region.

Both MAP_SHARED and MAP_PRIVATE are described in POSIX.1-2001 and POSIX.1-2008. MAP_SHARED_VALIDATE is a Linux extension.

In addition, zero or more of the following values can be ORed in flags:

MAP_32BIT (since Linux 2.4.20, 2.6)

Put the mapping into the first 2 Gigabytes of the process address space. This flag is supported only on x86-64, for 64-bit programs. It was added to allow thread stacks to be allocated somewhere in the first 2 GB of memory, so as to improve context-switch performance on some early 64-bit processors. Modern x86-64 processors no longer have this performance problem, so use of this flag is not required on those systems. The MAP_32BIT flag is ignored when MAP_FIXED is set.

MAP_ANON

Synonym for MAP_ANONYMOUS; provided for compatibility with other implementations.

MAP_ANONYMOUS

The mapping is not backed by any file; its contents are initialized to zero. The fd argument is ignored; however, some implementations require fd to be -1 if MAP_ANONYMOUS (or MAP_ANON) is specified, and portable applications should ensure this. The offset argument should be zero. Support for MAP_ANONYMOUS in conjunction with MAP_SHARED was added in Linux 2.4.

MAP_DENYWRITE

This flag is ignored. (Long ago—Linux 2.0 and earlier—it signaled that attempts to write to the underlying file should fail with ETXTBSY. But this was a source of denial-of-service attacks.)

MAP_EXECUTABLE

This flag is ignored.

MAP_FILE

Compatibility flag. Ignored.

MAP_FIXED

Don't interpret addr as a hint: place the mapping at exactly that address. addr must be suitably aligned: for most architectures a multiple of the page size is sufficient; however, some architectures may impose additional restrictions. If the memory region specified by addr and length overlaps pages of any existing mapping(s), then the overlapped part of the existing mapping(s) will be discarded. If the specified address cannot be used, mmap() will fail.

Software that aspires to be portable should use the MAP_FIXED flag with care, keeping in mind that the exact layout of a process's memory mappings is allowed to change significantly between Linux versions, C library versions, and operating system releases. Carefully read the discussion of this flag in NOTES!

MAP_FIXED_NOREPLACE (since Linux 4.17)

This flag provides behavior that is similar to MAP_FIXED with respect to the addr enforcement, but differs in that MAP_FIXED_NOREPLACE never clobbers a preexisting mapped range. If the requested range would collide with an existing mapping, then this call fails with the error EEXIST. This flag can therefore be used as a way to atomically (with respect to other threads) attempt to map an address range: one thread will succeed; all others will report failure.

Note that older kernels which do not recognize the MAP_FIXED_NOREPLACE flag will typically (upon detecting a collision with a preexisting mapping) fall back to a “non-MAP_FIXED” type of behavior: they will return an address that is different from the requested address. Therefore, backward-compatible software should check the returned address against the requested address.

MAP_GROWSDOWN

This flag is used for stacks. It indicates to the kernel virtual memory system that the mapping should extend downward in memory. The return address is one page lower than the memory area that is actually created in the process's virtual address space. Touching an address in the "guard" page below the mapping will cause the mapping to grow by a page. This growth can be repeated until the mapping grows to within a page of the high end of the next lower mapping, at which point touching the "guard" page will result in a SIGSEGV signal.

MAP_HUGETLB (since Linux 2.6.32)

Allocate the mapping using "huge" pages. See the Linux kernel source file Documentation/admin-guide/mm/hugetlbpage.rst for further information, as well as NOTES, below.

MAP_HUGE_2MB, MAP_HUGE_1GB (since Linux 3.8)

Used in conjunction with MAP_HUGETLB to select alternative hugetlb page sizes (respectively, 2 MB and 1 GB) on systems that support multiple hugetlb page sizes.

More generally, the desired huge page size can be configured by encoding the base-2 logarithm of the desired page size in the six bits at the offset MAP_HUGE_SHIFT. (A value of zero in this bit field provides the default huge page size; the default huge page size can be discovered via the Hugepagesize field exposed by /proc/meminfo.) Thus, the above two constants are defined as:

```
#define MAP_HUGE_2MB    (21 << MAP_HUGE_SHIFT)
#define MAP_HUGE_1GB    (30 << MAP_HUGE_SHIFT)

```

The range of huge page sizes that are supported by the system can be discovered by listing the subdirectories in /sys/kernel/mm/hugepages.

MAP_LOCKED (since Linux 2.5.37)

Mark the mapped region to be locked in the same way as mlock(2). This implementation will try to populate (prefault) the whole range but the mmap() call doesn't fail with ENOMEM if this fails. Therefore major faults might happen later on. So the semantic is not as strong as mlock(2). One should use mmap() plus mlock(2) when major faults are not acceptable after the initialization of the mapping. The MAP_LOCKED flag is ignored in older kernels.

MAP_NONBLOCK (since Linux 2.5.46)

This flag is meaningful only in conjunction with MAP_POPULATE. Don't perform read-ahead: create page tables entries only for pages that are already present in RAM. Since Linux 2.6.23, this flag causes MAP_POPULATE to do nothing. One day, the combination of MAP_POPULATE and MAP_NONBLOCK may be reimplemented.

MAP_NORESERVE

Do not reserve swap space for this mapping. When swap space is reserved, one has the guarantee that it is possible to modify the mapping. When swap space is not reserved one might get SIGSEGV upon a write if no physical memory is available. See also the discussion of the file /proc/sys/vm/overcommit_memory in proc(5). Before Linux 2.6, this flag had effect only for private writable mappings.

MAP_POPULATE (since Linux 2.5.46)

Populate (prefault) page tables for a mapping. For a file mapping, this causes read-ahead on the file. This will help to reduce blocking on page faults later. The mmap() call doesn't fail if the mapping cannot be populated (for example, due to limitations on the number of mapped huge pages when using MAP_HUGETLB). Support for MAP_POPULATE in conjunction with private mappings was added in Linux 2.6.23.

MAP_STACK (since Linux 2.6.27)

Allocate the mapping at an address suitable for a process or thread stack.

This flag is currently a no-op on Linux. However, by employing this flag, applications can ensure that they transparently obtain support if the flag is implemented in the future. Thus, it is used in the glibc threading implementation to allow for the fact that some architectures may (later) require special treatment for stack allocations. A further reason to employ this flag is portability: MAP_STACK exists (and has an effect) on some other systems (e.g., some of the BSDs).

MAP_SYNC (since Linux 4.15)

This flag is available only with the MAP_SHARED_VALIDATE mapping type; mappings of type MAP_SHARED will silently ignore this flag. This flag is supported only for files supporting DAX (direct mapping of persistent memory). For other files, creating a mapping with this flag results in an EOPNOTSUPP error.

Shared file mappings with this flag provide the guarantee that while some memory is mapped writable in the address space of the process, it will be visible in the same file at the same offset even after the system crashes or is rebooted. In conjunction with the use of appropriate CPU instructions, this provides users of such mappings with a more efficient way of making data modifications persistent.

MAP_UNINITIALIZED (since Linux 2.6.33)

Don't clear anonymous pages. This flag is intended to improve performance on embedded devices. This flag is honored only if the kernel was configured with the CONFIG_MMAP_ALLOW_UNINITIALIZED option. Because of the security implications, that option is normally enabled only on embedded devices (i.e., devices where one has complete control of the contents of user memory).

Of the above flags, only MAP_FIXED is specified in POSIX.1-2001 and POSIX.1-2008. However, most systems also support MAP_ANONYMOUS (or its synonym MAP_ANON).

### munmap()
The munmap() system call deletes the mappings for the specified address range, and causes further references to addresses within the range to generate invalid memory references. The region is also automatically unmapped when the process is terminated. On the other hand, closing the file descriptor does not unmap the region.

The address addr must be a multiple of the page size (but length need not be). All pages containing a part of the indicated range are unmapped, and subsequent references to these pages will generate SIGSEGV. It is not an error if the indicated range does not contain any mapped pages.

## RETURN VALUE
On success, mmap() returns a pointer to the mapped area. On error, the value MAP_FAILED (that is, (void *) -1) is returned, and errno is set to indicate the error.

On success, munmap() returns 0. On failure, it returns -1, and errno is set to indicate the error (probably to EINVAL).

## ERRORS
EACCES

A file descriptor refers to a non-regular file. Or a file mapping was requested, but fd is not open for reading. Or MAP_SHARED was requested and PROT_WRITE is set, but fd is not open in read/write (O_RDWR) mode. Or PROT_WRITE is set, but the file is append-only.

EAGAIN

The file has been locked, or too much memory has been locked (see setrlimit(2)).

EBADF

fd is not a valid file descriptor (and MAP_ANONYMOUS was not set).

EEXIST

MAP_FIXED_NOREPLACE was specified in flags, and the range covered by addr and length clashes with an existing mapping.

EINVAL

We don't like addr, length, or offset (e.g., they are too large, or not aligned on a page boundary).

EINVAL

(since Linux 2.6.12) length was 0.

EINVAL

flags contained none of MAP_PRIVATE, MAP_SHARED, or MAP_SHARED_VALIDATE.

ENFILE

The system-wide limit on the total number of open files has been reached.

ENODEV

The underlying filesystem of the specified file does not support memory mapping.

ENOMEM

No memory is available.

ENOMEM

The process's maximum number of mappings would have been exceeded. This error can also occur for munmap(), when unmapping a region in the middle of an existing mapping, since this results in two smaller mappings on either side of the region being unmapped.

ENOMEM

(since Linux 4.7) The process's RLIMIT_DATA limit, described in getrlimit(2), would have been exceeded.

ENOMEM

We don't like addr, because it exceeds the virtual address space of the CPU.

EOVERFLOW

On 32-bit architecture together with the large file extension (i.e., using 64-bit off_t): the number of pages used for length plus number of pages used for offset would overflow unsigned long (32 bits).

EPERM

The prot argument asks for PROT_EXEC but the mapped area belongs to a file on a filesystem that was mounted no-exec.

EPERM

The operation was prevented by a file seal; see fcntl(2).

EPERM

The MAP_HUGETLB flag was specified, but the caller was not privileged (did not have the CAP_IPC_LOCK capability) and is not a member of the sysctl_hugetlb_shm_group group; see the description of /proc/sys/vm/sysctl_hugetlb_shm_group in

ETXTBSY

MAP_DENYWRITE was set but the object specified by fd is open for writing.

Use of a mapped region can result in these signals:

SIGSEGV

Attempted write into a region mapped as read-only.

SIGBUS

Attempted access to a page of the buffer that lies beyond the end of the mapped file. For an explanation of the treatment of the bytes in the page that corresponds to the end of a mapped file that is not a multiple of the page size, see NOTES.

## ATTRIBUTES
For an explanation of the terms used in this section, see attributes(7).

Interface

Attribute

Value

mmap (), munmap ()

Thread safety

MT-Safe

## VERSIONS
On some hardware architectures (e.g., i386), PROT_WRITE implies PROT_READ. It is architecture dependent whether PROT_READ implies PROT_EXEC or not. Portable programs should always set PROT_EXEC if they intend to execute code in the new mapping.

The portable way to create a mapping is to specify addr as 0 (NULL), and omit MAP_FIXED from flags. In this case, the system chooses the address for the mapping; the address is chosen so as not to conflict with any existing mapping, and will not be 0. If the MAP_FIXED flag is specified, and addr is 0 (NULL), then the mapped address will be 0 (NULL).

Certain flags constants are defined only if suitable feature test macros are defined (possibly by default): _DEFAULT_SOURCE with glibc 2.19 or later; or _BSD_SOURCE or _SVID_SOURCE in glibc 2.19 and earlier. (Employing _GNU_SOURCE also suffices, and requiring that macro specifically would have been more logical, since these flags are all Linux-specific.) The relevant flags are: MAP_32BIT, MAP_ANONYMOUS (and the synonym MAP_ANON), MAP_DENYWRITE, MAP_EXECUTABLE, MAP_FILE, MAP_GROWSDOWN, MAP_HUGETLB, MAP_LOCKED, MAP_NONBLOCK, MAP_NORESERVE, MAP_POPULATE, and MAP_STACK.

### C library/kernel differences
This page describes the interface provided by the glibc mmap() wrapper function. Originally, this function invoked a system call of the same name. Since Linux 2.4, that system call has been superseded by mmap2(2), and nowadays the glibc mmap() wrapper function invokes mmap2(2) with a suitably adjusted value for offset.

## STANDARDS
POSIX.1-2008.

## HISTORY
POSIX.1-2001, SVr4, 4.4BSD.

On POSIX systems on which mmap(), msync(2), and munmap() are available, _POSIX_MAPPED_FILES is defined in <unistd.h> to a value greater than 0. (See also sysconf(3).)

## NOTES
Memory mapped by mmap() is preserved across fork(2), with the same attributes.

A file is mapped in multiples of the page size. For a file that is not a multiple of the page size, the remaining bytes in the partial page at the end of the mapping are zeroed when mapped, and modifications to that region are not written out to the file. The effect of changing the size of the underlying file of a mapping on the pages that correspond to added or removed regions of the file is unspecified.

An application can determine which pages of a mapping are currently resident in the buffer/page cache using mincore(2).

### Using MAP_FIXED safely
The only safe use for MAP_FIXED is where the address range specified by addr and length was previously reserved using another mapping; otherwise, the use of MAP_FIXED is hazardous because it forcibly removes preexisting mappings, making it easy for a multithreaded process to corrupt its own address space.

For example, suppose that thread A looks through /proc/pid/maps in order to locate an unused address range that it can map using MAP_FIXED, while thread B simultaneously acquires part or all of that same address range. When thread A subsequently employs mmap(MAP_FIXED), it will effectively clobber the mapping that thread B created. In this scenario, thread B need not create a mapping directly; simply making a library call that, internally, uses dlopen(3) to load some other shared library, will suffice. The dlopen(3) call will map the library into the process's address space. Furthermore, almost any library call may be implemented in a way that adds memory mappings to the address space, either with this technique, or by simply allocating memory. Examples include brk(2), malloc(3), pthread_create(3), and the PAM libraries http://www.linux-pam.org.

Since Linux 4.17, a multithreaded program can use the MAP_FIXED_NOREPLACE flag to avoid the hazard described above when attempting to create a mapping at a fixed address that has not been reserved by a preexisting mapping.

### Timestamps changes for file-backed mappings
For file-backed mappings, the st_atime field for the mapped file may be updated at any time between the mmap() and the corresponding unmapping; the first reference to a mapped page will update the field if it has not been already.

The st_ctime and st_mtime field for a file mapped with PROT_WRITE and MAP_SHARED will be updated after a write to the mapped region, and before a subsequent msync(2) with the MS_SYNC or MS_ASYNC flag, if one occurs.

### Huge page (Huge TLB) mappings
For mappings that employ huge pages, the requirements for the arguments of mmap() and munmap() differ somewhat from the requirements for mappings that use the native system page size.

For mmap(), offset must be a multiple of the underlying huge page size. The system automatically aligns length to be a multiple of the underlying huge page size.

For munmap(), addr, and length must both be a multiple of the underlying huge page size.

## BUGS
On Linux, there are no guarantees like those suggested above under MAP_NORESERVE. By default, any process can be killed at any moment when the system runs out of memory.

Before Linux 2.6.7, the MAP_POPULATE flag has effect only if prot is specified as PROT_NONE.

SUSv3 specifies that mmap() should fail if length is 0. However, before Linux 2.6.12, mmap() succeeded in this case: no mapping was created and the call returned addr. Since Linux 2.6.12, mmap() fails with the error EINVAL for this case.

POSIX specifies that the system shall always zero fill any partial page at the end of the object and that system will never write any modification of the object beyond its end. On Linux, when you write data to such partial page after the end of the object, the data stays in the page cache even after the file is closed and unmapped and even though the data is never written to the file itself, subsequent mappings may see the modified content. In some cases, this could be fixed by calling msync(2) before the unmap takes place; however, this doesn't work on tmpfs(5) (for example, when using the POSIX shared memory interface documented in shm_overview(7)).

## EXAMPLES
The following program prints part of the file specified in its first command-line argument to standard output. The range of bytes to be printed is specified via offset and length values in the second and third command-line arguments. The program creates a memory mapping of the required pages of the file and then uses write(2) to output the desired bytes.

### Program source

```
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#define handle_error(msg) \

    do { perror(msg); exit(EXIT_FAILURE); } while (0)
int
main(int argc, char *argv[])
{

    int          fd;

    char         *addr;

    off_t        offset, pa_offset;

    size_t       length;

    ssize_t      s;

    struct stat  sb;

    if (argc < 3 || argc > 4) {

        fprintf(stderr, "%s file offset [length]\n", argv[0]);

        exit(EXIT_FAILURE);

    }

    fd = open(argv[1], O_RDONLY);

    if (fd == -1)

        handle_error("open");

    if (fstat(fd, &sb) == -1)           /* To obtain file size */

        handle_error("fstat");

    offset = atoi(argv[2]);

    pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE) - 1);

        /* offset for mmap() must be page aligned */

    if (offset >= sb.st_size) {

        fprintf(stderr, "offset is past end of file\n");

        exit(EXIT_FAILURE);

    }

    if (argc == 4) {

        length = atoi(argv[3]);

        if (offset + length > sb.st_size)

            length = sb.st_size - offset;

                /* Can't display bytes past end of file */

    } else {    /* No length arg ==> display to end of file */

        length = sb.st_size - offset;

    }

    addr = mmap(NULL, length + offset - pa_offset, PROT_READ,

                MAP_PRIVATE, fd, pa_offset);

    if (addr == MAP_FAILED)

        handle_error("mmap");

    s = write(STDOUT_FILENO, addr + offset - pa_offset, length);

    if (s != length) {

        if (s == -1)

            handle_error("write");

        fprintf(stderr, "partial write");

        exit(EXIT_FAILURE);

    }

    munmap(addr, length + offset - pa_offset);

    close(fd);

    exit(EXIT_SUCCESS);
}
```

## SEE ALSO
ftruncate(2), getpagesize(2), memfd_create(2), mincore(2), mlock(2), mmap2(2), mprotect(2), mremap(2), msync(2), remap_file_pages(2), setrlimit(2), shmat(2), userfaultfd(2), shm_open(3), shm_overview(7)

The descriptions of the following files in proc(5): /proc/pid/maps, /proc/pid/map_files, and /proc/pid/smaps.

B.O. Gallmeister, POSIX.4, O'Reilly, pp. 128–129 and 389–391.


package: man-pages

title: mmap2(2)

summary: map files or devices into memory

text:
# mmap2(2)

## NAME
mmap2 - map files or devices into memory

## LIBRARY
Standard C library (libc, -lc)

## SYNOPSIS

```
#include <sys/mman.h>    /* Definition of MAP_* and PROT_* constants */
#include <sys/syscall.h> /* Definition of SYS_* constants */
#include <unistd.h>
```

```
void *syscall(SYS_mmap2, unsigned long addr, unsigned long length,
              unsigned long prot, unsigned long flags,
              unsigned long fd, unsigned long pgoffset);
```

## DESCRIPTION
This is probably not the system call that you are interested in; instead, see mmap(2), which describes the glibc wrapper function that invokes this system call.

The mmap2() system call provides the same interface as mmap(2), except that the final argument specifies the offset into the file in 4096-byte units (instead of bytes, as is done by mmap(2)). This enables applications that use a 32-bit off_t to map large files (up to 2^44 bytes).

## RETURN VALUE
On success, mmap2() returns a pointer to the mapped area. On error, -1 is returned and errno is set to indicate the error.

## ERRORS
EFAULT

Problem with getting the data from user space.

EINVAL

(Various platforms where the page size is not 4096 bytes.) offset * 4096 is not a multiple of the system page size.

mmap2() can also return any of the errors described in mmap(2).

## VERSIONS
On architectures where this system call is present, the glibc mmap() wrapper function invokes this system call rather than the mmap(2) system call.

This system call does not exist on x86-64.

On ia64, the unit for offset is actually the system page size, rather than 4096 bytes.

## STANDARDS
Linux.

## HISTORY
Linux 2.3.31.

## SEE ALSO
getpagesize(2), mmap(2), mremap(2), msync(2), shm_open(3)

branch: sisyphus


title: modify_ldt(2)

summary: get or set a per-process LDT entry

text:
# modify_ldt(2)

## NAME
modify_ldt - get or set a per-process LDT entry

## LIBRARY
Standard C library (libc, -lc)

## SYNOPSIS

```
#include <asm/ldt.h>         /* Definition of struct user_desc */
#include <sys/syscall.h>     /* Definition of SYS_* constants */
#include <unistd.h>
```

```
int syscall(SYS_modify_ldt, int func, void ptr[.bytecount],
            unsigned long bytecount);
```

Note: glibc provides no wrapper for modify_ldt(), necessitating the use of syscall(2).

## DESCRIPTION
modify_ldt() reads or writes the local descriptor table (LDT) for a process. The LDT is an array of segment descriptors that can be referenced by user code. Linux allows processes to configure a per-process (actually per-mm) LDT. For more information about the LDT, see the Intel Software Developer's Manual or the AMD Architecture Programming Manual.

When func is 0, modify_ldt() reads the LDT into the memory pointed to by ptr. The number of bytes read is the smaller of bytecount and the actual size of the LDT, although the kernel may act as though the LDT is padded with additional trailing zero bytes. On success, modify_ldt() will return the number of bytes read.

When func is 1 or 0x11, modify_ldt() modifies the LDT entry indicated by ptr->entry_number. ptr points to a user_desc structure and bytecount must equal the size of this structure.

The user_desc structure is defined in <asm/ldt.h> as:

```
struct user_desc {

    unsigned int  entry_number;

    unsigned int  base_addr;

    unsigned int  limit;

    unsigned int  seg_32bit:1;

    unsigned int  contents:2;

    unsigned int  read_exec_only:1;

    unsigned int  limit_in_pages:1;

    unsigned int  seg_not_present:1;

    unsigned int  useable:1;
};
```

In Linux 2.4 and earlier, this structure was named modify_ldt_ldt_s.

The contents field is the segment type (data, expand-down data, non-conforming code, or conforming code). The other fields match their descriptions in the CPU manual, although modify_ldt() cannot set the hardware-defined "accessed" bit described in the CPU manual.

A user_desc is considered "empty" if read_exec_only and seg_not_present are set to 1 and all of the other fields are 0. An LDT entry can be cleared by setting it to an "empty" user_desc or, if func is 1, by setting both base and limit to 0.

A conforming code segment (i.e., one with contents==3) will be rejected if func is 1 or if seg_not_present is 0.

When func is 2, modify_ldt() will read zeros. This appears to be a leftover from Linux 2.4.

## RETURN VALUE
On success, modify_ldt() returns either the actual number of bytes read (for reading) or 0 (for writing). On failure, modify_ldt() returns -1 and sets errno to indicate the error.

## ERRORS
EFAULT

ptr points outside the address space.

EINVAL

ptr is 0, or func is 1 and bytecount is not equal to the size of the structure user_desc, or func is 1 or 0x11 and the new LDT entry has invalid values.

ENOSYS

func is neither 0, 1, 2, nor 0x11.

## STANDARDS
Linux.

## NOTES
modify_ldt() should not be used for thread-local storage, as it slows down context switches and only supports a limited number of threads. Threading libraries should use set_thread_area(2) or arch_prctl(2) instead, except on extremely old kernels that do not support those system calls.

The normal use for modify_ldt() is to run legacy 16-bit or segmented 32-bit code. Not all kernels allow 16-bit segments to be installed, however.

Even on 64-bit kernels, modify_ldt() cannot be used to create a long mode (i.e., 64-bit) code segment. The undocumented field "lm" in user_desc is not useful, and, despite its name, does not result in a long mode segment.

## BUGS
On 64-bit kernels before Linux 3.19, setting the "lm" bit in user_desc prevents the descriptor from being considered empty. Keep in mind that the "lm" bit does not exist in the 32-bit headers, but these buggy kernels will still notice the bit even when set in a 32-bit process.

## SEE ALSO
arch_prctl(2), set_thread_area(2), vm86(2)


mount

title: mount(2)

summary: mount filesystem

text:
# mount(2)

## NAME
mount - mount filesystem

## LIBRARY
Standard C library (libc, -lc)

## SYNOPSIS

```
#include <sys/mount.h>
```

```
int mount(const char *source, const char *target,
          const char *filesystemtype, unsigned long mountflags,
          const void *_Nullable data);
```

## DESCRIPTION
mount() attaches the filesystem specified by source (which is often a pathname referring to a device, but can also be the pathname of a directory or file, or a dummy string) to the location (a directory or file) specified by the pathname in target.

Appropriate privilege (Linux: the CAP_SYS_ADMIN capability) is required to mount filesystems.

Values for the filesystemtype argument supported by the kernel are listed in /proc/filesystems (e.g., "btrfs", "ext4", "jfs", "xfs", "vfat", "fuse", "tmpfs", "cgroup", "proc", "mqueue", "nfs", "cifs", "iso9660"). Further types may become available when the appropriate modules are loaded.

The data argument is interpreted by the different filesystems. Typically it is a string of comma-separated options understood by this filesystem. See mount(8) for details of the options available for each filesystem type. This argument may be specified as NULL, if there are no options.

A call to mount() performs one of a number of general types of operation, depending on the bits specified in mountflags. The choice of which operation to perform is determined by testing the bits set in mountflags, with the tests being conducted in the order listed here:

•

Remount an existing mount: mountflags includes MS_REMOUNT.

•

Create a bind mount: mountflags includes MS_BIND.

•

Change the propagation type of an existing mount: mountflags includes one of MS_SHARED, MS_PRIVATE, MS_SLAVE, or MS_UNBINDABLE.

•

Move an existing mount to a new location: mountflags includes MS_MOVE.

•

Create a new mount: mountflags includes none of the above flags.

Each of these operations is detailed later in this page. Further flags may be specified in mountflags to modify the behavior of mount(), as described below.

### Additional mount flags
The list below describes the additional flags that can be specified in mountflags. Note that some operation types ignore some or all of these flags, as described later in this page.

MS_DIRSYNC (since Linux 2.5.19)

Make directory changes on this filesystem synchronous. (This property can be obtained for individual directories or subtrees using chattr(1).)

MS_LAZYTIME (since Linux 4.0)

Reduce on-disk updates of inode timestamps (atime, mtime, ctime) by maintaining these changes only in memory. The on-disk timestamps are updated only when:

•

the inode needs to be updated for some change unrelated to file timestamps;

•

the application employs fsync(2), syncfs(2), or sync(2);

•

an undeleted inode is evicted from memory; or

•

more than 24 hours have passed since the inode was written to disk.

This mount option significantly reduces writes needed to update the inode's timestamps, especially mtime and atime. However, in the event of a system crash, the atime and mtime fields on disk might be out of date by up to 24 hours.

Examples of workloads where this option could be of significant benefit include frequent random writes to preallocated files, as well as cases where the MS_STRICTATIME mount option is also enabled. (The advantage of combining MS_STRICTATIME and MS_LAZYTIME is that stat(2) will return the correctly updated atime, but the atime updates will be flushed to disk only in the cases listed above.)

MS_MANDLOCK

Permit mandatory locking on files in this filesystem. (Mandatory locking must still be enabled on a per-file basis, as described in fcntl(2).) Since Linux 4.5, this mount option requires the CAP_SYS_ADMIN capability and a kernel configured with the CONFIG_MANDATORY_FILE_LOCKING option. Mandatory locking has been fully deprecated in Linux 5.15, so this flag should be considered deprecated.

MS_NOATIME

Do not update access times for (all types of) files on this filesystem.

MS_NODEV

Do not allow access to devices (special files) on this filesystem.

MS_NODIRATIME

Do not update access times for directories on this filesystem. This flag provides a subset of the functionality provided by MS_NOATIME; that is, MS_NOATIME implies MS_NODIRATIME.

MS_NOEXEC

Do not allow programs to be executed from this filesystem.

MS_NOSUID

Do not honor set-user-ID and set-group-ID bits or file capabilities when executing programs from this filesystem. In addition, SELinux domain transitions require the permission nosuid_transition, which in turn needs also the policy capability nnp_nosuid_transition.

MS_RDONLY

Mount filesystem read-only.

MS_REC (since Linux 2.4.11)

Used in conjunction with MS_BIND to create a recursive bind mount, and in conjunction with the propagation type flags to recursively change the propagation type of all of the mounts in a subtree. See below for further details.

MS_RELATIME (since Linux 2.6.20)

When a file on this filesystem is accessed, update the file's last access time (atime) only if the current value of atime is less than or equal to the file's last modification time (mtime) or last status change time (ctime). This option is useful for programs, such as mutt(1), that need to know when a file has been read since it was last modified. Since Linux 2.6.30, the kernel defaults to the behavior provided by this flag (unless MS_NOATIME was specified), and the MS_STRICTATIME flag is required to obtain traditional semantics. In addition, since Linux 2.6.30, the file's last access time is always updated if it is more than 1 day old.

MS_SILENT (since Linux 2.6.17)

Suppress the display of certain (printk()) warning messages in the kernel log. This flag supersedes the misnamed and obsolete MS_VERBOSE flag (available since Linux 2.4.12), which has the same meaning.

MS_STRICTATIME (since Linux 2.6.30)

Always update the last access time (atime) when files on this filesystem are accessed. (This was the default behavior before Linux 2.6.30.) Specifying this flag overrides the effect of setting the MS_NOATIME and MS_RELATIME flags.

MS_SYNCHRONOUS

Make writes on this filesystem synchronous (as though the O_SYNC flag to open(2) was specified for all file opens to this filesystem).

MS_NOSYMFOLLOW (since Linux 5.10)

Do not follow symbolic links when resolving paths. Symbolic links can still be created, and readlink(1), readlink(2), realpath(1), and realpath(3) all still work properly.

From Linux 2.4 onward, some of the above flags are settable on a per-mount basis, while others apply to the superblock of the mounted filesystem, meaning that all mounts of the same filesystem share those flags. (Previously, all of the flags were per-superblock.)

The per-mount-point flags are as follows:

•

Since Linux 2.4: MS_NODEV, MS_NOEXEC, and MS_NOSUID flags are settable on a per-mount-point basis.

•

Additionally, since Linux 2.6.16: MS_NOATIME and MS_NODIRATIME.

•

Additionally, since Linux 2.6.20: MS_RELATIME.

The following flags are per-superblock: MS_DIRSYNC, MS_LAZYTIME, MS_MANDLOCK, MS_SILENT, and MS_SYNCHRONOUS. The initial settings of these flags are determined on the first mount of the filesystem, and will be shared by all subsequent mounts of the same filesystem. Subsequently, the settings of the flags can be changed via a remount operation (see below). Such changes will be visible via all mounts associated with the filesystem.

Since Linux 2.6.16, MS_RDONLY can be set or cleared on a per-mount-point basis as well as on the underlying filesystem superblock. The mounted filesystem will be writable only if neither the filesystem nor the mountpoint are flagged as read-only.

### Remounting an existing mount
An existing mount may be remounted by specifying MS_REMOUNT in mountflags. This allows you to change the mountflags and data of an existing mount without having to unmount and remount the filesystem. target should be the same value specified in the initial mount() call.

The source and filesystemtype arguments are ignored.

The mountflags and data arguments should match the values used in the original mount() call, except for those parameters that are being deliberately changed.

The following mountflags can be changed: MS_LAZYTIME, MS_MANDLOCK, MS_NOATIME, MS_NODEV, MS_NODIRATIME, MS_NOEXEC, MS_NOSUID, MS_RELATIME, MS_RDONLY, MS_STRICTATIME (whose effect is to clear the MS_NOATIME and MS_RELATIME flags), and MS_SYNCHRONOUS. Attempts to change the setting of the MS_DIRSYNC and MS_SILENT flags during a remount are silently ignored. Note that changes to per-superblock flags are visible via all mounts of the associated filesystem (because the per-superblock flags are shared by all mounts).

Since Linux 3.17, if none of MS_NOATIME, MS_NODIRATIME, MS_RELATIME, or MS_STRICTATIME is specified in mountflags, then the remount operation preserves the existing values of these flags (rather than defaulting to MS_RELATIME).

Since Linux 2.6.26, the MS_REMOUNT flag can be used with MS_BIND to modify only the per-mount-point flags. This is particularly useful for setting or clearing the "read-only" flag on a mount without changing the underlying filesystem. Specifying mountflags as:

```
MS_REMOUNT | MS_BIND | MS_RDONLY
```

will make access through this mountpoint read-only, without affecting other mounts.

### Creating a bind mount
If mountflags includes MS_BIND (available since Linux 2.4), then perform a bind mount. A bind mount makes a file or a directory subtree visible at another point within the single directory hierarchy. Bind mounts may cross filesystem boundaries and span chroot(2) jails.

The filesystemtype and data arguments are ignored.

The remaining bits (other than MS_REC, described below) in the mountflags argument are also ignored. (The bind mount has the same mount options as the underlying mount.) However, see the discussion of remounting above, for a method of making an existing bind mount read-only.

By default, when a directory is bind mounted, only that directory is mounted; if there are any submounts under the directory tree, they are not bind mounted. If the MS_REC flag is also specified, then a recursive bind mount operation is performed: all submounts under the source subtree (other than unbindable mounts) are also bind mounted at the corresponding location in the target subtree.

### Changing the propagation type of an existing mount
If mountflags includes one of MS_SHARED, MS_PRIVATE, MS_SLAVE, or MS_UNBINDABLE (all available since Linux 2.6.15), then the propagation type of an existing mount is changed. If more than one of these flags is specified, an error results.

The only other flags that can be specified while changing the propagation type are MS_REC (described below) and MS_SILENT (which is ignored).

The source, filesystemtype, and data arguments are ignored.

The meanings of the propagation type flags are as follows:

MS_SHARED

Make this mount shared. Mount and unmount events immediately under this mount will propagate to the other mounts that are members of this mount's peer group. Propagation here means that the same mount or unmount will automatically occur under all of the other mounts in the peer group. Conversely, mount and unmount events that take place under peer mounts will propagate to this mount.

MS_PRIVATE

Make this mount private. Mount and unmount events do not propagate into or out of this mount.

MS_SLAVE

If this is a shared mount that is a member of a peer group that contains other members, convert it to a slave mount. If this is a shared mount that is a member of a peer group that contains no other members, convert it to a private mount. Otherwise, the propagation type of the mount is left unchanged.

When a mount is a slave, mount and unmount events propagate into this mount from the (master) shared peer group of which it was formerly a member. Mount and unmount events under this mount do not propagate to any peer.

A mount can be the slave of another peer group while at the same time sharing mount and unmount events with a peer group of which it is a member.

MS_UNBINDABLE

Make this mount unbindable. This is like a private mount, and in addition this mount can't be bind mounted. When a recursive bind mount (mount() with the MS_BIND and MS_REC flags) is performed on a directory subtree, any unbindable mounts within the subtree are automatically pruned (i.e., not replicated) when replicating that subtree to produce the target subtree.

By default, changing the propagation type affects only the target mount. If the MS_REC flag is also specified in mountflags, then the propagation type of all mounts under target is also changed.

For further details regarding mount propagation types (including the default propagation type assigned to new mounts), see mount_namespaces(7).

### Moving a mount
If mountflags contains the flag MS_MOVE (available since Linux 2.4.18), then move a subtree: source specifies an existing mount and target specifies the new location to which that mount is to be relocated. The move is atomic: at no point is the subtree unmounted.

The remaining bits in the mountflags argument are ignored, as are the filesystemtype and data arguments.

### Creating a new mount
If none of MS_REMOUNT, MS_BIND, MS_MOVE, MS_SHARED, MS_PRIVATE, MS_SLAVE, or MS_UNBINDABLE is specified in mountflags, then mount() performs its default action: creating a new mount. source specifies the source for the new mount, and target specifies the directory at which to create the mount point.

The filesystemtype and data arguments are employed, and further bits may be specified in mountflags to modify the behavior of the call.

## RETURN VALUE
On success, zero is returned. On error, -1 is returned, and errno is set to indicate the error.

## ERRORS
The error values given below result from filesystem type independent errors. Each filesystem type may have its own special errors and its own special behavior. See the Linux kernel source code for details.

EACCES

A component of a path was not searchable. (See also path_resolution(7).)

EACCES

Mounting a read-only filesystem was attempted without giving the MS_RDONLY flag.

The filesystem may be read-only for various reasons, including: it resides on a read-only optical disk; it is resides on a device with a physical switch that has been set to mark the device read-only; the filesystem implementation was compiled with read-only support; or errors were detected when initially mounting the filesystem, so that it was marked read-only and can't be remounted as read-write (until the errors are fixed).

Some filesystems instead return the error EROFS on an attempt to mount a read-only filesystem.

EACCES

The block device source is located on a filesystem mounted with the MS_NODEV option.

EBUSY

An attempt was made to stack a new mount directly on top of an existing mount point that was created in this mount namespace with the same source and target.

EBUSY

source cannot be remounted read-only, because it still holds files open for writing.

EFAULT

One of the pointer arguments points outside the user address space.

EINVAL

source had an invalid superblock.

EINVAL

A remount operation (MS_REMOUNT) was attempted, but source was not already mounted on target.

EINVAL

A move operation (MS_MOVE) was attempted, but the mount tree under source includes unbindable mounts and target is a mount that has propagation type MS_SHARED.

EINVAL

A move operation (MS_MOVE) was attempted, but the parent mount of source mount has propagation type MS_SHARED.

EINVAL

A move operation (MS_MOVE) was attempted, but source was not a mount, or was '/'.

EINVAL

A bind operation (MS_BIND) was requested where source referred a mount namespace magic link (i.e., a /proc/pid/ns/mnt magic link or a bind mount to such a link) and the propagation type of the parent mount of target was MS_SHARED, but propagation of the requested bind mount could lead to a circular dependency that might prevent the mount namespace from ever being freed.

EINVAL

mountflags includes more than one of MS_SHARED, MS_PRIVATE, MS_SLAVE, or MS_UNBINDABLE.

EINVAL

mountflags includes MS_SHARED, MS_PRIVATE, MS_SLAVE, or MS_UNBINDABLE and also includes a flag other than MS_REC or MS_SILENT.

EINVAL

An attempt was made to bind mount an unbindable mount.

EINVAL

In an unprivileged mount namespace (i.e., a mount namespace owned by a user namespace that was created by an unprivileged user), a bind mount operation (MS_BIND) was attempted without specifying (MS_REC), which would have revealed the filesystem tree underneath one of the submounts of the directory being bound.

ELOOP

Too many links encountered during pathname resolution.

ELOOP

A move operation was attempted, and target is a descendant of source.

EMFILE

(In case no block device is required:) Table of dummy devices is full.

ENAMETOOLONG

A pathname was longer than MAXPATHLEN.

ENODEV

filesystemtype not configured in the kernel.

ENOENT

A pathname was empty or had a nonexistent component.

ENOMEM

The kernel could not allocate a free page to copy filenames or data into.

ENOTBLK

source is not a block device (and a device was required).

ENOTDIR

target, or a prefix of source, is not a directory.

ENXIO

The major number of the block device source is out of range.

EPERM

The caller does not have the required privileges.

EPERM

An attempt was made to modify (MS_REMOUNT) the MS_RDONLY, MS_NOSUID, or MS_NOEXEC flag, or one of the "atime" flags (MS_NOATIME, MS_NODIRATIME, MS_RELATIME) of an existing mount, but the mount is locked; see mount_namespaces(7).

EROFS

Mounting a read-only filesystem was attempted without giving the MS_RDONLY flag. See EACCES, above.

## STANDARDS
Linux.

## HISTORY
The definitions of MS_DIRSYNC, MS_MOVE, MS_PRIVATE, MS_REC, MS_RELATIME, MS_SHARED, MS_SLAVE, MS_STRICTATIME, and MS_UNBINDABLE were added to glibc headers in glibc 2.12.

Since Linux 2.4 a single filesystem can be mounted at multiple mount points, and multiple mounts can be stacked on the same mount point.

The mountflags argument may have the magic number 0xC0ED (MS_MGC_VAL) in the top 16 bits. (All of the other flags discussed in DESCRIPTION occupy the low order 16 bits of mountflags.) Specifying MS_MGC_VAL was required before Linux 2.4, but since Linux 2.4 is no longer required and is ignored if specified.

The original MS_SYNC flag was renamed MS_SYNCHRONOUS in 1.1.69 when a different MS_SYNC was added to <mman.h>.

Before Linux 2.4 an attempt to execute a set-user-ID or set-group-ID program on a filesystem mounted with MS_NOSUID would fail with EPERM. Since Linux 2.4 the set-user-ID and set-group-ID bits are just silently ignored in this case.

## NOTES

### Mount namespaces
Starting with Linux 2.4.19, Linux provides mount namespaces. A mount namespace is the set of filesystem mounts that are visible to a process. Mount namespaces can be (and usually are) shared between multiple processes, and changes to the namespace (i.e., mounts and unmounts) by one process are visible to all other processes sharing the same namespace. (The pre-2.4.19 Linux situation can be considered as one in which a single namespace was shared by every process on the system.)

A child process created by fork(2) shares its parent's mount namespace; the mount namespace is preserved across an execve(2).

A process can obtain a private mount namespace if: it was created using the clone(2) CLONE_NEWNS flag, in which case its new namespace is initialized to be a copy of the namespace of the process that called clone(2); or it calls unshare(2) with the CLONE_NEWNS flag, which causes the caller's mount namespace to obtain a private copy of the namespace that it was previously sharing with other processes, so that future mounts and unmounts by the caller are invisible to other processes (except child processes that the caller subsequently creates) and vice versa.

For further details on mount namespaces, see mount_namespaces(7).

### Parental relationship between mounts
Each mount has a parent mount. The overall parental relationship of all mounts defines the single directory hierarchy seen by the processes within a mount namespace.

The parent of a new mount is defined when the mount is created. In the usual case, the parent of a new mount is the mount of the filesystem containing the directory or file at which the new mount is attached. In the case where a new mount is stacked on top of an existing mount, the parent of the new mount is the previous mount that was stacked at that location.

The parental relationship between mounts can be discovered via the /proc/pid/mountinfo file (see below).

### /proc/pid/mounts and /proc/pid/mountinfo
The Linux-specific /proc/pid/mounts file exposes the list of mounts in the mount namespace of the process with the specified ID. The /proc/pid/mountinfo file exposes even more information about mounts, including the propagation type and mount ID information that makes it possible to discover the parental relationship between mounts. See proc(5) and mount_namespaces(7) for details of this file.

## SEE ALSO
mountpoint(1), chroot(2), ioctl_iflags(2), mount_setattr(2), pivot_root(2), umount(2), mount_namespaces(7), path_resolution(7), findmnt(8), lsblk(8), mount(8), umount(8)


title: mount_setattr(2)

text:
# mount_setattr(2)

## NAME
mount_setattr - change properties of a mount or mount tree

## LIBRARY
Standard C library (libc, -lc)

## SYNOPSIS

```
#include <linux/fcntl.h> /* Definition of AT_* constants */
#include <linux/mount.h> /* Definition of MOUNT_ATTR_* constants */
#include <sys/syscall.h> /* Definition of SYS_* constants */
#include <unistd.h>
```

```
int syscall(SYS_mount_setattr, int dirfd, const char *pathname,
            unsigned int flags, struct mount_attr *attr, size_t size);
```

Note: glibc provides no wrapper for mount_setattr(), necessitating the use of syscall(2).

## DESCRIPTION
The mount_setattr() system call changes the mount properties of a mount or an entire mount tree. If pathname is a relative pathname, then it is interpreted relative to the directory referred to by the file descriptor dirfd. If dirfd is the special value AT_FDCWD, then pathname is interpreted relative to the current working directory of the calling process. If pathname is the empty string and AT_EMPTY_PATH is specified in flags, then the mount properties of the mount identified by dirfd are changed. (See openat(2) for an explanation of why the dirfd argument is useful.)

The mount_setattr() system call uses an extensible structure (struct mount_attr) to allow for future extensions. Any non-flag extensions to mount_setattr() will be implemented as new fields appended to the this structure, with a zero value in a new field resulting in the kernel behaving as though that extension field was not present. Therefore, the caller must zero-fill this structure on initialization. See the "Extensibility" subsection under NOTES for more details.

The size argument should usually be specified as sizeof(struct mount_attr). However, if the caller is using a kernel that supports an extended struct mount_attr, but the caller does not intend to make use of these features, it is possible to pass the size of an earlier version of the structure together with the extended structure. This allows the kernel to not copy later parts of the structure that aren't used anyway. With each extension that changes the size of struct mount_attr, the kernel will expose a definition of the form MOUNT_ATTR_SIZE_VERnumber. For example, the macro for the size of the initial version of struct mount_attr is MOUNT_ATTR_SIZE_VER0.

The flags argument can be used to alter the pathname resolution behavior. The supported values are:

AT_EMPTY_PATH

If pathname is the empty string, change the mount properties on dirfd itself.

AT_RECURSIVE

Change the mount properties of the entire mount tree.

AT_SYMLINK_NOFOLLOW

Don't follow trailing symbolic links.

AT_NO_AUTOMOUNT

Don't trigger automounts.

The attr argument of mount_setattr() is a structure of the following form:

```
struct mount_attr {

    __u64 attr_set;     /* Mount properties to set */

    __u64 attr_clr;     /* Mount properties to clear */

    __u64 propagation;  /* Mount propagation type */

    __u64 userns_fd;    /* User namespace file descriptor */
};
```

The attr_set and attr_clr members are used to specify the mount properties that are supposed to be set or cleared for a mount or mount tree. Flags set in attr_set enable a property on a mount or mount tree, and flags set in attr_clr remove a property from a mount or mount tree.

When changing mount properties, the kernel will first clear the flags specified in the attr_clr field, and then set the flags specified in the attr_set field. For example, these settings:

```
struct mount_attr attr = {

    .attr_clr = MOUNT_ATTR_NOEXEC | MOUNT_ATTR_NODEV,

    .attr_set = MOUNT_ATTR_RDONLY | MOUNT_ATTR_NOSUID,
};
```

are equivalent to the following steps:

```
unsigned int current_mnt_flags = mnt->mnt_flags;
/*

 * Clear all flags set in .attr_clr,

 * clearing MOUNT_ATTR_NOEXEC and MOUNT_ATTR_NODEV.

 */
current_mnt_flags &= ~attr->attr_clr;
/*

 * Now set all flags set in .attr_set,

 * applying MOUNT_ATTR_RDONLY and MOUNT_ATTR_NOSUID.

 */
current_mnt_flags |= attr->attr_set;
mnt->mnt_flags = current_mnt_flags;
```

As a result of this change, the mount or mount tree (a) is read-only; (b) blocks the execution of set-user-ID and set-group-ID programs; (c) allows execution of programs; and (d) allows access to devices.

Multiple changes with the same set of flags requested in attr_clr and attr_set are guaranteed to be idempotent after the changes have been applied.

The following mount attributes can be specified in the attr_set or attr_clr fields:

MOUNT_ATTR_RDONLY

If set in attr_set, makes the mount read-only. If set in attr_clr, removes the read-only setting if set on the mount.

MOUNT_ATTR_NOSUID

If set in attr_set, causes the mount not to honor the set-user-ID and set-group-ID mode bits and file capabilities when executing programs. If set in attr_clr, clears the set-user-ID, set-group-ID, and file capability restriction if set on this mount.

MOUNT_ATTR_NODEV

If set in attr_set, prevents access to devices on this mount. If set in attr_clr, removes the restriction that prevented accessing devices on this mount.

MOUNT_ATTR_NOEXEC

If set in attr_set, prevents executing programs on this mount. If set in attr_clr, removes the restriction that prevented executing programs on this mount.

MOUNT_ATTR_NOSYMFOLLOW

If set in attr_set, prevents following symbolic links on this mount. If set in attr_clr, removes the restriction that prevented following symbolic links on this mount.

MOUNT_ATTR_NODIRATIME

If set in attr_set, prevents updating access time for directories on this mount. If set in attr_clr, removes the restriction that prevented updating access time for directories. Note that MOUNT_ATTR_NODIRATIME can be combined with other access-time settings and is implied by the noatime setting. All other access-time settings are mutually exclusive.

MOUNT_ATTR__ATIME - changing access-time settings

The access-time values listed below are an enumeration that includes the value zero, expressed in the bits defined by the mask MOUNT_ATTR__ATIME. Even though these bits are an enumeration (in contrast to the other mount flags such as MOUNT_ATTR_NOEXEC), they are nonetheless passed in attr_set and attr_clr for consistency with fsmount(2), which introduced this behavior.

Note that, since the access-time values are an enumeration rather than bit values, a caller wanting to transition to a different access-time setting cannot simply specify the access-time setting in attr_set, but must also include MOUNT_ATTR__ATIME in the attr_clr field. The kernel will verify that MOUNT_ATTR__ATIME isn't partially set in attr_clr (i.e., either all bits in the MOUNT_ATTR__ATIME bit field are either set or clear), and that attr_set doesn't have any access-time bits set if MOUNT_ATTR__ATIME isn't set in attr_clr.

MOUNT_ATTR_RELATIME

When a file is accessed via this mount, update the file's last access time (atime) only if the current value of atime is less than or equal to the file's last modification time (mtime) or last status change time (ctime).

To enable this access-time setting on a mount or mount tree, MOUNT_ATTR_RELATIME must be set in attr_set and MOUNT_ATTR__ATIME must be set in the attr_clr field.

MOUNT_ATTR_NOATIME

Do not update access times for (all types of) files on this mount.

To enable this access-time setting on a mount or mount tree, MOUNT_ATTR_NOATIME must be set in attr_set and MOUNT_ATTR__ATIME must be set in the attr_clr field.

MOUNT_ATTR_STRICTATIME

Always update the last access time (atime) when files are accessed on this mount.

To enable this access-time setting on a mount or mount tree, MOUNT_ATTR_STRICTATIME must be set in attr_set and MOUNT_ATTR__ATIME must be set in the attr_clr field.

MOUNT_ATTR_IDMAP

If set in attr_set, creates an ID-mapped mount. The ID mapping is taken from the user namespace specified in userns_fd and attached to the mount.

Since it is not supported to change the ID mapping of a mount after it has been ID mapped, it is invalid to specify MOUNT_ATTR_IDMAP in attr_clr.

For further details, see the subsection "ID-mapped mounts" under NOTES.

The propagation field is used to specify the propagation type of the mount or mount tree. This field either has the value zero, meaning leave the propagation type unchanged, or it has one of the following values:

MS_PRIVATE

Turn all mounts into private mounts.

MS_SHARED

Turn all mounts into shared mounts.

MS_SLAVE

Turn all mounts into dependent mounts.

MS_UNBINDABLE

Turn all mounts into unbindable mounts.

For further details on the above propagation types, see mount_namespaces(7).

## RETURN VALUE
On success, mount_setattr() returns zero. On error, -1 is returned and errno is set to indicate the cause of the error.

## ERRORS
EBADF

pathname is relative but dirfd is neither AT_FDCWD nor a valid file descriptor.

EBADF

userns_fd is not a valid file descriptor.

EBUSY

The caller tried to change the mount to MOUNT_ATTR_RDONLY, but the mount still holds files open for writing.

EBUSY

The caller tried to create an ID-mapped mount raising MOUNT_ATTR_IDMAP and specifying userns_fd but the mount still holds files open for writing.

EINVAL

The pathname specified via the dirfd and pathname arguments to mount_setattr() isn't a mount point.

EINVAL

An unsupported value was set in flags.

EINVAL

An unsupported value was specified in the attr_set field of mount_attr.

EINVAL

An unsupported value was specified in the attr_clr field of mount_attr.

EINVAL

An unsupported value was specified in the propagation field of mount_attr.

EINVAL

More than one of MS_SHARED, MS_SLAVE, MS_PRIVATE, or MS_UNBINDABLE was set in the propagation field of mount_attr.

EINVAL

An access-time setting was specified in the attr_set field without MOUNT_ATTR__ATIME being set in the attr_clr field.

EINVAL

MOUNT_ATTR_IDMAP was specified in attr_clr.

EINVAL

A file descriptor value was specified in userns_fd which exceeds INT_MAX.

EINVAL

A valid file descriptor value was specified in userns_fd, but the file descriptor did not refer to a user namespace.

EINVAL

The underlying filesystem does not support ID-mapped mounts.

EINVAL

The mount that is to be ID mapped is not a detached mount; that is, the mount has not previously been visible in a mount namespace.

EINVAL

A partial access-time setting was specified in attr_clr instead of MOUNT_ATTR__ATIME being set.

EINVAL

The mount is located outside the caller's mount namespace.

EINVAL

The underlying filesystem has been mounted in a mount namespace that is owned by a noninitial user namespace

ENOENT

A pathname was empty or had a nonexistent component.

ENOMEM

When changing mount propagation to MS_SHARED, a new peer group ID needs to be allocated for all mounts without a peer group ID set. This allocation failed because there was not enough memory to allocate the relevant internal structures.

ENOSPC

When changing mount propagation to MS_SHARED, a new peer group ID needs to be allocated for all mounts without a peer group ID set. This allocation failed because the kernel has run out of IDs.

EPERM

One of the mounts had at least one of MOUNT_ATTR_NOATIME, MOUNT_ATTR_NODEV, MOUNT_ATTR_NODIRATIME, MOUNT_ATTR_NOEXEC, MOUNT_ATTR_NOSUID, or MOUNT_ATTR_RDONLY set and the flag is locked. Mount attributes become locked on a mount if:

•

A new mount or mount tree is created causing mount propagation across user namespaces (i.e., propagation to a mount namespace owned by a different user namespace). The kernel will lock the aforementioned flags to prevent these sensitive properties from being altered.

•

A new mount and user namespace pair is created. This happens for example when specifying CLONE_NEWUSER | CLONE_NEWNS in unshare(2), clone(2), or clone3(2). The aforementioned flags become locked in the new mount namespace to prevent sensitive mount properties from being altered. Since the newly created mount namespace will be owned by the newly created user namespace, a calling process that is privileged in the new user namespace would—in the absence of such locking—be able to alter sensitive mount properties (e.g., to remount a mount that was marked read-only as read-write in the new mount namespace).

EPERM

A valid file descriptor value was specified in userns_fd, but the file descriptor refers to the initial user namespace.

EPERM

An attempt was made to add an ID mapping to a mount that is already ID mapped.

EPERM

The caller does not have CAP_SYS_ADMIN in the initial user namespace.

## STANDARDS
Linux.

## HISTORY
Linux 5.12.

## NOTES

### ID-mapped mounts
Creating an ID-mapped mount makes it possible to change the ownership of all files located under a mount. Thus, ID-mapped mounts make it possible to change ownership in a temporary and localized way. It is a localized change because the ownership changes are visible only via a specific mount. All other users and locations where the filesystem is exposed are unaffected. It is a temporary change because the ownership changes are tied to the lifetime of the mount.

Whenever callers interact with the filesystem through an ID-mapped mount, the ID mapping of the mount will be applied to user and group IDs associated with filesystem objects. This encompasses the user and group IDs associated with inodes and also the following xattr(7) keys:

•

security.capability, whenever filesystem capabilities are stored or returned in the VFS_CAP_REVISION_3 format, which stores a root user ID alongside the capabilities (see capabilities(7)).

•

system.posix_acl_access and system.posix_acl_default, whenever user IDs or group IDs are stored in ACL_USER or ACL_GROUP entries.

The following conditions must be met in order to create an ID-mapped mount:

•

The caller must have the CAP_SYS_ADMIN capability in the user namespace the filesystem was mounted in.

•

The underlying filesystem must support ID-mapped mounts. Currently, the following filesystems support ID-mapped mounts:

•

xfs(5) (since Linux 5.12)

•

ext4(5) (since Linux 5.12)

•

FAT (since Linux 5.12)

•

btrfs(5) (since Linux 5.15)

•

ntfs3 (since Linux 5.15)

•

f2fs (since Linux 5.18)

•

erofs (since Linux 5.19)

•

overlayfs (ID-mapped lower and upper layers supported since Linux 5.19)

•

The mount must not already be ID-mapped. This also implies that the ID mapping of a mount cannot be altered.

•

The mount must not have any writers.

•

The mount must be a detached mount; that is, it must have been created by calling open_tree(2) with the OPEN_TREE_CLONE flag and it must not already have been visible in a mount namespace. (To put things another way: the mount must not have been attached to the filesystem hierarchy with a system call such as move_mount(2).)

ID mappings can be created for user IDs, group IDs, and project IDs. An ID mapping is essentially a mapping of a range of user or group IDs into another or the same range of user or group IDs. ID mappings are written to map files as three numbers separated by white space. The first two numbers specify the starting user or group ID in each of the two user namespaces. The third number specifies the range of the ID mapping. For example, a mapping for user IDs such as "1000 1001 1" would indicate that user ID 1000 in the caller's user namespace is mapped to user ID 1001 in its ancestor user namespace. Since the map range is 1, only user ID 1000 is mapped.

It is possible to specify up to 340 ID mappings for each ID mapping type. If any user IDs or group IDs are not mapped, all files owned by that unmapped user or group ID will appear as being owned by the overflow user ID or overflow group ID respectively.

Further details on setting up ID mappings can be found in user_namespaces(7).

In the common case, the user namespace passed in userns_fd (together with MOUNT_ATTR_IDMAP in attr_set) to create an ID-mapped mount will be the user namespace of a container. In other scenarios it will be a dedicated user namespace associated with a user's login session as is the case for portable home directories in systemd-homed.service(8)). It is also perfectly fine to create a dedicated user namespace for the sake of ID mapping a mount.

ID-mapped mounts can be useful in the following and a variety of other scenarios:

•

Sharing files or filesystems between multiple users or multiple machines, especially in complex scenarios. For example, ID-mapped mounts are used to implement portable home directories in systemd-homed.service(8), where they allow users to move their home directory to an external storage device and use it on multiple computers where they are assigned different user IDs and group IDs. This effectively makes it possible to assign random user IDs and group IDs at login time.

•

Sharing files or filesystems from the host with unprivileged containers. This allows a user to avoid having to change ownership permanently through chown(2).

•

ID mapping a container's root filesystem. Users don't need to change ownership permanently through chown(2). Especially for large root filesystems, using chown(2) can be prohibitively expensive.

•

Sharing files or filesystems between containers with non-overlapping ID mappings.

•

Implementing discretionary access (DAC) permission checking for filesystems lacking a concept of ownership.

•

Efficiently changing ownership on a per-mount basis. In contrast to chown(2), changing ownership of large sets of files is instantaneous with ID-mapped mounts. This is especially useful when ownership of an entire root filesystem of a virtual machine or container is to be changed as mentioned above. With ID-mapped mounts, a single mount_setattr() system call will be sufficient to change the ownership of all files.

•

Taking the current ownership into account. ID mappings specify precisely what a user or group ID is supposed to be mapped to. This contrasts with the chown(2) system call which cannot by itself take the current ownership of the files it changes into account. It simply changes the ownership to the specified user ID and group ID.

•

Locally and temporarily restricted ownership changes. ID-mapped mounts make it possible to change ownership locally, restricting the ownership changes to specific mounts, and temporarily as the ownership changes only apply as long as the mount exists. By contrast, changing ownership via the chown(2) system call changes the ownership globally and permanently.

### Extensibility
In order to allow for future extensibility, mount_setattr() requires the user-space application to specify the size of the mount_attr structure that it is passing. By providing this information, it is possible for mount_setattr() to provide both forwards- and backwards-compatibility, with size acting as an implicit version number. (Because new extension fields will always be appended, the structure size will always increase.) This extensibility design is very similar to other system calls such as perf_setattr(2), perf_event_open(2), clone3(2) and openat2(2).

Let usize be the size of the structure as specified by the user-space application, and let ksize be the size of the structure which the kernel supports, then there are three cases to consider:

•

If ksize equals usize, then there is no version mismatch and attr can be used verbatim.

•

If ksize is larger than usize, then there are some extension fields that the kernel supports which the user-space application is unaware of. Because a zero value in any added extension field signifies a no-op, the kernel treats all of the extension fields not provided by the user-space application as having zero values. This provides backwards-compatibility.

•

If ksize is smaller than usize, then there are some extension fields which the user-space application is aware of but which the kernel does not support. Because any extension field must have its zero values signify a no-op, the kernel can safely ignore the unsupported extension fields if they are all zero. If any unsupported extension fields are non-zero, then -1 is returned and errno is set to E2BIG. This provides forwards-compatibility.

Because the definition of struct mount_attr may change in the future (with new fields being added when system headers are updated), user-space applications should zero-fill struct mount_attr to ensure that recompiling the program with new headers will not result in spurious errors at run time. The simplest way is to use a designated initializer:

```
struct mount_attr attr = {

    .attr_set = MOUNT_ATTR_RDONLY,

    .attr_clr = MOUNT_ATTR_NODEV
};
```

Alternatively, the structure can be zero-filled using memset(3) or similar functions:

```
struct mount_attr attr;
memset(&attr, 0, sizeof(attr));
attr.attr_set = MOUNT_ATTR_RDONLY;
attr.attr_clr = MOUNT_ATTR_NODEV;
```

A user-space application that wishes to determine which extensions the running kernel supports can do so by conducting a binary search on size with a structure which has every byte nonzero (to find the largest value which doesn't produce an error of E2BIG).

## EXAMPLES

```
/*

 * This program allows the caller to create a new detached mount

 * and set various properties on it.

 */
#define _GNU_SOURCE
#include <err.h>
#include <fcntl.h>
#include <getopt.h>
#include <linux/mount.h>
#include <linux/types.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/syscall.h>
#include <unistd.h>
static inline int
mount_setattr(int dirfd, const char *pathname, unsigned int flags,

              struct mount_attr *attr, size_t size)
{

    return syscall(SYS_mount_setattr, dirfd, pathname, flags,

                   attr, size);
}
static inline int
open_tree(int dirfd, const char *filename, unsigned int flags)
{

    return syscall(SYS_open_tree, dirfd, filename, flags);
}
static inline int
move_mount(int from_dirfd, const char *from_pathname,

           int to_dirfd, const char *to_pathname, unsigned int flags)
{

    return syscall(SYS_move_mount, from_dirfd, from_pathname,

                   to_dirfd, to_pathname, flags);
}
static const struct option longopts[] = {

    {"map-mount",       required_argument,  NULL,  'a'},

    {"recursive",       no_argument,        NULL,  'b'},

    {"read-only",       no_argument,        NULL,  'c'},

    {"block-setid",     no_argument,        NULL,  'd'},

    {"block-devices",   no_argument,        NULL,  'e'},

    {"block-exec",      no_argument,        NULL,  'f'},

    {"no-access-time",  no_argument,        NULL,  'g'},

    { NULL,             0,                  NULL,   0 },
};
int
main(int argc, char *argv[])
{

    int                fd_userns = -1;

    int                fd_tree;

    int                index = 0;

    int                ret;

    bool               recursive = false;

    const char         *source;

    const char         *target;

    struct mount_attr  *attr = &(struct mount_attr){};

    while ((ret = getopt_long_only(argc, argv, "",

                                   longopts, &index)) != -1) {

        switch (ret) {

        case 'a':

            fd_userns = open(optarg, O_RDONLY | O_CLOEXEC);

            if (fd_userns == -1)

                err(EXIT_FAILURE, "open(%s)", optarg);

            break;

        case 'b':

            recursive = true;

            break;

        case 'c':

            attr->attr_set |= MOUNT_ATTR_RDONLY;

            break;

        case 'd':

            attr->attr_set |= MOUNT_ATTR_NOSUID;

            break;

        case 'e':

            attr->attr_set |= MOUNT_ATTR_NODEV;

            break;

        case 'f':

            attr->attr_set |= MOUNT_ATTR_NOEXEC;

            break;

        case 'g':

            attr->attr_set |= MOUNT_ATTR_NOATIME;

            attr->attr_clr |= MOUNT_ATTR__ATIME;

            break;

        default:

            errx(EXIT_FAILURE, "Invalid argument specified");

        }

    }

    if ((argc - optind) < 2)

        errx(EXIT_FAILURE, "Missing source or target mount point");

    source = argv[optind];

    target = argv[optind + 1];

    /* In the following, -1 as the 'dirfd' argument ensures that

       open_tree() fails if 'source' is not an absolute pathname. */

    fd_tree = open_tree(-1, source,

                        OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC |

                        AT_EMPTY_PATH | (recursive ? AT_RECURSIVE : 0));

    if (fd_tree == -1)

        err(EXIT_FAILURE, "open(%s)", source);

    if (fd_userns >= 0) {

        attr->attr_set  |= MOUNT_ATTR_IDMAP;

        attr->userns_fd = fd_userns;

    }

    ret = mount_setattr(fd_tree, "",

                        AT_EMPTY_PATH | (recursive ? AT_RECURSIVE : 0),

                        attr, sizeof(struct mount_attr));

    if (ret == -1)

        err(EXIT_FAILURE, "mount_setattr");

    close(fd_userns);

    /* In the following, -1 as the 'to_dirfd' argument ensures that

       open_tree() fails if 'target' is not an absolute pathname. */

    ret = move_mount(fd_tree, "", -1, target,

                     MOVE_MOUNT_F_EMPTY_PATH);

    if (ret == -1)

        err(EXIT_FAILURE, "move_mount() to %s", target);

    close(fd_tree);

    exit(EXIT_SUCCESS);
}
```

## SEE ALSO
newgidmap(1), newuidmap(1), clone(2), mount(2), unshare(2), proc(5), capabilities(7), mount_namespaces(7), user_namespaces(7), xattr(7)


title: move_pages(2)

text:
# move_pages(2)

## NAME
move_pages - move individual pages of a process to another node

## LIBRARY
NUMA (Non-Uniform Memory Access) policy library (libnuma, -lnuma)

## SYNOPSIS

```
#include <numaif.h>
```

```
long move_pages(int pid, unsigned long count, void *pages[.count],
                const int nodes[.count], int status[.count], int flags);
```

## DESCRIPTION
move_pages() moves the specified pages of the process pid to the memory nodes specified by nodes. The result of the move is reflected in status. The flags indicate constraints on the pages to be moved.

pid is the ID of the process in which pages are to be moved. If pid is 0, then move_pages() moves pages of the calling process.

To move pages in another process requires the following privileges:

•

Up to and including Linux 4.12: the caller must be privileged (CAP_SYS_NICE) or the real or effective user ID of the calling process must match the real or saved-set user ID of the target process.

•

The older rules allowed the caller to discover various virtual address choices made by the kernel that could lead to the defeat of address-space-layout randomization for a process owned by the same UID as the caller, the rules were changed starting with Linux 4.13. Since Linux 4.13, permission is governed by a ptrace access mode PTRACE_MODE_READ_REALCREDS check with respect to the target process; see ptrace(2).

count is the number of pages to move. It defines the size of the three arrays pages, nodes, and status.

pages is an array of pointers to the pages that should be moved. These are pointers that should be aligned to page boundaries. Addresses are specified as seen by the process specified by pid.

nodes is an array of integers that specify the desired location for each page. Each element in the array is a node number. nodes can also be NULL, in which case move_pages() does not move any pages but instead will return the node where each page currently resides, in the status array. Obtaining the status of each page may be necessary to determine pages that need to be moved.

status is an array of integers that return the status of each page. The array contains valid values only if move_pages() did not return an error. Preinitialization of the array to a value which cannot represent a real numa node or valid error of status array could help to identify pages that have been migrated.

flags specify what types of pages to move. MPOL_MF_MOVE means that only pages that are in exclusive use by the process are to be moved. MPOL_MF_MOVE_ALL means that pages shared between multiple processes can also be moved. The process must be privileged (CAP_SYS_NICE) to use MPOL_MF_MOVE_ALL.

### Page states in the status array
The following values can be returned in each element of the status array.

0..MAX_NUMNODES

Identifies the node on which the page resides.

-EACCES

The page is mapped by multiple processes and can be moved only if MPOL_MF_MOVE_ALL is specified.

-EBUSY

The page is currently busy and cannot be moved. Try again later. This occurs if a page is undergoing I/O or another kernel subsystem is holding a reference to the page.

-EFAULT

This is a zero page or the memory area is not mapped by the process.

-EIO

Unable to write back a page. The page has to be written back in order to move it since the page is dirty and the filesystem does not provide a migration function that would allow the move of dirty pages.

-EINVAL

A dirty page cannot be moved. The filesystem does not provide a migration function and has no ability to write back pages.

-ENOENT

The page is not present.

-ENOMEM

Unable to allocate memory on target node.

## RETURN VALUE
On success move_pages() returns zero. On error, it returns -1, and sets errno to indicate the error. If positive value is returned, it is the number of nonmigrated pages.

## ERRORS
Positive value

The number of nonmigrated pages if they were the result of nonfatal reasons (since Linux 4.17).

E2BIG

Too many pages to move. Since Linux 2.6.29, the kernel no longer generates this error.

EACCES

One of the target nodes is not allowed by the current cpuset.

EFAULT

Parameter array could not be accessed.

EINVAL

Flags other than MPOL_MF_MOVE and MPOL_MF_MOVE_ALL was specified or an attempt was made to migrate pages of a kernel thread.

ENODEV

One of the target nodes is not online.

EPERM

The caller specified MPOL_MF_MOVE_ALL without sufficient privileges (CAP_SYS_NICE). Or, the caller attempted to move pages of a process belonging to another user but did not have privilege to do so (CAP_SYS_NICE).

ESRCH

Process does not exist.

## STANDARDS
Linux.

## HISTORY
Linux 2.6.18.

## NOTES
For information on library support, see numa(7).

Use get_mempolicy(2) with the MPOL_F_MEMS_ALLOWED flag to obtain the set of nodes that are allowed by the current cpuset. Note that this information is subject to change at any time by manual or automatic reconfiguration of the cpuset.

Use of this function may result in pages whose location (node) violates the memory policy established for the specified addresses (See mbind(2)) and/or the specified process (See set_mempolicy(2)). That is, memory policy does not constrain the destination nodes used by move_pages().

The <numaif.h> header is not included with glibc, but requires installing libnuma-devel or a similar package.

## SEE ALSO
get_mempolicy(2), mbind(2), set_mempolicy(2), numa(3), numa_maps(5), cpuset(7), numa(7), migratepages(8), numastat(8)


mprotect

title: mprotect(2)

summary: set protection on a region of memory

text:
# mprotect(2)

## NAME
mprotect, pkey_mprotect - set protection on a region of memory

## LIBRARY
Standard C library (libc, -lc)

## SYNOPSIS

```
#include <sys/mman.h>
```

```
int mprotect(void addr[.len], size_t len, int prot);
```

```
#define _GNU_SOURCE             /* See feature_test_macros(7) */
#include <sys/mman.h>
```

```
int pkey_mprotect(void addr[.len], size_t len, int prot, int pkey);
```

## DESCRIPTION
mprotect() changes the access protections for the calling process's memory pages containing any part of the address range in the interval [addr, addr+len-1]. addr must be aligned to a page boundary.

If the calling process tries to access memory in a manner that violates the protections, then the kernel generates a SIGSEGV signal for the process.

prot is a combination of the following access flags: PROT_NONE or a bitwise OR of the other values in the following list:

PROT_NONE

The memory cannot be accessed at all.

PROT_READ

The memory can be read.

PROT_WRITE

The memory can be modified.

PROT_EXEC

The memory can be executed.

PROT_SEM (since Linux 2.5.7)

The memory can be used for atomic operations. This flag was introduced as part of the futex(2) implementation (in order to guarantee the ability to perform atomic operations required by commands such as FUTEX_WAIT), but is not currently used in on any architecture.

PROT_SAO (since Linux 2.6.26)

The memory should have strong access ordering. This feature is specific to the PowerPC architecture (version 2.06 of the architecture specification adds the SAO CPU feature, and it is available on POWER 7 or PowerPC A2, for example).

Additionally (since Linux 2.6.0), prot can have one of the following flags set:

PROT_GROWSUP

Apply the protection mode up to the end of a mapping that grows upwards. (Such mappings are created for the stack area on architectures—for example, HP-PARISC—that have an upwardly growing stack.)

PROT_GROWSDOWN

Apply the protection mode down to the beginning of a mapping that grows downward (which should be a stack segment or a segment mapped with the MAP_GROWSDOWN flag set).

Like mprotect(), pkey_mprotect() changes the protection on the pages specified by addr and len. The pkey argument specifies the protection key (see pkeys(7)) to assign to the memory. The protection key must be allocated with pkey_alloc(2) before it is passed to pkey_mprotect(). For an example of the use of this system call, see pkeys(7).

## RETURN VALUE
On success, mprotect() and pkey_mprotect() return zero. On error, these system calls return -1, and errno is set to indicate the error.

## ERRORS
EACCES

The memory cannot be given the specified access. This can happen, for example, if you mmap(2) a file to which you have read-only access, then ask mprotect() to mark it PROT_WRITE.

EINVAL

addr is not a valid pointer, or not a multiple of the system page size.

EINVAL

(pkey_mprotect()) pkey has not been allocated with pkey_alloc(2)

EINVAL

Both PROT_GROWSUP and PROT_GROWSDOWN were specified in prot.

EINVAL

Invalid flags specified in prot.

EINVAL

(PowerPC architecture) PROT_SAO was specified in prot, but SAO hardware feature is not available.

ENOMEM

Internal kernel structures could not be allocated.

ENOMEM

Addresses in the range [addr, addr+len-1] are invalid for the address space of the process, or specify one or more pages that are not mapped. (Before Linux 2.4.19, the error EFAULT was incorrectly produced for these cases.)

ENOMEM

Changing the protection of a memory region would result in the total number of mappings with distinct attributes (e.g., read versus read/write protection) exceeding the allowed maximum. (For example, making the protection of a range PROT_READ in the middle of a region currently protected as PROT_READ|PROT_WRITE would result in three mappings: two read/write mappings at each end and a read-only mapping in the middle.)

## VERSIONS
POSIX says that the behavior of mprotect() is unspecified if it is applied to a region of memory that was not obtained via mmap(2).

On Linux, it is always permissible to call mprotect() on any address in a process's address space (except for the kernel vsyscall area). In particular, it can be used to change existing code mappings to be writable.

Whether PROT_EXEC has any effect different from PROT_READ depends on processor architecture, kernel version, and process state. If READ_IMPLIES_EXEC is set in the process's personality flags (see personality(2)), specifying PROT_READ will implicitly add PROT_EXEC.

On some hardware architectures (e.g., i386), PROT_WRITE implies PROT_READ.

POSIX.1 says that an implementation may permit access other than that specified in prot, but at a minimum can allow write access only if PROT_WRITE has been set, and must not allow any access if PROT_NONE has been set.

Applications should be careful when mixing use of mprotect() and pkey_mprotect(). On x86, when mprotect() is used with prot set to PROT_EXEC a pkey may be allocated and set on the memory implicitly by the kernel, but only when the pkey was 0 previously.

On systems that do not support protection keys in hardware, pkey_mprotect() may still be used, but pkey must be set to -1. When called this way, the operation of pkey_mprotect() is equivalent to mprotect().

## STANDARDS
mprotect()

POSIX.1-2008.

pkey_mprotect()

Linux.

## HISTORY
mprotect()

POSIX.1-2001, SVr4.

pkey_mprotect()

Linux 4.9, glibc 2.27.

## EXAMPLES
The program below demonstrates the use of mprotect(). The program allocates four pages of memory, makes the third of these pages read-only, and then executes a loop that walks upward through the allocated region modifying bytes.

An example of what we might see when running the program is the following:

```
$ ./a.out
Start of region:        0x804c000
Got SIGSEGV at address: 0x804e000
```

### Program source

```
#include <malloc.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>
#define handle_error(msg) \

    do { perror(msg); exit(EXIT_FAILURE); } while (0)
static char *buffer;
static void
handler(int sig, siginfo_t *si, void *unused)
{

    /* Note: calling printf() from a signal handler is not safe

       (and should not be done in production programs), since

       printf() is not async-signal-safe; see signal-safety(7).

       Nevertheless, we use printf() here as a simple way of

       showing that the handler was called. */

    printf("Got SIGSEGV at address: %p\n", si->si_addr);

    exit(EXIT_FAILURE);
}
int
main(void)
{

    int               pagesize;

    struct sigaction  sa;

    sa.sa_flags = SA_SIGINFO;

    sigemptyset(&sa.sa_mask);

    sa.sa_sigaction = handler;

    if (sigaction(SIGSEGV, &sa, NULL) == -1)

        handle_error("sigaction");

    pagesize = sysconf(_SC_PAGE_SIZE);

    if (pagesize == -1)

        handle_error("sysconf");

    /* Allocate a buffer aligned on a page boundary;

       initial protection is PROT_READ | PROT_WRITE. */

    buffer = memalign(pagesize, 4 * pagesize);

    if (buffer == NULL)

        handle_error("memalign");

    printf("Start of region:        %p\n", buffer);

    if (mprotect(buffer + pagesize * 2, pagesize,

                 PROT_READ) == -1)

        handle_error("mprotect");

    for (char *p = buffer ; ; )

        *(p++) = 'a';

    printf("Loop completed\n");     /* Should never happen */

    exit(EXIT_SUCCESS);
}
```

## SEE ALSO
mmap(2), sysconf(3), pkeys(7)


title: mq_getsetattr(2)

summary: get/set message queue attributes

text:
# mq_getsetattr(2)

## NAME
mq_getsetattr - get/set message queue attributes

## SYNOPSIS

```
#include <mqueue.h>           /* Definition of struct mq_attr */
#include <sys/syscall.h>      /* Definition of SYS_* constants */
#include <unistd.h>
```

```
int syscall(SYS_mq_getsetattr, mqd_t mqdes,
            const struct mq_attr *newattr, struct mq_attr *oldattr);
```

## DESCRIPTION
Do not use this system call.

This is the low-level system call used to implement mq_getattr(3) and mq_setattr(3). For an explanation of how this system call operates, see the description of mq_setattr(3).

## STANDARDS
None.

## NOTES
Never call it unless you are writing a C library!

## SEE ALSO
mq_getattr(3), mq_overview(7)


mremap

title: mremap(2)

summary: remap a virtual memory address

text:
# mremap(2)

## NAME
mremap - remap a virtual memory address

## LIBRARY
Standard C library (libc, -lc)

## SYNOPSIS

```
#define _GNU_SOURCE         /* See feature_test_macros(7) */
#include <sys/mman.h>
```

```
void *mremap(void old_address[.old_size], size_t old_size,
             size_t new_size, int flags, ... /* void *new_address */);
```

## DESCRIPTION
mremap() expands (or shrinks) an existing memory mapping, potentially moving it at the same time (controlled by the flags argument and the available virtual address space).

old_address is the old address of the virtual memory block that you want to expand (or shrink). Note that old_address has to be page aligned. old_size is the old size of the virtual memory block. new_size is the requested size of the virtual memory block after the resize. An optional fifth argument, new_address, may be provided; see the description of MREMAP_FIXED below.

If the value of old_size is zero, and old_address refers to a shareable mapping (see mmap(2) MAP_SHARED), 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.

The flags bit-mask argument may be 0, or include the following flags:

MREMAP_MAYMOVE

By default, if there is not sufficient space to expand a mapping at its current location, then mremap() fails. If this flag is specified, then the kernel is permitted to relocate the mapping to a new virtual address, if necessary. If the mapping is relocated, then absolute pointers into the old mapping location become invalid (offsets relative to the starting address of the mapping should be employed).

MREMAP_FIXED (since Linux 2.3.31)

This flag serves a similar purpose to the MAP_FIXED flag of mmap(2). If this flag is specified, then mremap() accepts a fifth argument, void *new_address, which specifies a page-aligned address to which the mapping must be moved. Any previous mapping at the address range specified by new_address and new_size is unmapped.

If MREMAP_FIXED is specified, then MREMAP_MAYMOVE must also be specified.

MREMAP_DONTUNMAP (since Linux 5.7)

This flag, which must be used in conjunction with MREMAP_MAYMOVE, remaps a mapping to a new address but does not unmap the mapping at old_address.

The MREMAP_DONTUNMAP flag can be used only with private anonymous mappings (see the description of MAP_PRIVATE and MAP_ANONYMOUS in mmap(2)).

After completion, any access to the range specified by old_address and old_size will result in a page fault. The page fault will be handled by a userfaultfd(2) handler if the address is in a range previously registered with userfaultfd(2). Otherwise, the kernel allocates a zero-filled page to handle the fault.

The MREMAP_DONTUNMAP flag may be used to atomically move a mapping while leaving the source mapped. See NOTES for some possible applications of MREMAP_DONTUNMAP.

If the memory segment specified by old_address and old_size is locked (using mlock(2) or similar), then this lock is maintained when the segment is resized and/or relocated. As a consequence, the amount of memory locked by the process may change.

## RETURN VALUE
On success mremap() returns a pointer to the new virtual memory area. On error, the value MAP_FAILED (that is, (void *) -1) is returned, and errno is set to indicate the error.

## ERRORS
EAGAIN

The caller tried to expand a memory segment that is locked, but this was not possible without exceeding the RLIMIT_MEMLOCK resource limit.

EFAULT

Some address in the range old_address to old_address+old_size is an invalid virtual memory address for this process. You can also get EFAULT even if there exist mappings that cover the whole address space requested, but those mappings are of different types.

EINVAL

An invalid argument was given. Possible causes are:

•

old_address was not page aligned;

•

a value other than MREMAP_MAYMOVE or MREMAP_FIXED or MREMAP_DONTUNMAP was specified in flags;

•

new_size was zero;

•

new_size or new_address was invalid;

•

the new address range specified by new_address and new_size overlapped the old address range specified by old_address and old_size;

•

MREMAP_FIXED or MREMAP_DONTUNMAP was specified without also specifying MREMAP_MAYMOVE;

•

MREMAP_DONTUNMAP was specified, but one or more pages in the range specified by old_address and old_size were not private anonymous;

•

MREMAP_DONTUNMAP was specified and old_size was not equal to new_size;

•

old_size was zero and old_address does not refer to a shareable mapping (but see BUGS);

•

old_size was zero and the MREMAP_MAYMOVE flag was not specified.

ENOMEM

Not enough memory was available to complete the operation. Possible causes are:

•

The memory area cannot be expanded at the current virtual address, and the MREMAP_MAYMOVE flag is not set in flags. Or, there is not enough (virtual) memory available.

•

MREMAP_DONTUNMAP was used causing a new mapping to be created that would exceed the (virtual) memory available. Or, it would exceed the maximum number of allowed mappings.

## STANDARDS
Linux.

## HISTORY
Prior to glibc 2.4, glibc did not expose the definition of MREMAP_FIXED, and the prototype for mremap() did not allow for the new_address argument.

## NOTES
mremap() changes the mapping between virtual addresses and memory pages. This can be used to implement a very efficient realloc(3).

In Linux, memory is divided into pages. A process has (one or) several linear virtual memory segments. Each virtual memory segment has one or more mappings to real memory pages (in the page table). Each virtual memory segment has its own protection (access rights), which may cause a segmentation violation (SIGSEGV) if the memory is accessed incorrectly (e.g., writing to a read-only segment). Accessing virtual memory outside of the segments will also cause a segmentation violation.

If mremap() is used to move or expand an area locked with mlock(2) or equivalent, the mremap() call will make a best effort to populate the new area but will not fail with ENOMEM if the area cannot be populated.

### MREMAP_DONTUNMAP use cases
Possible applications for MREMAP_DONTUNMAP include:

•

Non-cooperative userfaultfd(2): an application can yank out a virtual address range using MREMAP_DONTUNMAP and then employ a userfaultfd(2) handler to handle the page faults that subsequently occur as other threads in the process touch pages in the yanked range.

•

Garbage collection: MREMAP_DONTUNMAP can be used in conjunction with userfaultfd(2) to implement garbage collection algorithms (e.g., in a Java virtual machine). Such an implementation can be cheaper (and simpler) than conventional garbage collection techniques that involve marking pages with protection PROT_NONE in conjunction with the use of a SIGSEGV handler to catch accesses to those pages.

## BUGS
Before Linux 4.14, if old_size was zero and the mapping referred to by old_address was a private mapping (mmap(2) MAP_PRIVATE), mremap() created a new private mapping unrelated to the original mapping. This behavior was unintended and probably unexpected in user-space applications (since the intention of mremap() is to create a new mapping based on the original mapping). Since Linux 4.14, mremap() fails with the error EINVAL in this scenario.

## SEE ALSO
brk(2), getpagesize(2), getrlimit(2), mlock(2), mmap(2), sbrk(2), malloc(3), realloc(3)

Your favorite text book on operating systems for more information on paged memory (e.g., Modern Operating Systems by Andrew S. Tanenbaum, Inside Linux by Randolph Bentson, The Design of the UNIX Operating System by Maurice J. Bach)