€•8MŒ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/mfd_noexec”Œ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/mfd_noexec”Œ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/mfd_noexec”Œ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/mfd_noexec”Œ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/mfd_noexec”Œ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/mfd_noexec”Œ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/mfd_noexec”Œ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³ŒF/var/lib/git/docbuild/linux/Documentation/userspace-api/mfd_noexec.rst”h´KubhŒsection”“”)�”}”(hhh]”(hŒtitle”“”)�”}”(hŒ"Introduction of non-executable mfd”h]”hŒ"Introduction of non-executable mfd”…”�”}”(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ŒEDaniel Verkamp Jeff Xu ”h]”hŒ paragraph”“”)�”}”(hŒDDaniel Verkamp Jeff Xu ”h]”(hŒDaniel Verkamp <”…”�”}”(hhÿh²hh³Nh´NubhŒ reference”“”)�”}”(hŒdverkamp@chromium.org”h]”hŒdverkamp@chromium.org”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”Œmailto:dverkamp@chromium.org”uh1jhhÿubhŒ > Jeff Xu <”…”�”}”(hhÿh²hh³Nh´Nubj)�”}”(hŒjeffxu@chromium.org”h]”hŒjeffxu@chromium.org”…”�”}”(hjh²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²hubhã)�”}”(hhh]”(hè)�”}”(hŒ Contributor”h]”hŒ Contributor”…”�”}”(hjFh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hçhjCh³hÇh´Kubhø)�”}”(hŒ!Aleksa Sarai ”h]”hþ)�”}”(hŒ Aleksa Sarai ”h]”(hŒAleksa Sarai <”…”�”}”(hjXh²hh³Nh´Nubj)�”}”(hŒcyphar@cyphar.com”h]”hŒcyphar@cyphar.com”…”�”}”(hj`h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”Œmailto:cyphar@cyphar.com”uh1jhjXubhŒ>”…”�”}”(hjXh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K hjTubah}”(h]”h ]”h"]”h$]”h&]”uh1h÷hjCubeh}”(h]”h ]”h"]”h$]”h&]”uh1hâh³hÇh´K hhßh²hubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝhhÊh²hh³hÇh´Kubhþ)�”}”(hŒœSince Linux introduced the memfd feature, memfds have always had their execute bit set, and the memfd_create() syscall doesn't allow setting it differently.”h]”hŒžSince Linux introduced the memfd feature, memfds have always had their execute bit set, and the memfd_create() syscall doesn’t allow setting it differently.”…”�”}”(hjŒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K hhÊh²hubhþ)�”}”(hXÞHowever, in a secure-by-default system, such as ChromeOS, (where all executables should come from the rootfs, which is protected by verified boot), this executable nature of memfd opens a door for NoExec bypass and enables “confused deputy attackâ€�. E.g, in VRP bug [1]: cros_vm process created a memfd to share the content with an external process, however the memfd is overwritten and used for executing arbitrary code and root escalation. [2] lists more VRP of this kind.”h]”hXÞHowever, in a secure-by-default system, such as ChromeOS, (where all executables should come from the rootfs, which is protected by verified boot), this executable nature of memfd opens a door for NoExec bypass and enables “confused deputy attackâ€�. E.g, in VRP bug [1]: cros_vm process created a memfd to share the content with an external process, however the memfd is overwritten and used for executing arbitrary code and root escalation. [2] lists more VRP of this kind.”…”�”}”(hjšh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KhhÊh²hubhþ)�”}”(hX On the other hand, executable memfd has its legit use: runc uses memfd’s seal and executable feature to copy the contents of the binary then execute them. For such a system, we need a solution to differentiate runc's use of executable memfds and an attacker's [3].”h]”hXOn the other hand, executable memfd has its legit use: runc uses memfd’s seal and executable feature to copy the contents of the binary then execute them. For such a system, we need a solution to differentiate runc’s use of executable memfds and an attacker’s [3].”…”�”}”(hj¨h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KhhÊh²hubhŒdefinition_list”“”)�”}”(hhh]”hŒdefinition_list_item”“”)�”}”(hŒûTo address those above: - Let memfd_create() set X bit at creation time. - Let memfd be sealed for modifying X bit when NX is set. - Add a new pid namespace sysctl: vm.memfd_noexec to help applications in migrating and enforcing non-executable MFD. ”h]”(hŒterm”“”)�”}”(hŒTo address those above:”h]”hŒTo address those above:”…”�”}”(hjÃh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁh³hÇh´K"hj½ubhŒ definition”“”)�”}”(hhh]”hŒ bullet_list”“”)�”}”(hhh]”(hŒ list_item”“”)�”}”(hŒ.Let memfd_create() set X bit at creation time.”h]”hþ)�”}”(hjßh]”hŒ.Let memfd_create() set X bit at creation time.”…”�”}”(hjáh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KhjÝubah}”(h]”h ]”h"]”h$]”h&]”uh1jÛhjØubjÜ)�”}”(hŒ7Let memfd be sealed for modifying X bit when NX is set.”h]”hþ)�”}”(hjöh]”hŒ7Let memfd be sealed for modifying X bit when NX is set.”…”�”}”(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ŒtAdd a new pid namespace sysctl: vm.memfd_noexec to help applications in migrating and enforcing non-executable MFD. ”h]”hþ)�”}”(hŒsAdd a new pid namespace sysctl: vm.memfd_noexec to help applications in migrating and enforcing non-executable MFD.”h]”hŒsAdd a new pid namespace sysctl: vm.memfd_noexec to help applications in migrating and enforcing non-executable MFD.”…”�”}”(hjh²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”Œ-”uh1jÖh³hÇh´KhjÓubah}”(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¶hhÊh²hh³Nh´NubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒUser API”h]”hŒUser API”…”�”}”(hj@h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj=h²hh³hÇh´K%ubhþ)�”}”(hŒ:``int memfd_create(const char *name, unsigned int flags)``”h]”hŒliteral”“”)�”}”(hjPh]”hŒ6int memfd_create(const char *name, unsigned int flags)”…”�”}”(hjTh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jRhjNubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K&hj=h²hubj·)�”}”(hhh]”(j¼)�”}”(hX``MFD_NOEXEC_SEAL`` When MFD_NOEXEC_SEAL bit is set in the ``flags``, memfd is created with NX. F_SEAL_EXEC is set and the memfd can't be modified to add X later. MFD_ALLOW_SEALING is also implied. This is the most common case for the application to use memfd. ”h]”(jÂ)�”}”(hŒ``MFD_NOEXEC_SEAL``”h]”jS)�”}”(hjph]”hŒMFD_NOEXEC_SEAL”…”�”}”(hjrh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jRhjnubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁh³hÇh´K,hjjubjÒ)�”}”(hhh]”hþ)�”}”(hŒðWhen MFD_NOEXEC_SEAL bit is set in the ``flags``, memfd is created with NX. F_SEAL_EXEC is set and the memfd can't be modified to add X later. MFD_ALLOW_SEALING is also implied. This is the most common case for the application to use memfd.”h]”(hŒ'When MFD_NOEXEC_SEAL bit is set in the ”…”�”}”(hjˆh²hh³Nh´NubjS)�”}”(hŒ ``flags``”h]”hŒflags”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jRhjˆubhŒÂ, memfd is created with NX. F_SEAL_EXEC is set and the memfd can’t be modified to add X later. MFD_ALLOW_SEALING is also implied. This is the most common case for the application to use memfd.”…”�”}”(hjˆh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K)hj…ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÑhjjubeh}”(h]”h ]”h"]”h$]”h&]”uh1j»h³hÇh´K,hjgubj¼)�”}”(hŒQ``MFD_EXEC`` When MFD_EXEC bit is set in the ``flags``, memfd is created with X. ”h]”(jÂ)�”}”(hŒ ``MFD_EXEC``”h]”jS)�”}”(hjºh]”hŒMFD_EXEC”…”�”}”(hj¼h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jRhj¸ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁh³hÇh´K/hj´ubjÒ)�”}”(hhh]”hþ)�”}”(hŒCWhen MFD_EXEC bit is set in the ``flags``, memfd is created with X.”h]”(hŒ When MFD_EXEC bit is set in the ”…”�”}”(hjÒh²hh³Nh´NubjS)�”}”(hŒ ``flags``”h]”hŒflags”…”�”}”(hjÚh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jRhjÒubhŒ, memfd is created with X.”…”�”}”(hjÒh²hh³Nh´Nubeh}”(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&]”uh1j»h³hÇh´K/hjgh²hubj¼)�”}”(hŒ‹Note: ``MFD_NOEXEC_SEAL`` implies ``MFD_ALLOW_SEALING``. In case that an app doesn't want sealing, it can add F_SEAL_SEAL after creation. ”h]”(jÂ)�”}”(hŒNote:”h]”hŒNote:”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁh³hÇh´K4hjþubjÒ)�”}”(hhh]”hþ)�”}”(hŒƒ``MFD_NOEXEC_SEAL`` implies ``MFD_ALLOW_SEALING``. In case that an app doesn't want sealing, it can add F_SEAL_SEAL after creation.”h]”(jS)�”}”(hŒ``MFD_NOEXEC_SEAL``”h]”hŒMFD_NOEXEC_SEAL”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jRhjubhŒ implies ”…”�”}”(hjh²hh³Nh´NubjS)�”}”(hŒ``MFD_ALLOW_SEALING``”h]”hŒMFD_ALLOW_SEALING”…”�”}”(hj)h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jRhjubhŒT. In case that an app doesn’t want sealing, it can add F_SEAL_SEAL after creation.”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K2hjubah}”(h]”h ]”h"]”h$]”h&]”uh1jÑhjþubeh}”(h]”h ]”h"]”h$]”h&]”uh1j»h³hÇh´K4hjgh²hubeh}”(h]”h ]”h"]”h$]”h&]”uh1j¶hj=h²hh³hÇh´Nubeh}”(h]”Œuser-api”ah ]”h"]”Œuser api”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K%ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒSysctl:”h]”hŒSysctl:”…”�”}”(hj^h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj[h²hh³hÇh´K7ubhþ)�”}”(hŒ)``pid namespaced sysctl vm.memfd_noexec``”h]”jS)�”}”(hjnh]”hŒ%pid namespaced sysctl vm.memfd_noexec”…”�”}”(hjph²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jRhjlubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K8hj[h²hubhþ)�”}”(hŒ;The new pid namespaced sysctl vm.memfd_noexec has 3 values:”h]”hŒ;The new pid namespaced sysctl vm.memfd_noexec has 3 values:”…”�”}”(hjƒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´K:hj[h²hubhŒ block_quote”“”)�”}”(hXn- 0: MEMFD_NOEXEC_SCOPE_EXEC memfd_create() without MFD_EXEC nor MFD_NOEXEC_SEAL acts like MFD_EXEC was set. - 1: MEMFD_NOEXEC_SCOPE_NOEXEC_SEAL memfd_create() without MFD_EXEC nor MFD_NOEXEC_SEAL acts like MFD_NOEXEC_SEAL was set. - 2: MEMFD_NOEXEC_SCOPE_NOEXEC_ENFORCED memfd_create() without MFD_NOEXEC_SEAL will be rejected. ”h]”j×)�”}”(hhh]”(jÜ)�”}”(hŒu0: MEMFD_NOEXEC_SCOPE_EXEC memfd_create() without MFD_EXEC nor MFD_NOEXEC_SEAL acts like MFD_EXEC was set. ”h]”j·)�”}”(hhh]”j¼)�”}”(hŒk0: MEMFD_NOEXEC_SCOPE_EXEC memfd_create() without MFD_EXEC nor MFD_NOEXEC_SEAL acts like MFD_EXEC was set. ”h]”(jÂ)�”}”(hŒ0: MEMFD_NOEXEC_SCOPE_EXEC”h]”hŒ0: MEMFD_NOEXEC_SCOPE_EXEC”…”�”}”(hj¥h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁh³hÇh´K>hj¡ubjÒ)�”}”(hhh]”hþ)�”}”(hŒOmemfd_create() without MFD_EXEC nor MFD_NOEXEC_SEAL acts like MFD_EXEC was set.”h]”hŒOmemfd_create() without MFD_EXEC nor MFD_NOEXEC_SEAL acts like MFD_EXEC was set.”…”�”}”(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&]”uh1j»h³hÇh´K>hjžubah}”(h]”h ]”h"]”h$]”h&]”uh1j¶hjšubah}”(h]”h ]”h"]”h$]”h&]”uh1jÛhj—ubjÜ)�”}”(hŒƒ1: MEMFD_NOEXEC_SCOPE_NOEXEC_SEAL memfd_create() without MFD_EXEC nor MFD_NOEXEC_SEAL acts like MFD_NOEXEC_SEAL was set. ”h]”j·)�”}”(hhh]”j¼)�”}”(hŒy1: MEMFD_NOEXEC_SCOPE_NOEXEC_SEAL memfd_create() without MFD_EXEC nor MFD_NOEXEC_SEAL acts like MFD_NOEXEC_SEAL was set. ”h]”(jÂ)�”}”(hŒ!1: MEMFD_NOEXEC_SCOPE_NOEXEC_SEAL”h]”hŒ!1: MEMFD_NOEXEC_SCOPE_NOEXEC_SEAL”…”�”}”(hjçh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁh³hÇh´KBhjãubjÒ)�”}”(hhh]”hþ)�”}”(hŒVmemfd_create() without MFD_EXEC nor MFD_NOEXEC_SEAL acts like MFD_NOEXEC_SEAL was set.”h]”hŒVmemfd_create() without MFD_EXEC nor MFD_NOEXEC_SEAL acts like MFD_NOEXEC_SEAL was set.”…”�”}”(hjøh²hh³Nh´Nubah}”(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´KBhjàubah}”(h]”h ]”h"]”h$]”h&]”uh1j¶hjÜubah}”(h]”h ]”h"]”h$]”h&]”uh1jÛhj—ubjÜ)�”}”(hŒd2: MEMFD_NOEXEC_SCOPE_NOEXEC_ENFORCED memfd_create() without MFD_NOEXEC_SEAL will be rejected. ”h]”j·)�”}”(hhh]”j¼)�”}”(hŒ_2: MEMFD_NOEXEC_SCOPE_NOEXEC_ENFORCED memfd_create() without MFD_NOEXEC_SEAL will be rejected. ”h]”(jÂ)�”}”(hŒ%2: MEMFD_NOEXEC_SCOPE_NOEXEC_ENFORCED”h]”hŒ%2: MEMFD_NOEXEC_SCOPE_NOEXEC_ENFORCED”…”�”}”(hj)h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁh³hÇh´KEhj%ubjÒ)�”}”(hhh]”hþ)�”}”(hŒ8memfd_create() without MFD_NOEXEC_SEAL will be rejected.”h]”hŒ8memfd_create() without MFD_NOEXEC_SEAL will be rejected.”…”�”}”(hj:h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hýh³hÇh´KEhj7ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÑhj%ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j»h³hÇh´KEhj"ubah}”(h]”h ]”h"]”h$]”h&]”uh1j¶hjubah}”(h]”h ]”h"]”h$]”h&]”uh1jÛhj—ubeh}”(h]”h ]”h"]”h$]”h&]”j)j*uh1jÖh³hÇh´K