Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

mseal(2)

FieldValue
Numbers (x64 / i386 / arm64-generic / arm32)462 / 462 / 462 / 462 (hub)
Since (kernel)6.10 (hub; worklog 1-b tag-probed absent 6.9 / present 6.10)
Man pagenone (no man2/mseal.2 exists as of man-pages 6.19; documented from kernel source: mm/mseal.c + Documentation/userspace-api/mseal.rst, both fetched – this page is a source-sourced entry, marked as such)
glibc wrappernone in release glibc; glibc NEWS 2.43 (development section of the cached snapshot): “On Linux, the mseal function has been added. It allows for sealing memory mappings to prevent further changes during process execution, such as changes to protection permissions, unmapping, relocation to another location, or shrinking the size.”
Aliases coverednone
Ledger IDSC-mseal

Purpose

mseal() seals a virtual memory range: after the call, the kernel blocks mm syscalls that would modify the sealed mapping’s attributes or layout – munmap(2) (munmap), mmap(2) (mmap), mremap(2) (mremap), mprotect(2) and pkey_mprotect(2) (mprotect), and the destructive madvise behaviors MADV_DONTNEED, MADV_FREE, MADV_DONTNEED_LOCKED, MADV_WIPEONFORK and MADV_DONTFORK (mseal.rst list). Blocked calls fail with EPERM. The goal is fault mitigation: a corrupted pointer can no longer turn .text/.rodata writable or remap trusted memory (mseal.rst; same idea as XNU VM_FLAGS_PERMANENT and OpenBSD mimmutable).

Synopsis

/* kernel 6.10+, 64-bit only; no libc declaration in release glibc */
int mseal(void *addr, size_t len, unsigned long flags);

(mseal.rst signature; mm/mseal.c implements SYSCALL_DEFINE3(mseal, unsigned long, start, size_t, len, unsigned long, flags).)

Arguments and behavior

addr/len name the range: start must be page-aligned (after untagged_addr) inside an allocated VMA, the end must lie in an allocated VMA with no gap; len is page-aligned implicitly by the kernel. flags is reserved and must be 0 (mm/mseal.c returns EINVAL otherwise). Sealing is idempotent: re-sealing an already sealed range is a no-action, not an error. There is no munseal, consistent with F_SEAL_SEAL for files; a sealed mapping stays until the process terminates or execve(2) (mseal.rst).

Return value and errors

0 on success; negated errors from the raw call: EINVAL (flags nonzero, unaligned start, addr+len overflow), ENOMEM (start or end unallocated, gap in range), ENOSYS (kernel without mseal, and 32-bit kernels: the feature is built only for 64-bit kernels per mseal.rst). For these errors the range is left unmodified; internal errors (VMA merge/split, max-VMA count) may partially update the range. Blocked-syscall EPERM return is atomic for munmap; mprotect/madvise may have partially applied changes; mmap/mremap is undefined (mseal.rst).

Flags and constants

None: flags must be 0. Config gates: CONFIG_ARCH_HAS_MMAP_SEAL / mseal support in mm/mseal.c; CONFIG_MSEAL_SYSTEM_MAPPINGS seals kernel created system mappings (vdso, vvar, vectors, sigpage, uprobes) on architectures with CONFIG_ARCH_SUPPORTS_MSEAL_SYSTEM_MAPPINGS (mseal.rst).

Security and notes

  • mseal does not make memory immutable: /proc/self/mem (FOLL_FORCE), ptrace PTRACE_POKETEXT and userfaultfd can still write read-only sealed pages (mseal.rst, crediting Jann Horn’s analysis).
  • Do not seal malloc’d heap: the allocator must shrink/unmap (mseal.rst “When not to use mseal”); same warning for aio/shm-managed mappings.
  • Since 6.10 (worklog 1-b); no man page – all semantics here are from the kernel sources named above.

References

  • Kernel source: source-cache/fetched/master-mm-mseal.c; master-Documentation-userspace-api-mseal.rst (author Jeff Xu).
  • glibc NEWS: source-cache/glibc-sparse/NEWS (2.43 section, mseal).
  • Numbers/Since: hub overview; worklog Task 1-b.