€•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”…””}”(hjh²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