€•oÅŒsphinx.addnodes”Œdocument”“”)�”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)�”}”(hhh]”(hŒ pending_xref”“”)�”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…”�”}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ'/translations/zh_CN/userspace-api/mseal”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)�”}”(hhh]”hŒChinese (Traditional)”…”�”}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/zh_TW/userspace-api/mseal”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒItalian”…”�”}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/it_IT/userspace-api/mseal”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒJapanese”…”�”}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/ja_JP/userspace-api/mseal”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒKorean”…”�”}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/ko_KR/userspace-api/mseal”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒPortuguese (Brazilian)”…”�”}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/pt_BR/userspace-api/mseal”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒSpanish”…”�”}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/sp_SP/userspace-api/mseal”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒcomment”“”)�”}”(hŒ SPDX-License-Identifier: GPL-2.0”h]”hŒ SPDX-License-Identifier: GPL-2.0”…”�”}”hh·sbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1hµhhh²hh³ŒA/var/lib/git/docbuild/linux/Documentation/userspace-api/mseal.rst”h´KubhŒsection”“”)�”}”(hhh]”(hŒtitle”“”)�”}”(hŒIntroduction of mseal”h]”hŒIntroduction of mseal”…”�”}”(hhÏh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhhÊh²hh³hÇh´KubhŒ field_list”“”)�”}”(hhh]”hŒfield”“”)�”}”(hhh]”(hŒ field_name”“”)�”}”(hŒAuthor”h]”hŒAuthor”…”�”}”(hhéh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hçhhäh³hÇh´KubhŒ field_body”“”)�”}”(hŒJeff Xu ”h]”hŒ paragraph”“”)�”}”(hŒJeff Xu ”h]”(hŒ Jeff Xu <”…”�”}”(hhÿh²hh³Nh´NubhŒ reference”“”)�”}”(hŒjeffxu@chromium.org”h]”hŒjeffxu@chromium.org”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”Œmailto:jeffxu@chromium.org”uh1jhhÿubhŒ>”…”�”}”(hhÿh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´Khhùubah}”(h]”h ]”h"]”h$]”h&]”uh1h÷hhäubeh}”(h]”h ]”h"]”h$]”h&]”uh1hâh³hÇh´Khhßh²hubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝhhÊh²hh³hÇh´Kubhþ)�”}”(hX-Modern CPUs support memory permissions such as RW and NX bits. The memory permission feature improves security stance on memory corruption bugs, i.e. the attacker can’t just write to arbitrary memory and point the code to it, the memory has to be marked with X bit, or else an exception will happen.”h]”hX-Modern CPUs support memory permissions such as RW and NX bits. The memory permission feature improves security stance on memory corruption bugs, i.e. the attacker can’t just write to arbitrary memory and point the code to it, the memory has to be marked with X bit, or else an exception will happen.”…”�”}”(hj5h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K hhÊh²hubhþ)�”}”(hX0Memory sealing additionally protects the mapping itself against modifications. This is useful to mitigate memory corruption issues where a corrupted pointer is passed to a memory management system. For example, such an attacker primitive can break control-flow integrity guarantees since read-only memory that is supposed to be trusted can become writable or .text pages can get remapped. Memory sealing can automatically be applied by the runtime loader to seal .text and .rodata pages and applications can additionally seal security critical data at runtime.”h]”hX0Memory sealing additionally protects the mapping itself against modifications. This is useful to mitigate memory corruption issues where a corrupted pointer is passed to a memory management system. For example, such an attacker primitive can break control-flow integrity guarantees since read-only memory that is supposed to be trusted can become writable or .text pages can get remapped. Memory sealing can automatically be applied by the runtime loader to seal .text and .rodata pages and applications can additionally seal security critical data at runtime.”…”�”}”(hjCh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KhhÊh²hubhþ)�”}”(hŒ‡A similar feature already exists in the XNU kernel with the VM_FLAGS_PERMANENT flag [1] and on OpenBSD with the mimmutable syscall [2].”h]”hŒ‡A similar feature already exists in the XNU kernel with the VM_FLAGS_PERMANENT flag [1] and on OpenBSD with the mimmutable syscall [2].”…”�”}”(hjQh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KhhÊh²hubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒSYSCALL”h]”hŒSYSCALL”…”�”}”(hjbh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj_h²hh³hÇh´KubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒmseal syscall signature”h]”hŒmseal syscall signature”…”�”}”(hjsh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjph²hh³hÇh´KubhŒ block_quote”“”)�”}”(hX'``int mseal(void *addr, size_t len, unsigned long flags)`` **addr**/**len**: virtual memory address range. The address range set by **addr**/**len** must meet: - The start address must be in an allocated VMA. - The start address must be page aligned. - The end address (**addr** + **len**) must be in an allocated VMA. - no gap (unallocated memory) between start and end address. The ``len`` will be paged aligned implicitly by the kernel. **flags**: reserved for future use. **Return values**: - **0**: Success. - **-EINVAL**: * Invalid input ``flags``. * The start address (``addr``) is not page aligned. * Address range (``addr`` + ``len``) overflow. - **-ENOMEM**: * The start address (``addr``) is not allocated. * The end address (``addr`` + ``len``) is not allocated. * A gap (unallocated memory) between start and end address. - **-ENOSYS**: * The kernel does not implement ``mseal()``. **Note about error return**: - For above error cases, users can expect the given memory range is unmodified, i.e. no partial update. - There might be other internal errors/cases not listed here, e.g. error during merging/splitting VMAs, or the process reaching the maximum number of supported VMAs. In those cases, partial updates to the given memory range could happen. However, those cases should be rare. **Architecture support**: mseal is built only for 64-bit kernels. 32-bit kernels return ``-ENOSYS``. **Idempotent**: users can call mseal multiple times. mseal on an already sealed memory is a no-action (not error). **no munseal** Once mapping is sealed, it can't be unsealed. The kernel should never have munseal, this is consistent with other sealing feature, e.g. F_SEAL_SEAL for file. ”h]”(hþ)�”}”(hŒ:``int mseal(void *addr, size_t len, unsigned long flags)``”h]”hŒliteral”“”)�”}”(hj‰h]”hŒ6int mseal(void *addr, size_t len, unsigned long flags)”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j‹hj‡ubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KhjƒubhŒdefinition_list”“”)�”}”(hhh]”hŒdefinition_list_item”“”)�”}”(hXŠ**addr**/**len**: virtual memory address range. The address range set by **addr**/**len** must meet: - The start address must be in an allocated VMA. - The start address must be page aligned. - The end address (**addr** + **len**) must be in an allocated VMA. - no gap (unallocated memory) between start and end address. The ``len`` will be paged aligned implicitly by the kernel. ”h]”(hŒterm”“”)�”}”(hŒ/**addr**/**len**: virtual memory address range.”h]”(hŒstrong”“”)�”}”(hŒ**addr**”h]”hŒaddr”…”�”}”(hj³h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j±hj­ubhŒ/”…”�”}”(hj­h²hh³Nh´Nubj²)�”}”(hŒ**len**”h]”hŒlen”…”�”}”(hjÅh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j±hj­ubhŒ: virtual memory address range.”…”�”}”(hj­h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1j«h³hÇh´K'hj§ubhŒ definition”“”)�”}”(hhh]”(j¡)�”}”(hhh]”j¦)�”}”(hXThe address range set by **addr**/**len** must meet: - The start address must be in an allocated VMA. - The start address must be page aligned. - The end address (**addr** + **len**) must be in an allocated VMA. - no gap (unallocated memory) between start and end address. ”h]”(j¬)�”}”(hŒ4The address range set by **addr**/**len** must meet:”h]”(hŒThe address range set by ”…”�”}”(hjéh²hh³Nh´Nubj²)�”}”(hŒ**addr**”h]”hŒaddr”…”�”}”(hjñh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j±hjéubhŒ/”…”�”}”(hjéh²hh³Nh´Nubj²)�”}”(hŒ**len**”h]”hŒlen”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j±hjéubhŒ must meet:”…”�”}”(hjéh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1j«h³hÇh´K%hjåubjÞ)�”}”(hhh]”hŒ bullet_list”“”)�”}”(hhh]”(hŒ list_item”“”)�”}”(hŒ.The start address must be in an allocated VMA.”h]”hþ)�”}”(hj'h]”hŒ.The start address must be in an allocated VMA.”…”�”}”(hj)h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K"hj%ubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj ubj$)�”}”(hŒ'The start address must be page aligned.”h]”hþ)�”}”(hj>h]”hŒ'The start address must be page aligned.”…”�”}”(hj@h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K#hj<ubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj ubj$)�”}”(hŒAThe end address (**addr** + **len**) must be in an allocated VMA.”h]”hþ)�”}”(hjUh]”(hŒThe end address (”…”�”}”(hjWh²hh³Nh´Nubj²)�”}”(hŒ**addr**”h]”hŒaddr”…”�”}”(hj^h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j±hjWubhŒ + ”…”�”}”(hjWh²hh³Nh´Nubj²)�”}”(hŒ**len**”h]”hŒlen”…”�”}”(hjph²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j±hjWubhŒ) must be in an allocated VMA.”…”�”}”(hjWh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K$hjSubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj ubj$)�”}”(hŒ;no gap (unallocated memory) between start and end address. ”h]”hþ)�”}”(hŒ:no gap (unallocated memory) between start and end address.”h]”hŒ:no gap (unallocated memory) between start and end address.”…”�”}”(hj’h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K%hjŽubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj ubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ-”uh1jh³hÇh´K"hjubah}”(h]”h ]”h"]”h$]”h&]”uh1jÝhjåubeh}”(h]”h ]”h"]”h$]”h&]”uh1j¥h³hÇh´K%hjâubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjßubhþ)�”}”(hŒ;The ``len`` will be paged aligned implicitly by the kernel.”h]”(hŒThe ”…”�”}”(hjÀh²hh³Nh´NubjŒ)�”}”(hŒ``len``”h]”hŒlen”…”�”}”(hjÈh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j‹hjÀubhŒ0 will be paged aligned implicitly by the kernel.”…”�”}”(hjÀh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K'hjßubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÝhj§ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j¥h³hÇh´K'hj¢ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjƒubhþ)�”}”(hŒ#**flags**: reserved for future use.”h]”(j²)�”}”(hŒ **flags**”h]”hŒflags”…”�”}”(hjöh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j±hjòubhŒ: reserved for future use.”…”�”}”(hjòh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K)hjƒubj¡)�”}”(hhh]”(j¦)�”}”(hX¸**Return values**: - **0**: Success. - **-EINVAL**: * Invalid input ``flags``. * The start address (``addr``) is not page aligned. * Address range (``addr`` + ``len``) overflow. - **-ENOMEM**: * The start address (``addr``) is not allocated. * The end address (``addr`` + ``len``) is not allocated. * A gap (unallocated memory) between start and end address. - **-ENOSYS**: * The kernel does not implement ``mseal()``. ”h]”(j¬)�”}”(hŒ**Return values**:”h]”(j²)�”}”(hŒ**Return values**”h]”hŒ Return values”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j±hjubhŒ:”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1j«h³hÇh´K6hjubjÞ)�”}”(hhh]”j)�”}”(hhh]”(j$)�”}”(hŒ**0**: Success.”h]”hþ)�”}”(hj9h]”(j²)�”}”(hŒ**0**”h]”hŒ0”…”�”}”(hj>h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j±hj;ubhŒ : Success.”…”�”}”(hj;h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K,hj7ubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj4ubj$)�”}”(hŒ�**-EINVAL**: * Invalid input ``flags``. * The start address (``addr``) is not page aligned. * Address range (``addr`` + ``len``) overflow.”h]”j¡)�”}”(hhh]”j¦)�”}”(hŒŠ**-EINVAL**: * Invalid input ``flags``. * The start address (``addr``) is not page aligned. * Address range (``addr`` + ``len``) overflow.”h]”(j¬)�”}”(hŒ **-EINVAL**:”h]”(j²)�”}”(hŒ **-EINVAL**”h]”hŒ-EINVAL”…”�”}”(hjkh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j±hjgubhŒ:”…”�”}”(hjgh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1j«h³hÇh´K/hjcubjÞ)�”}”(hhh]”j)�”}”(hhh]”(j$)�”}”(hŒInvalid input ``flags``.”h]”hþ)�”}”(hj‹h]”(hŒInvalid input ”…”�”}”(hj�h²hh³Nh´NubjŒ)�”}”(hŒ ``flags``”h]”hŒflags”…”�”}”(hj”h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j‹hj�ubhŒ.”…”�”}”(hj�h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K.hj‰ubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj†ubj$)�”}”(hŒ1The start address (``addr``) is not page aligned.”h]”hþ)�”}”(hj´h]”(hŒThe start address (”…”�”}”(hj¶h²hh³Nh´NubjŒ)�”}”(hŒ``addr``”h]”hŒaddr”…”�”}”(hj½h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j‹hj¶ubhŒ) is not page aligned.”…”�”}”(hj¶h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K/hj²ubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj†ubj$)�”}”(hŒ,Address range (``addr`` + ``len``) overflow.”h]”hþ)�”}”(hjÝh]”(hŒAddress range (”…”�”}”(hjßh²hh³Nh´NubjŒ)�”}”(hŒ``addr``”h]”hŒaddr”…”�”}”(hjæh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j‹hjßubhŒ + ”…”�”}”(hjßh²hh³Nh´NubjŒ)�”}”(hŒ``len``”h]”hŒlen”…”�”}”(hjøh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j‹hjßubhŒ ) overflow.”…”�”}”(hjßh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K0hjÛubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj†ubeh}”(h]”h ]”h"]”h$]”h&]”j¬Œ*”uh1jh³hÇh´K.hjƒubah}”(h]”h ]”h"]”h$]”h&]”uh1jÝhjcubeh}”(h]”h ]”h"]”h$]”h&]”uh1j¥h³hÇh´K/hj`ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj\ubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj4ubj$)�”}”(hŒµ**-ENOMEM**: * The start address (``addr``) is not allocated. * The end address (``addr`` + ``len``) is not allocated. * A gap (unallocated memory) between start and end address.”h]”j¡)�”}”(hhh]”j¦)�”}”(hŒ²**-ENOMEM**: * The start address (``addr``) is not allocated. * The end address (``addr`` + ``len``) is not allocated. * A gap (unallocated memory) between start and end address.”h]”(j¬)�”}”(hŒ **-ENOMEM**:”h]”(j²)�”}”(hŒ **-ENOMEM**”h]”hŒ-ENOMEM”…”�”}”(hjDh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j±hj@ubhŒ:”…”�”}”(hj@h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1j«h³hÇh´K3hj<ubjÞ)�”}”(hhh]”j)�”}”(hhh]”(j$)�”}”(hŒ.The start address (``addr``) is not allocated.”h]”hþ)�”}”(hjdh]”(hŒThe start address (”…”�”}”(hjfh²hh³Nh´NubjŒ)�”}”(hŒ``addr``”h]”hŒaddr”…”�”}”(hjmh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j‹hjfubhŒ) is not allocated.”…”�”}”(hjfh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K2hjbubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj_ubj$)�”}”(hŒ6The end address (``addr`` + ``len``) is not allocated.”h]”hþ)�”}”(hj�h]”(hŒThe end address (”…”�”}”(hj�h²hh³Nh´NubjŒ)�”}”(hŒ``addr``”h]”hŒaddr”…”�”}”(hj–h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j‹hj�ubhŒ + ”…”�”}”(hj�h²hh³Nh´NubjŒ)�”}”(hŒ``len``”h]”hŒlen”…”�”}”(hj¨h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j‹hj�ubhŒ) is not allocated.”…”�”}”(hj�h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K3hj‹ubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj_ubj$)�”}”(hŒ9A gap (unallocated memory) between start and end address.”h]”hþ)�”}”(hjÈh]”hŒ9A gap (unallocated memory) between start and end address.”…”�”}”(hjÊh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K4hjÆubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj_ubeh}”(h]”h ]”h"]”h$]”h&]”j¬juh1jh³hÇh´K2hj\ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÝhj<ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j¥h³hÇh´K3hj9ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj5ubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj4ubj$)�”}”(hŒ;**-ENOSYS**: * The kernel does not implement ``mseal()``. ”h]”j¡)�”}”(hhh]”j¦)�”}”(hŒ:**-ENOSYS**: * The kernel does not implement ``mseal()``. ”h]”(j¬)�”}”(hŒ **-ENOSYS**:”h]”(j²)�”}”(hŒ **-ENOSYS**”h]”hŒ-ENOSYS”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j±hjubhŒ:”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1j«h³hÇh´K6hjubjÞ)�”}”(hhh]”j)�”}”(hhh]”j$)�”}”(hŒ+The kernel does not implement ``mseal()``. ”h]”hþ)�”}”(hŒ*The kernel does not implement ``mseal()``.”h]”(hŒThe kernel does not implement ”…”�”}”(hj,h²hh³Nh´NubjŒ)�”}”(hŒ ``mseal()``”h]”hŒmseal()”…”�”}”(hj4h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j‹hj,ubhŒ.”…”�”}”(hj,h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K6hj(ubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj%ubah}”(h]”h ]”h"]”h$]”h&]”j¬juh1jh³hÇh´K6hj"ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÝhjubeh}”(h]”h ]”h"]”h$]”h&]”uh1j¥h³hÇh´K6hjÿubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjûubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj4ubeh}”(h]”h ]”h"]”h$]”h&]”j¬j­uh1jh³hÇh´K,hj1ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÝhjubeh}”(h]”h ]”h"]”h$]”h&]”uh1j¥h³hÇh´K6hjubj¦)�”}”(hX **Note about error return**: - For above error cases, users can expect the given memory range is unmodified, i.e. no partial update. - There might be other internal errors/cases not listed here, e.g. error during merging/splitting VMAs, or the process reaching the maximum number of supported VMAs. In those cases, partial updates to the given memory range could happen. However, those cases should be rare. ”h]”(j¬)�”}”(hŒ**Note about error return**:”h]”(j²)�”}”(hŒ**Note about error return**”h]”hŒNote about error return”…”�”}”(hjŠh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j±hj†ubhŒ:”…”�”}”(hj†h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1j«h³hÇh´K>hj‚ubjÞ)�”}”(hhh]”j)�”}”(hhh]”(j$)�”}”(hŒeFor above error cases, users can expect the given memory range is unmodified, i.e. no partial update.”h]”hþ)�”}”(hŒeFor above error cases, users can expect the given memory range is unmodified, i.e. no partial update.”h]”hŒeFor above error cases, users can expect the given memory range is unmodified, i.e. no partial update.”…”�”}”(hj¬h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K9hj¨ubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj¥ubj$)�”}”(hXThere might be other internal errors/cases not listed here, e.g. error during merging/splitting VMAs, or the process reaching the maximum number of supported VMAs. In those cases, partial updates to the given memory range could happen. However, those cases should be rare. ”h]”hþ)�”}”(hXThere might be other internal errors/cases not listed here, e.g. error during merging/splitting VMAs, or the process reaching the maximum number of supported VMAs. In those cases, partial updates to the given memory range could happen. However, those cases should be rare.”h]”hXThere might be other internal errors/cases not listed here, e.g. error during merging/splitting VMAs, or the process reaching the maximum number of supported VMAs. In those cases, partial updates to the given memory range could happen. However, those cases should be rare.”…”�”}”(hjÄh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K;hjÀubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj¥ubeh}”(h]”h ]”h"]”h$]”h&]”j¬j­uh1jh³hÇh´K9hj¢ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÝhj‚ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j¥h³hÇh´K>hjubj¦)�”}”(hŒe**Architecture support**: mseal is built only for 64-bit kernels. 32-bit kernels return ``-ENOSYS``. ”h]”(j¬)�”}”(hŒ**Architecture support**:”h]”(j²)�”}”(hŒ**Architecture support**”h]”hŒArchitecture support”…”�”}”(hjòh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j±hjîubhŒ:”…”�”}”(hjîh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1j«h³hÇh´KBhjêubjÞ)�”}”(hhh]”hþ)�”}”(hŒJmseal is built only for 64-bit kernels. 32-bit kernels return ``-ENOSYS``.”h]”(hŒ>mseal is built only for 64-bit kernels. 32-bit kernels return ”…”�”}”(hj h²hh³Nh´NubjŒ)�”}”(hŒ ``-ENOSYS``”h]”hŒ-ENOSYS”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j‹hj ubhŒ.”…”�”}”(hj h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KAhj ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÝhjêubeh}”(h]”h ]”h"]”h$]”h&]”uh1j¥h³hÇh´KBhjubj¦)�”}”(hŒs**Idempotent**: users can call mseal multiple times. mseal on an already sealed memory is a no-action (not error). ”h]”(j¬)�”}”(hŒ**Idempotent**:”h]”(j²)�”}”(hŒ**Idempotent**”h]”hŒ Idempotent”…”�”}”(hjAh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j±hj=ubhŒ:”…”�”}”(hj=h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1j«h³hÇh´KFhj9ubjÞ)�”}”(hhh]”hþ)�”}”(hŒbusers can call mseal multiple times. mseal on an already sealed memory is a no-action (not error).”h]”hŒbusers can call mseal multiple times. mseal on an already sealed memory is a no-action (not error).”…”�”}”(hj\h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KEhjYubah}”(h]”h ]”h"]”h$]”h&]”uh1jÝhj9ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j¥h³hÇh´KFhjubj¦)�”}”(hŒ­**no munseal** Once mapping is sealed, it can't be unsealed. The kernel should never have munseal, this is consistent with other sealing feature, e.g. F_SEAL_SEAL for file. ”h]”(j¬)�”}”(hŒ**no munseal**”h]”j²)�”}”(hj|h]”hŒ no munseal”…”�”}”(hj~h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j±hjzubah}”(h]”h ]”h"]”h$]”h&]”uh1j«h³hÇh´KKhjvubjÞ)�”}”(hhh]”hþ)�”}”(hŒ�Once mapping is sealed, it can't be unsealed. The kernel should never have munseal, this is consistent with other sealing feature, e.g. F_SEAL_SEAL for file.”h]”hŒŸOnce mapping is sealed, it can’t be unsealed. The kernel should never have munseal, this is consistent with other sealing feature, e.g. F_SEAL_SEAL for file.”…”�”}”(hj”h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KIhj‘ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÝhjvubeh}”(h]”h ]”h"]”h$]”h&]”uh1j¥h³hÇh´KKhjubeh}”(h]”h ]”h"]”h$]”h&]”uh1j hjƒubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³hÇh´Khjph²hubeh}”(h]”Œmseal-syscall-signature”ah ]”h"]”Œmseal syscall signature”ah$]”h&]”uh1hÈhj_h²hh³hÇh´KubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ%Blocked mm syscall for sealed mapping”h]”hŒ%Blocked mm syscall for sealed mapping”…”�”}”(hjÅh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjÂh²hh³hÇh´KNubj‚)�”}”(hXoIt might be important to note: **once the mapping is sealed, it will stay in the process's memory until the process terminates**. Example:: *ptr = mmap(0, 4096, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); rc = mseal(ptr, 4096, 0); /* munmap will fail */ rc = munmap(ptr, 4096); assert(rc < 0); Blocked mm syscall: - munmap - mmap - mremap - mprotect and pkey_mprotect - some destructive madvise behaviors: MADV_DONTNEED, MADV_FREE, MADV_DONTNEED_LOCKED, MADV_FREE, MADV_DONTFORK, MADV_WIPEONFORK The first set of syscalls to block is munmap, mremap, mmap. They can either leave an empty space in the address space, therefore allowing replacement with a new mapping with new set of attributes, or can overwrite the existing mapping with another mapping. mprotect and pkey_mprotect are blocked because they changes the protection bits (RWX) of the mapping. Certain destructive madvise behaviors, specifically MADV_DONTNEED, MADV_FREE, MADV_DONTNEED_LOCKED, and MADV_WIPEONFORK, can introduce risks when applied to anonymous memory by threads lacking write permissions. Consequently, these operations are prohibited under such conditions. The aforementioned behaviors have the potential to modify region contents by discarding pages, effectively performing a memset(0) operation on the anonymous memory. Kernel will return -EPERM for blocked syscalls. When blocked syscall return -EPERM due to sealing, the memory regions may or may not be changed, depends on the syscall being blocked: - munmap: munmap is atomic. If one of VMAs in the given range is sealed, none of VMAs are updated. - mprotect, pkey_mprotect, madvise: partial update might happen, e.g. when mprotect over multiple VMAs, mprotect might update the beginning VMAs before reaching the sealed VMA and return -EPERM. - mmap and mremap: undefined behavior. ”h]”(hþ)�”}”(hŒ�It might be important to note: **once the mapping is sealed, it will stay in the process's memory until the process terminates**.”h]”(hŒIt might be important to note: ”…”�”}”(hj×h²hh³Nh´Nubj²)�”}”(hŒa**once the mapping is sealed, it will stay in the process's memory until the process terminates**”h]”hŒ_once the mapping is sealed, it will stay in the process’s memory until the process terminates”…”�”}”(hjßh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j±hj×ubhŒ.”…”�”}”(hj×h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KOhjÓubhþ)�”}”(hŒ Example::”h]”hŒExample:”…”�”}”(hj÷h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KRhjÓubhŒ literal_block”“”)�”}”(hŒœ*ptr = mmap(0, 4096, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); rc = mseal(ptr, 4096, 0); /* munmap will fail */ rc = munmap(ptr, 4096); assert(rc < 0);”h]”hŒœ*ptr = mmap(0, 4096, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); rc = mseal(ptr, 4096, 0); /* munmap will fail */ rc = munmap(ptr, 4096); assert(rc < 0);”…”�”}”hjsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jh³hÇh´KThjÓubj¡)�”}”(hhh]”j¦)�”}”(hŒÌBlocked mm syscall: - munmap - mmap - mremap - mprotect and pkey_mprotect - some destructive madvise behaviors: MADV_DONTNEED, MADV_FREE, MADV_DONTNEED_LOCKED, MADV_FREE, MADV_DONTFORK, MADV_WIPEONFORK ”h]”(j¬)�”}”(hŒBlocked mm syscall:”h]”hŒBlocked mm syscall:”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j«h³hÇh´K`hjubjÞ)�”}”(hhh]”j)�”}”(hhh]”(j$)�”}”(hŒmunmap”h]”hþ)�”}”(hj2h]”hŒmunmap”…”�”}”(hj4h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K[hj0ubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj-ubj$)�”}”(hŒmmap”h]”hþ)�”}”(hjIh]”hŒmmap”…”�”}”(hjKh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K\hjGubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj-ubj$)�”}”(hŒmremap”h]”hþ)�”}”(hj`h]”hŒmremap”…”�”}”(hjbh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K]hj^ubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj-ubj$)�”}”(hŒmprotect and pkey_mprotect”h]”hþ)�”}”(hjwh]”hŒmprotect and pkey_mprotect”…”�”}”(hjyh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K^hjuubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj-ubj$)�”}”(hŒ~some destructive madvise behaviors: MADV_DONTNEED, MADV_FREE, MADV_DONTNEED_LOCKED, MADV_FREE, MADV_DONTFORK, MADV_WIPEONFORK ”h]”hþ)�”}”(hŒ}some destructive madvise behaviors: MADV_DONTNEED, MADV_FREE, MADV_DONTNEED_LOCKED, MADV_FREE, MADV_DONTFORK, MADV_WIPEONFORK”h]”hŒ}some destructive madvise behaviors: MADV_DONTNEED, MADV_FREE, MADV_DONTNEED_LOCKED, MADV_FREE, MADV_DONTFORK, MADV_WIPEONFORK”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K_hjŒubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj-ubeh}”(h]”h ]”h"]”h$]”h&]”j¬j­uh1jh³hÇh´K[hj*ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÝhjubeh}”(h]”h ]”h"]”h$]”h&]”uh1j¥h³hÇh´K`hjubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjÓubhþ)�”}”(hXThe first set of syscalls to block is munmap, mremap, mmap. They can either leave an empty space in the address space, therefore allowing replacement with a new mapping with new set of attributes, or can overwrite the existing mapping with another mapping.”h]”hXThe first set of syscalls to block is munmap, mremap, mmap. They can either leave an empty space in the address space, therefore allowing replacement with a new mapping with new set of attributes, or can overwrite the existing mapping with another mapping.”…”�”}”(hj¼h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KbhjÓubhþ)�”}”(hŒemprotect and pkey_mprotect are blocked because they changes the protection bits (RWX) of the mapping.”h]”hŒemprotect and pkey_mprotect are blocked because they changes the protection bits (RWX) of the mapping.”…”�”}”(hjÊh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KghjÓubhþ)�”}”(hX½Certain destructive madvise behaviors, specifically MADV_DONTNEED, MADV_FREE, MADV_DONTNEED_LOCKED, and MADV_WIPEONFORK, can introduce risks when applied to anonymous memory by threads lacking write permissions. Consequently, these operations are prohibited under such conditions. The aforementioned behaviors have the potential to modify region contents by discarding pages, effectively performing a memset(0) operation on the anonymous memory.”h]”hX½Certain destructive madvise behaviors, specifically MADV_DONTNEED, MADV_FREE, MADV_DONTNEED_LOCKED, and MADV_WIPEONFORK, can introduce risks when applied to anonymous memory by threads lacking write permissions. Consequently, these operations are prohibited under such conditions. The aforementioned behaviors have the potential to modify region contents by discarding pages, effectively performing a memset(0) operation on the anonymous memory.”…”�”}”(hjØh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KjhjÓubhþ)�”}”(hŒ/Kernel will return -EPERM for blocked syscalls.”h]”hŒ/Kernel will return -EPERM for blocked syscalls.”…”�”}”(hjæh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KrhjÓubhþ)�”}”(hŒ†When blocked syscall return -EPERM due to sealing, the memory regions may or may not be changed, depends on the syscall being blocked:”h]”hŒ†When blocked syscall return -EPERM due to sealing, the memory regions may or may not be changed, depends on the syscall being blocked:”…”�”}”(hjôh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KthjÓubj‚)�”}”(hXS- munmap: munmap is atomic. If one of VMAs in the given range is sealed, none of VMAs are updated. - mprotect, pkey_mprotect, madvise: partial update might happen, e.g. when mprotect over multiple VMAs, mprotect might update the beginning VMAs before reaching the sealed VMA and return -EPERM. - mmap and mremap: undefined behavior. ”h]”j)�”}”(hhh]”(j$)�”}”(hŒ`munmap: munmap is atomic. If one of VMAs in the given range is sealed, none of VMAs are updated.”h]”hþ)�”}”(hŒ`munmap: munmap is atomic. If one of VMAs in the given range is sealed, none of VMAs are updated.”h]”hŒ`munmap: munmap is atomic. If one of VMAs in the given range is sealed, none of VMAs are updated.”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´Kwhj ubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hjubj$)�”}”(hŒÀmprotect, pkey_mprotect, madvise: partial update might happen, e.g. when mprotect over multiple VMAs, mprotect might update the beginning VMAs before reaching the sealed VMA and return -EPERM.”h]”hþ)�”}”(hŒÀmprotect, pkey_mprotect, madvise: partial update might happen, e.g. when mprotect over multiple VMAs, mprotect might update the beginning VMAs before reaching the sealed VMA and return -EPERM.”h]”hŒÀmprotect, pkey_mprotect, madvise: partial update might happen, e.g. when mprotect over multiple VMAs, mprotect might update the beginning VMAs before reaching the sealed VMA and return -EPERM.”…”�”}”(hj%h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´Kyhj!ubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hjubj$)�”}”(hŒ%mmap and mremap: undefined behavior. ”h]”hþ)�”}”(hŒ$mmap and mremap: undefined behavior.”h]”hŒ$mmap and mremap: undefined behavior.”…”�”}”(hj=h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K|hj9ubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hjubeh}”(h]”h ]”h"]”h$]”h&]”j¬j­uh1jh³hÇh´Kwhjubah}”(h]”h ]”h"]”h$]”h&]”uh1j�h³hÇh´KwhjÓubeh}”(h]”h ]”h"]”h$]”h&]”uh1j�h³hÇh´KOhjÂh²hubeh}”(h]”Œ%blocked-mm-syscall-for-sealed-mapping”ah ]”h"]”Œ%blocked mm syscall for sealed mapping”ah$]”h&]”uh1hÈhj_h²hh³hÇh´KNubeh}”(h]”Œsyscall”ah ]”h"]”Œsyscall”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ Use cases”h]”hŒ Use cases”…”�”}”(hjvh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjsh²hh³hÇh´Kubj)�”}”(hhh]”(j$)�”}”(hŒbglibc: The dynamic linker, during loading ELF executables, can apply sealing to mapping segments. ”h]”hþ)�”}”(hŒaglibc: The dynamic linker, during loading ELF executables, can apply sealing to mapping segments.”h]”hŒaglibc: The dynamic linker, during loading ELF executables, can apply sealing to mapping segments.”…”�”}”(hj‹h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K€hj‡ubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj„h²hh³hÇh´Nubj$)�”}”(hŒAChrome browser: protect some security sensitive data structures. ”h]”hþ)�”}”(hŒ@Chrome browser: protect some security sensitive data structures.”h]”hŒ@Chrome browser: protect some security sensitive data structures.”…”�”}”(hj£h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K„hjŸubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj„h²hh³hÇh´Nubj$)�”}”(hXNSystem mappings: The system mappings are created by the kernel and include vdso, vvar, vvar_vclock, vectors (arm compat-mode), sigpage (arm compat-mode), uprobes. Those system mappings are readonly only or execute only, memory sealing can protect them from ever changing to writable or unmapped/remapped as different attributes. This is useful to mitigate memory corruption issues where a corrupted pointer is passed to a memory management system. If supported by an architecture (CONFIG_ARCH_SUPPORTS_MSEAL_SYSTEM_MAPPINGS), the CONFIG_MSEAL_SYSTEM_MAPPINGS seals all system mappings of this architecture. WARNING: This feature breaks programs which rely on relocating or unmapping system mappings. Known broken software at the time of writing includes CHECKPOINT_RESTORE, UML, gVisor, rr. Therefore this config can't be enabled universally. ”h]”(hþ)�”}”(hŒ¢System mappings: The system mappings are created by the kernel and include vdso, vvar, vvar_vclock, vectors (arm compat-mode), sigpage (arm compat-mode), uprobes.”h]”hŒ¢System mappings: The system mappings are created by the kernel and include vdso, vvar, vvar_vclock, vectors (arm compat-mode), sigpage (arm compat-mode), uprobes.”…”�”}”(hj»h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K†hj·ubhþ)�”}”(hXThose system mappings are readonly only or execute only, memory sealing can protect them from ever changing to writable or unmapped/remapped as different attributes. This is useful to mitigate memory corruption issues where a corrupted pointer is passed to a memory management system.”h]”hXThose system mappings are readonly only or execute only, memory sealing can protect them from ever changing to writable or unmapped/remapped as different attributes. This is useful to mitigate memory corruption issues where a corrupted pointer is passed to a memory management system.”…”�”}”(hjÉh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KŠhj·ubhþ)�”}”(hŒžIf supported by an architecture (CONFIG_ARCH_SUPPORTS_MSEAL_SYSTEM_MAPPINGS), the CONFIG_MSEAL_SYSTEM_MAPPINGS seals all system mappings of this architecture.”h]”hŒžIf supported by an architecture (CONFIG_ARCH_SUPPORTS_MSEAL_SYSTEM_MAPPINGS), the CONFIG_MSEAL_SYSTEM_MAPPINGS seals all system mappings of this architecture.”…”�”}”(hj×h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K�hj·ubhþ)�”}”(hŒëWARNING: This feature breaks programs which rely on relocating or unmapping system mappings. Known broken software at the time of writing includes CHECKPOINT_RESTORE, UML, gVisor, rr. Therefore this config can't be enabled universally.”h]”hŒíWARNING: This feature breaks programs which rely on relocating or unmapping system mappings. Known broken software at the time of writing includes CHECKPOINT_RESTORE, UML, gVisor, rr. Therefore this config can’t be enabled universally.”…”�”}”(hjåh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K“hj·ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j#hj„h²hh³hÇh´Nubeh}”(h]”h ]”h"]”h$]”h&]”j¬j­uh1jh³hÇh´K€hjsh²hubeh}”(h]”Œ use-cases”ah ]”h"]”Œ use cases”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒWhen not to use mseal”h]”hŒWhen not to use mseal”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj h²hh³hÇh´K™ubhþ)�”}”(hX"Applications can apply sealing to any virtual memory region from userspace, but it is *crucial to thoroughly analyze the mapping's lifetime* prior to apply the sealing. This is because the sealed mapping *won’t be unmapped* until the process terminates or the exec system call is invoked.”h]”(hŒVApplications can apply sealing to any virtual memory region from userspace, but it is ”…”�”}”(hj h²hh³Nh´NubhŒemphasis”“”)�”}”(hŒ6*crucial to thoroughly analyze the mapping's lifetime*”h]”hŒ6crucial to thoroughly analyze the mapping’s lifetime”…”�”}”(hj" h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubhŒ@ prior to apply the sealing. This is because the sealed mapping ”…”�”}”(hj h²hh³Nh´Nubj! )�”}”(hŒ*won’t be unmapped*”h]”hŒwon’t be unmapped”…”�”}”(hj4 h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubhŒA until the process terminates or the exec system call is invoked.”…”�”}”(hj h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´Kšhj h²hubj¡)�”}”(hhh]”j¦)�”}”(hXšFor example: - aio/shm aio/shm can call mmap and munmap on behalf of userspace, e.g. ksys_shmdt() in shm.c. The lifetimes of those mapping are not tied to the lifetime of the process. If those memories are sealed from userspace, then munmap will fail, causing leaks in VMA address space during the lifetime of the process. - ptr allocated by malloc (heap) Don't use mseal on the memory ptr return from malloc(). malloc() is implemented by allocator, e.g. by glibc. Heap manager might allocate a ptr from brk or mapping created by mmap. If an app calls mseal on a ptr returned from malloc(), this can affect the heap manager's ability to manage the mappings; the outcome is non-deterministic. Example:: ptr = malloc(size); /* don't call mseal on ptr return from malloc. */ mseal(ptr, size); /* free will success, allocator can't shrink heap lower than ptr */ free(ptr); ”h]”(j¬)�”}”(hŒ For example:”h]”hŒ For example:”…”�”}”(hjS h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j«h³hÇh´KµhjO ubjÞ)�”}”(hhh]”j)�”}”(hhh]”(j$)�”}”(hX5aio/shm aio/shm can call mmap and munmap on behalf of userspace, e.g. ksys_shmdt() in shm.c. The lifetimes of those mapping are not tied to the lifetime of the process. If those memories are sealed from userspace, then munmap will fail, causing leaks in VMA address space during the lifetime of the process. ”h]”hþ)�”}”(hX4aio/shm aio/shm can call mmap and munmap on behalf of userspace, e.g. ksys_shmdt() in shm.c. The lifetimes of those mapping are not tied to the lifetime of the process. If those memories are sealed from userspace, then munmap will fail, causing leaks in VMA address space during the lifetime of the process.”h]”hX4aio/shm aio/shm can call mmap and munmap on behalf of userspace, e.g. ksys_shmdt() in shm.c. The lifetimes of those mapping are not tied to the lifetime of the process. If those memories are sealed from userspace, then munmap will fail, causing leaks in VMA address space during the lifetime of the process.”…”�”}”(hjk h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K hjg ubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hjd ubj$)�”}”(hX1ptr allocated by malloc (heap) Don't use mseal on the memory ptr return from malloc(). malloc() is implemented by allocator, e.g. by glibc. Heap manager might allocate a ptr from brk or mapping created by mmap. If an app calls mseal on a ptr returned from malloc(), this can affect the heap manager's ability to manage the mappings; the outcome is non-deterministic. Example:: ptr = malloc(size); /* don't call mseal on ptr return from malloc. */ mseal(ptr, size); /* free will success, allocator can't shrink heap lower than ptr */ free(ptr); ”h]”(hþ)�”}”(hXnptr allocated by malloc (heap) Don't use mseal on the memory ptr return from malloc(). malloc() is implemented by allocator, e.g. by glibc. Heap manager might allocate a ptr from brk or mapping created by mmap. If an app calls mseal on a ptr returned from malloc(), this can affect the heap manager's ability to manage the mappings; the outcome is non-deterministic.”h]”hXrptr allocated by malloc (heap) Don’t use mseal on the memory ptr return from malloc(). malloc() is implemented by allocator, e.g. by glibc. Heap manager might allocate a ptr from brk or mapping created by mmap. If an app calls mseal on a ptr returned from malloc(), this can affect the heap manager’s ability to manage the mappings; the outcome is non-deterministic.”…”�”}”(hjƒ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K§hj ubhþ)�”}”(hŒ Example::”h]”hŒExample:”…”�”}”(hj‘ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K¯hj ubj)�”}”(hŒ¦ptr = malloc(size); /* don't call mseal on ptr return from malloc. */ mseal(ptr, size); /* free will success, allocator can't shrink heap lower than ptr */ free(ptr);”h]”hŒ¦ptr = malloc(size); /* don't call mseal on ptr return from malloc. */ mseal(ptr, size); /* free will success, allocator can't shrink heap lower than ptr */ free(ptr);”…”�”}”hjŸ sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jh³hÇh´K±hj ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j#hjd ubeh}”(h]”h ]”h"]”h$]”h&]”j¬j­uh1jh³hÇh´K hja ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÝhjO ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j¥h³hÇh´KµhjL ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj h²hh³Nh´Nubeh}”(h]”Œwhen-not-to-use-mseal”ah ]”h"]”Œwhen not to use mseal”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K™ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒmseal doesn't block”h]”hŒmseal doesn’t block”…”�”}”(hjÖ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjÓ h²hh³hÇh´K¸ubhþ)�”}”(hŒ¬In a nutshell, mseal blocks certain mm syscall from modifying some of VMA's attributes, such as protection bits (RWX). Sealed mappings doesn't mean the memory is immutable.”h]”hŒ°In a nutshell, mseal blocks certain mm syscall from modifying some of VMA’s attributes, such as protection bits (RWX). Sealed mappings doesn’t mean the memory is immutable.”…”�”}”(hjä h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K¹hjÓ h²hubhþ)�”}”(hŒ¬As Jann Horn pointed out in [3], there are still a few ways to write to RO memory, which is, in a way, by design. And those could be blocked by different security measures.”h]”hŒ¬As Jann Horn pointed out in [3], there are still a few ways to write to RO memory, which is, in a way, by design. And those could be blocked by different security measures.”…”�”}”(hjò h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K½hjÓ h²hubhþ)�”}”(hŒThose cases are:”h]”hŒThose cases are:”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KÁhjÓ h²hubj‚)�”}”(hŒ - Write to read-only memory through /proc/self/mem interface (FOLL_FORCE). - Write to read-only memory through ptrace (such as PTRACE_POKETEXT). - userfaultfd. ”h]”j)�”}”(hhh]”(j$)�”}”(hŒHWrite to read-only memory through /proc/self/mem interface (FOLL_FORCE).”h]”hþ)�”}”(hj h]”hŒHWrite to read-only memory through /proc/self/mem interface (FOLL_FORCE).”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KÃhj ubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj ubj$)�”}”(hŒCWrite to read-only memory through ptrace (such as PTRACE_POKETEXT).”h]”hþ)�”}”(hj. h]”hŒCWrite to read-only memory through ptrace (such as PTRACE_POKETEXT).”…”�”}”(hj0 h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KÄhj, ubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj ubj$)�”}”(hŒ userfaultfd. ”h]”hþ)�”}”(hŒ userfaultfd.”h]”hŒ userfaultfd.”…”�”}”(hjG h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KÅhjC ubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hj ubeh}”(h]”h ]”h"]”h$]”h&]”j¬j­uh1jh³hÇh´KÃhj ubah}”(h]”h ]”h"]”h$]”h&]”uh1j�h³hÇh´KÃhjÓ h²hubhþ)�”}”(hŒ”The idea that inspired this patch comes from Stephen Röttger’s work in V8 CFI [4]. Chrome browser in ChromeOS will be the first user of this API.”h]”hŒ”The idea that inspired this patch comes from Stephen Röttger’s work in V8 CFI [4]. Chrome browser in ChromeOS will be the first user of this API.”…”�”}”(hjg h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KÇhjÓ h²hubeh}”(h]”Œmseal-doesn-t-block”ah ]”h"]”Œmseal doesn't block”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K¸ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ Reference”h]”hŒ Reference”…”�”}”(hj€ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj} h²hh³hÇh´KËubj)�”}”(hhh]”(j$)�”}”(hŒ€[1] https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/osfmk/mach/vm_statistics.h#L274”h]”hþ)�”}”(hj“ h]”(hŒ[1] ”…”�”}”(hj• h²hh³Nh´Nubj)�”}”(hŒ|https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/osfmk/mach/vm_statistics.h#L274”h]”hŒ|https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/osfmk/mach/vm_statistics.h#L274”…”�”}”(hjœ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”jž uh1jhj• ubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KÌhj‘ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hjŽ h²hh³hÇh´Nubj$)�”}”(hŒ([2] https://man.openbsd.org/mimmutable.2”h]”hþ)�”}”(hj¹ h]”(hŒ[2] ”…”�”}”(hj» h²hh³Nh´Nubj)�”}”(hŒ$https://man.openbsd.org/mimmutable.2”h]”hŒ$https://man.openbsd.org/mimmutable.2”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”jÄ uh1jhj» ubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KÍhj· ubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hjŽ h²hh³hÇh´Nubj$)�”}”(hŒc[3] https://lore.kernel.org/lkml/CAG48ez3ShUYey+ZAFsU2i1RpQn0a5eOs2hzQ426FkcgnfUGLvA@mail.gmail.com”h]”hþ)�”}”(hjß h]”(hŒ[3] ”…”�”}”(hjá h²hh³Nh´Nubj)�”}”(hŒ_https://lore.kernel.org/lkml/CAG48ez3ShUYey+ZAFsU2i1RpQn0a5eOs2hzQ426FkcgnfUGLvA@mail.gmail.com”h]”hŒ_https://lore.kernel.org/lkml/CAG48ez3ShUYey+ZAFsU2i1RpQn0a5eOs2hzQ426FkcgnfUGLvA@mail.gmail.com”…”�”}”(hjè h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”jê uh1jhjá ubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KÎhjÝ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hjŽ h²hh³hÇh´Nubj$)�”}”(hŒo[4] https://docs.google.com/document/d/1O2jwK4dxI3nRcOJuPYkonhTkNQfbmwdvxQMyXgeaRHo/edit#heading=h.bvaojj9fu6hc”h]”hþ)�”}”(hj h]”(hŒ[4] ”…”�”}”(hj h²hh³Nh´Nubj)�”}”(hŒkhttps://docs.google.com/document/d/1O2jwK4dxI3nRcOJuPYkonhTkNQfbmwdvxQMyXgeaRHo/edit#heading=h.bvaojj9fu6hc”h]”hŒkhttps://docs.google.com/document/d/1O2jwK4dxI3nRcOJuPYkonhTkNQfbmwdvxQMyXgeaRHo/edit#heading=h.bvaojj9fu6hc”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”j uh1jhj ubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KÏhj ubah}”(h]”h ]”h"]”h$]”h&]”uh1j#hjŽ h²hh³hÇh´Nubeh}”(h]”h ]”h"]”h$]”h&]”j¬j­uh1jh³hÇh´KÌhj} h²hubeh}”(h]”Œ reference”ah ]”h"]”Œ reference”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KËubeh}”(h]”Œintroduction-of-mseal”ah ]”h"]”Œintroduction of mseal”ah$]”h&]”uh1hÈhhh²hh³hÇh´Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”hÇuh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)�”}”(hÍNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”jb Œerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”hÇŒ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”(j< j9 jpjmj¿j¼jhjej j jÐ jÍ jz jw j4 j1 uŒ nametypes”}”(j< ‰jp‰j¿‰jh‰j ‰jÐ ‰jz ‰j4 ‰uh}”(j9 hÊjmj_j¼jpjejÂj jsjÍ j jw jÓ j1 j} uŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”Œtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nh²hub.