€•ù€Œ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”Œ5/translations/zh_CN/filesystems/fuse/fuse-passthrough”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)”}”(hhh]”hŒChinese (Traditional)”…””}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ5/translations/zh_TW/filesystems/fuse/fuse-passthrough”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ5/translations/it_IT/filesystems/fuse/fuse-passthrough”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ5/translations/ja_JP/filesystems/fuse/fuse-passthrough”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ5/translations/ko_KR/filesystems/fuse/fuse-passthrough”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒPortuguese (Brazilian)”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ5/translations/pt_BR/filesystems/fuse/fuse-passthrough”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒSpanish”…””}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ5/translations/sp_SP/filesystems/fuse/fuse-passthrough”Œ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³ŒO/var/lib/git/docbuild/linux/Documentation/filesystems/fuse/fuse-passthrough.rst”h´KubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒFUSE Passthrough”h]”hŒFUSE Passthrough”…””}”(hhÏh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhhÊh²hh³hÇh´KubhÉ)”}”(hhh]”(hÎ)”}”(hŒ Introduction”h]”hŒ Introduction”…””}”(hhàh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhhÝh²hh³hÇh´KubhŒ paragraph”“”)”}”(hXšFUSE (Filesystem in Userspace) passthrough is a feature designed to improve the performance of FUSE filesystems for I/O operations. Typically, FUSE operations involve communication between the kernel and a userspace FUSE daemon, which can incur overhead. Passthrough allows certain operations on a FUSE file to bypass the userspace daemon and be executed directly by the kernel on an underlying "backing file".”h]”hXžFUSE (Filesystem in Userspace) passthrough is a feature designed to improve the performance of FUSE filesystems for I/O operations. Typically, FUSE operations involve communication between the kernel and a userspace FUSE daemon, which can incur overhead. Passthrough allows certain operations on a FUSE file to bypass the userspace daemon and be executed directly by the kernel on an underlying “backing fileâ€.”…””}”(hhðh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K hhÝh²hubhï)”}”(hXÐThis is achieved by the FUSE daemon registering a file descriptor (pointing to the backing file on a lower filesystem) with the FUSE kernel module. The kernel then receives an identifier (``backing_id``) for this registered backing file. When a FUSE file is subsequently opened, the FUSE daemon can, in its response to the ``OPEN`` request, include this ``backing_id`` and set the ``FOPEN_PASSTHROUGH`` flag. This establishes a direct link for specific operations.”h]”(hŒ¼This is achieved by the FUSE daemon registering a file descriptor (pointing to the backing file on a lower filesystem) with the FUSE kernel module. The kernel then receives an identifier (”…””}”(hhþh²hh³Nh´NubhŒliteral”“”)”}”(hŒ``backing_id``”h]”hŒ backing_id”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhhþubhŒy) for this registered backing file. When a FUSE file is subsequently opened, the FUSE daemon can, in its response to the ”…””}”(hhþh²hh³Nh´Nubj)”}”(hŒ``OPEN``”h]”hŒOPEN”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhhþubhŒ request, include this ”…””}”(hhþh²hh³Nh´Nubj)”}”(hŒ``backing_id``”h]”hŒ backing_id”…””}”(hj,h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhhþubhŒ and set the ”…””}”(hhþh²hh³Nh´Nubj)”}”(hŒ``FOPEN_PASSTHROUGH``”h]”hŒFOPEN_PASSTHROUGH”…””}”(hj>h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhhþubhŒ> flag. This establishes a direct link for specific operations.”…””}”(hhþh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KhhÝh²hubhï)”}”(hŒ”Currently, passthrough is supported for operations like ``read(2)``/``write(2)`` (via ``read_iter``/``write_iter``), ``splice(2)``, and ``mmap(2)``.”h]”(hŒ8Currently, passthrough is supported for operations like ”…””}”(hjVh²hh³Nh´Nubj)”}”(hŒ ``read(2)``”h]”hŒread(2)”…””}”(hj^h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjVubhŒ/”…””}”(hjVh²hh³Nh´Nubj)”}”(hŒ ``write(2)``”h]”hŒwrite(2)”…””}”(hjph²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjVubhŒ (via ”…””}”(hjVh²hh³Nh´Nubj)”}”(hŒ ``read_iter``”h]”hŒ read_iter”…””}”(hj‚h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjVubhŒ/”…””}”hjVsbj)”}”(hŒ``write_iter``”h]”hŒ write_iter”…””}”(hj”h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjVubhŒ), ”…””}”(hjVh²hh³Nh´Nubj)”}”(hŒ ``splice(2)``”h]”hŒ splice(2)”…””}”(hj¦h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjVubhŒ, and ”…””}”(hjVh²hh³Nh´Nubj)”}”(hŒ ``mmap(2)``”h]”hŒmmap(2)”…””}”(hj¸h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjVubhŒ.”…””}”(hjVh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KhhÝh²hubeh}”(h]”Œ introduction”ah ]”h"]”Œ introduction”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KubhÉ)”}”(hhh]”(hÎ)”}”(hŒEnabling Passthrough”h]”hŒEnabling Passthrough”…””}”(hjÛh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjØh²hh³hÇh´Kubhï)”}”(hŒTo use FUSE passthrough:”h]”hŒTo use FUSE passthrough:”…””}”(hjéh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KhjØh²hubhŒ block_quote”“”)”}”(hXŠ1. The FUSE filesystem must be compiled with ``CONFIG_FUSE_PASSTHROUGH`` enabled. 2. The FUSE daemon, during the ``FUSE_INIT`` handshake, must negotiate the ``FUSE_PASSTHROUGH`` capability and specify its desired ``max_stack_depth``. 3. The (privileged) FUSE daemon uses the ``FUSE_DEV_IOC_BACKING_OPEN`` ioctl on its connection file descriptor (e.g., ``/dev/fuse``) to register a backing file descriptor and obtain a ``backing_id``. 4. When handling an ``OPEN`` or ``CREATE`` request for a FUSE file, the daemon replies with the ``FOPEN_PASSTHROUGH`` flag set in ``fuse_open_out::open_flags`` and provides the corresponding ``backing_id`` in ``fuse_open_out::backing_id``. 5. The FUSE daemon should eventually call ``FUSE_DEV_IOC_BACKING_CLOSE`` with the ``backing_id`` to release the kernel's reference to the backing file when it's no longer needed for passthrough setups. ”h]”hŒenumerated_list”“”)”}”(hhh]”(hŒ list_item”“”)”}”(hŒNThe FUSE filesystem must be compiled with ``CONFIG_FUSE_PASSTHROUGH`` enabled.”h]”hï)”}”(hŒNThe FUSE filesystem must be compiled with ``CONFIG_FUSE_PASSTHROUGH`` enabled.”h]”(hŒ*The FUSE filesystem must be compiled with ”…””}”(hjh²hh³Nh´Nubj)”}”(hŒ``CONFIG_FUSE_PASSTHROUGH``”h]”hŒCONFIG_FUSE_PASSTHROUGH”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjubhŒ enabled.”…””}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K!hjubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÿubj)”}”(hŒ”The FUSE daemon, during the ``FUSE_INIT`` handshake, must negotiate the ``FUSE_PASSTHROUGH`` capability and specify its desired ``max_stack_depth``.”h]”hï)”}”(hŒ”The FUSE daemon, during the ``FUSE_INIT`` handshake, must negotiate the ``FUSE_PASSTHROUGH`` capability and specify its desired ``max_stack_depth``.”h]”(hŒThe FUSE daemon, during the ”…””}”(hj2h²hh³Nh´Nubj)”}”(hŒ ``FUSE_INIT``”h]”hŒ FUSE_INIT”…””}”(hj:h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj2ubhŒ handshake, must negotiate the ”…””}”(hj2h²hh³Nh´Nubj)”}”(hŒ``FUSE_PASSTHROUGH``”h]”hŒFUSE_PASSTHROUGH”…””}”(hjLh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj2ubhŒ$ capability and specify its desired ”…””}”(hj2h²hh³Nh´Nubj)”}”(hŒ``max_stack_depth``”h]”hŒmax_stack_depth”…””}”(hj^h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj2ubhŒ.”…””}”(hj2h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K#hj.ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÿubj)”}”(hŒÄThe (privileged) FUSE daemon uses the ``FUSE_DEV_IOC_BACKING_OPEN`` ioctl on its connection file descriptor (e.g., ``/dev/fuse``) to register a backing file descriptor and obtain a ``backing_id``.”h]”hï)”}”(hŒÄThe (privileged) FUSE daemon uses the ``FUSE_DEV_IOC_BACKING_OPEN`` ioctl on its connection file descriptor (e.g., ``/dev/fuse``) to register a backing file descriptor and obtain a ``backing_id``.”h]”(hŒ&The (privileged) FUSE daemon uses the ”…””}”(hj€h²hh³Nh´Nubj)”}”(hŒ``FUSE_DEV_IOC_BACKING_OPEN``”h]”hŒFUSE_DEV_IOC_BACKING_OPEN”…””}”(hjˆh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj€ubhŒ0 ioctl on its connection file descriptor (e.g., ”…””}”(hj€h²hh³Nh´Nubj)”}”(hŒ ``/dev/fuse``”h]”hŒ /dev/fuse”…””}”(hjšh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj€ubhŒ5) to register a backing file descriptor and obtain a ”…””}”(hj€h²hh³Nh´Nubj)”}”(hŒ``backing_id``”h]”hŒ backing_id”…””}”(hj¬h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj€ubhŒ.”…””}”(hj€h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K&hj|ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÿubj)”}”(hŒìWhen handling an ``OPEN`` or ``CREATE`` request for a FUSE file, the daemon replies with the ``FOPEN_PASSTHROUGH`` flag set in ``fuse_open_out::open_flags`` and provides the corresponding ``backing_id`` in ``fuse_open_out::backing_id``.”h]”hï)”}”(hŒìWhen handling an ``OPEN`` or ``CREATE`` request for a FUSE file, the daemon replies with the ``FOPEN_PASSTHROUGH`` flag set in ``fuse_open_out::open_flags`` and provides the corresponding ``backing_id`` in ``fuse_open_out::backing_id``.”h]”(hŒWhen handling an ”…””}”(hjÎh²hh³Nh´Nubj)”}”(hŒ``OPEN``”h]”hŒOPEN”…””}”(hjÖh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÎubhŒ or ”…””}”(hjÎh²hh³Nh´Nubj)”}”(hŒ ``CREATE``”h]”hŒCREATE”…””}”(hjèh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÎubhŒ6 request for a FUSE file, the daemon replies with the ”…””}”(hjÎh²hh³Nh´Nubj)”}”(hŒ``FOPEN_PASSTHROUGH``”h]”hŒFOPEN_PASSTHROUGH”…””}”(hjúh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÎubhŒ flag set in ”…””}”(hjÎh²hh³Nh´Nubj)”}”(hŒ``fuse_open_out::open_flags``”h]”hŒfuse_open_out::open_flags”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÎubhŒ and provides the corresponding ”…””}”(hjÎh²hh³Nh´Nubj)”}”(hŒ``backing_id``”h]”hŒ backing_id”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÎubhŒ in ”…””}”(hjÎh²hh³Nh´Nubj)”}”(hŒ``fuse_open_out::backing_id``”h]”hŒfuse_open_out::backing_id”…””}”(hj0h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÎubhŒ.”…””}”(hjÎh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K)hjÊubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÿubj)”}”(hŒÇThe FUSE daemon should eventually call ``FUSE_DEV_IOC_BACKING_CLOSE`` with the ``backing_id`` to release the kernel's reference to the backing file when it's no longer needed for passthrough setups. ”h]”hï)”}”(hŒÆThe FUSE daemon should eventually call ``FUSE_DEV_IOC_BACKING_CLOSE`` with the ``backing_id`` to release the kernel's reference to the backing file when it's no longer needed for passthrough setups.”h]”(hŒ'The FUSE daemon should eventually call ”…””}”(hjRh²hh³Nh´Nubj)”}”(hŒ``FUSE_DEV_IOC_BACKING_CLOSE``”h]”hŒFUSE_DEV_IOC_BACKING_CLOSE”…””}”(hjZh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjRubhŒ with the ”…””}”(hjRh²hh³Nh´Nubj)”}”(hŒ``backing_id``”h]”hŒ backing_id”…””}”(hjlh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjRubhŒm to release the kernel’s reference to the backing file when it’s no longer needed for passthrough setups.”…””}”(hjRh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K-hjNubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÿubeh}”(h]”h ]”h"]”h$]”h&]”Œenumtype”Œarabic”Œprefix”hŒsuffix”Œ.”uh1jýhjùubah}”(h]”h ]”h"]”h$]”h&]”uh1j÷h³hÇh´K!hjØh²hubeh}”(h]”Œenabling-passthrough”ah ]”h"]”Œenabling passthrough”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KubhÉ)”}”(hhh]”(hÎ)”}”(hŒPrivilege Requirements”h]”hŒPrivilege Requirements”…””}”(hj¦h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj£h²hh³hÇh´K2ubhï)”}”(hX6Setting up passthrough functionality currently requires the FUSE daemon to possess the ``CAP_SYS_ADMIN`` capability. This requirement stems from several security and resource management considerations that are actively being discussed and worked on. The primary reasons for this restriction are detailed below.”h]”(hŒWSetting up passthrough functionality currently requires the FUSE daemon to possess the ”…””}”(hj´h²hh³Nh´Nubj)”}”(hŒ``CAP_SYS_ADMIN``”h]”hŒ CAP_SYS_ADMIN”…””}”(hj¼h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj´ubhŒÎ capability. This requirement stems from several security and resource management considerations that are actively being discussed and worked on. The primary reasons for this restriction are detailed below.”…””}”(hj´h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K4hj£h²hubhÉ)”}”(hhh]”(hÎ)”}”(hŒ"Resource Accounting and Visibility”h]”hŒ"Resource Accounting and Visibility”…””}”(hj×h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjÔh²hh³hÇh´K;ubhï)”}”(hXaThe core mechanism for passthrough involves the FUSE daemon opening a file descriptor to a backing file and registering it with the FUSE kernel module via the ``FUSE_DEV_IOC_BACKING_OPEN`` ioctl. This ioctl returns a ``backing_id`` associated with a kernel-internal ``struct fuse_backing`` object, which holds a reference to the backing ``struct file``.”h]”(hŒŸThe core mechanism for passthrough involves the FUSE daemon opening a file descriptor to a backing file and registering it with the FUSE kernel module via the ”…””}”(hjåh²hh³Nh´Nubj)”}”(hŒ``FUSE_DEV_IOC_BACKING_OPEN``”h]”hŒFUSE_DEV_IOC_BACKING_OPEN”…””}”(hjíh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjåubhŒ ioctl. This ioctl returns a ”…””}”(hjåh²hh³Nh´Nubj)”}”(hŒ``backing_id``”h]”hŒ backing_id”…””}”(hjÿh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjåubhŒ# associated with a kernel-internal ”…””}”(hjåh²hh³Nh´Nubj)”}”(hŒ``struct fuse_backing``”h]”hŒstruct fuse_backing”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjåubhŒ0 object, which holds a reference to the backing ”…””}”(hjåh²hh³Nh´Nubj)”}”(hŒ``struct file``”h]”hŒ struct file”…””}”(hj#h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjåubhŒ.”…””}”(hjåh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K=hjÔh²hubhï)”}”(hX]A significant concern arises because the FUSE daemon can close its own file descriptor to the backing file after registration. The kernel, however, will still hold a reference to the ``struct file`` via the ``struct fuse_backing`` object as long as it's associated with a ``backing_id`` (or subsequently, with an open FUSE file in passthrough mode).”h]”(hŒ·A significant concern arises because the FUSE daemon can close its own file descriptor to the backing file after registration. The kernel, however, will still hold a reference to the ”…””}”(hj;h²hh³Nh´Nubj)”}”(hŒ``struct file``”h]”hŒ struct file”…””}”(hjCh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj;ubhŒ via the ”…””}”(hj;h²hh³Nh´Nubj)”}”(hŒ``struct fuse_backing``”h]”hŒstruct fuse_backing”…””}”(hjUh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj;ubhŒ, object as long as it’s associated with a ”…””}”(hj;h²hh³Nh´Nubj)”}”(hŒ``backing_id``”h]”hŒ backing_id”…””}”(hjgh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj;ubhŒ? (or subsequently, with an open FUSE file in passthrough mode).”…””}”(hj;h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KChjÔh²hubhï)”}”(hŒEThis behavior leads to two main issues for unprivileged FUSE daemons:”h]”hŒEThis behavior leads to two main issues for unprivileged FUSE daemons:”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KIhjÔh²hubjø)”}”(hX1. **Invisibility to lsof and other inspection tools**: Once the FUSE daemon closes its file descriptor, the open backing file held by the kernel becomes "hidden." Standard tools like ``lsof``, which typically inspect process file descriptor tables, would not be able to identify that this file is still open by the system on behalf of the FUSE filesystem. This makes it difficult for system administrators to track resource usage or debug issues related to open files (e.g., preventing unmounts). 2. **Bypassing RLIMIT_NOFILE**: The FUSE daemon process is subject to resource limits, including the maximum number of open file descriptors (``RLIMIT_NOFILE``). If an unprivileged daemon could register backing files and then close its own FDs, it could potentially cause the kernel to hold an unlimited number of open ``struct file`` references without these being accounted against the daemon's ``RLIMIT_NOFILE``. This could lead to a denial-of-service (DoS) by exhausting system-wide file resources. ”h]”jþ)”}”(hhh]”(j)”}”(hXï**Invisibility to lsof and other inspection tools**: Once the FUSE daemon closes its file descriptor, the open backing file held by the kernel becomes "hidden." Standard tools like ``lsof``, which typically inspect process file descriptor tables, would not be able to identify that this file is still open by the system on behalf of the FUSE filesystem. This makes it difficult for system administrators to track resource usage or debug issues related to open files (e.g., preventing unmounts). ”h]”hï)”}”(hXî**Invisibility to lsof and other inspection tools**: Once the FUSE daemon closes its file descriptor, the open backing file held by the kernel becomes "hidden." Standard tools like ``lsof``, which typically inspect process file descriptor tables, would not be able to identify that this file is still open by the system on behalf of the FUSE filesystem. This makes it difficult for system administrators to track resource usage or debug issues related to open files (e.g., preventing unmounts).”h]”(hŒstrong”“”)”}”(hŒ3**Invisibility to lsof and other inspection tools**”h]”hŒ/Invisibility to lsof and other inspection tools”…””}”(hjžh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jœhj˜ubhŒ†: Once the FUSE daemon closes its file descriptor, the open backing file held by the kernel becomes “hidden.†Standard tools like ”…””}”(hj˜h²hh³Nh´Nubj)”}”(hŒ``lsof``”h]”hŒlsof”…””}”(hj°h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj˜ubhX1, which typically inspect process file descriptor tables, would not be able to identify that this file is still open by the system on behalf of the FUSE filesystem. This makes it difficult for system administrators to track resource usage or debug issues related to open files (e.g., preventing unmounts).”…””}”(hj˜h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KKhj”ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj‘ubj)”}”(hXô**Bypassing RLIMIT_NOFILE**: The FUSE daemon process is subject to resource limits, including the maximum number of open file descriptors (``RLIMIT_NOFILE``). If an unprivileged daemon could register backing files and then close its own FDs, it could potentially cause the kernel to hold an unlimited number of open ``struct file`` references without these being accounted against the daemon's ``RLIMIT_NOFILE``. This could lead to a denial-of-service (DoS) by exhausting system-wide file resources. ”h]”hï)”}”(hXó**Bypassing RLIMIT_NOFILE**: The FUSE daemon process is subject to resource limits, including the maximum number of open file descriptors (``RLIMIT_NOFILE``). If an unprivileged daemon could register backing files and then close its own FDs, it could potentially cause the kernel to hold an unlimited number of open ``struct file`` references without these being accounted against the daemon's ``RLIMIT_NOFILE``. This could lead to a denial-of-service (DoS) by exhausting system-wide file resources.”h]”(j)”}”(hŒ**Bypassing RLIMIT_NOFILE**”h]”hŒBypassing RLIMIT_NOFILE”…””}”(hjÖh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jœhjÒubhŒp: The FUSE daemon process is subject to resource limits, including the maximum number of open file descriptors (”…””}”(hjÒh²hh³Nh´Nubj)”}”(hŒ``RLIMIT_NOFILE``”h]”hŒ RLIMIT_NOFILE”…””}”(hjèh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÒubhŒ ). If an unprivileged daemon could register backing files and then close its own FDs, it could potentially cause the kernel to hold an unlimited number of open ”…””}”(hjÒh²hh³Nh´Nubj)”}”(hŒ``struct file``”h]”hŒ struct file”…””}”(hjúh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÒubhŒA references without these being accounted against the daemon’s ”…””}”(hjÒh²hh³Nh´Nubj)”}”(hŒ``RLIMIT_NOFILE``”h]”hŒ RLIMIT_NOFILE”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÒubhŒX. This could lead to a denial-of-service (DoS) by exhausting system-wide file resources.”…””}”(hjÒh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KShjÎubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj‘ubeh}”(h]”h ]”h"]”h$]”h&]”jj‘j’hj“j”uh1jýhjubah}”(h]”h ]”h"]”h$]”h&]”uh1j÷h³hÇh´KKhjÔh²hubhï)”}”(hŒ†The ``CAP_SYS_ADMIN`` requirement acts as a safeguard against these issues, restricting this powerful capability to trusted processes.”h]”(hŒThe ”…””}”(hj6h²hh³Nh´Nubj)”}”(hŒ``CAP_SYS_ADMIN``”h]”hŒ CAP_SYS_ADMIN”…””}”(hj>h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj6ubhŒq requirement acts as a safeguard against these issues, restricting this powerful capability to trusted processes.”…””}”(hj6h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K[hjÔh²hubhï)”}”(hŒ®**NOTE**: ``io_uring`` solves this similar issue by exposing its "fixed files", which are visible via ``fdinfo`` and accounted under the registering user's ``RLIMIT_NOFILE``.”h]”(j)”}”(hŒ**NOTE**”h]”hŒNOTE”…””}”(hjZh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jœhjVubhŒ: ”…””}”(hjVh²hh³Nh´Nubj)”}”(hŒ ``io_uring``”h]”hŒio_uring”…””}”(hjlh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjVubhŒT solves this similar issue by exposing its “fixed filesâ€, which are visible via ”…””}”(hjVh²hh³Nh´Nubj)”}”(hŒ ``fdinfo``”h]”hŒfdinfo”…””}”(hj~h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjVubhŒ. and accounted under the registering user’s ”…””}”(hjVh²hh³Nh´Nubj)”}”(hŒ``RLIMIT_NOFILE``”h]”hŒ RLIMIT_NOFILE”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjVubhŒ.”…””}”(hjVh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K^hjÔh²hubeh}”(h]”Œ"resource-accounting-and-visibility”ah ]”h"]”Œ"resource accounting and visibility”ah$]”h&]”uh1hÈhj£h²hh³hÇh´K;ubhÉ)”}”(hhh]”(hÎ)”}”(hŒ&Filesystem Stacking and Shutdown Loops”h]”hŒ&Filesystem Stacking and Shutdown Loops”…””}”(hj³h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj°h²hh³hÇh´Kcubhï)”}”(hŒàAnother concern relates to the potential for creating complex and problematic filesystem stacking scenarios if unprivileged users could set up passthrough. A FUSE passthrough filesystem might use a backing file that resides:”h]”hŒàAnother concern relates to the potential for creating complex and problematic filesystem stacking scenarios if unprivileged users could set up passthrough. A FUSE passthrough filesystem might use a backing file that resides:”…””}”(hjÁh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´Kehj°h²hubjø)”}”(hŒ—* On the *same* FUSE filesystem. * On another filesystem (like OverlayFS) which itself might have an upper or lower layer that is a FUSE filesystem. ”h]”hŒ bullet_list”“”)”}”(hhh]”(j)”}”(hŒOn the *same* FUSE filesystem.”h]”hï)”}”(hjÚh]”(hŒOn the ”…””}”(hjÜh²hh³Nh´NubhŒemphasis”“”)”}”(hŒ*same*”h]”hŒsame”…””}”(hjåh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jãhjÜubhŒ FUSE filesystem.”…””}”(hjÜh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KihjØubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÕubj)”}”(hŒrOn another filesystem (like OverlayFS) which itself might have an upper or lower layer that is a FUSE filesystem. ”h]”hï)”}”(hŒqOn another filesystem (like OverlayFS) which itself might have an upper or lower layer that is a FUSE filesystem.”h]”hŒqOn another filesystem (like OverlayFS) which itself might have an upper or lower layer that is a FUSE filesystem.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´Kjhjubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÕubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ*”uh1jÓh³hÇh´KihjÏubah}”(h]”h ]”h"]”h$]”h&]”uh1j÷h³hÇh´Kihj°h²hubhï)”}”(hXThese configurations could create dependency loops, particularly during filesystem shutdown or unmount sequences, leading to deadlocks or system instability. This is conceptually similar to the risks associated with the ``LOOP_SET_FD`` ioctl, which also requires ``CAP_SYS_ADMIN``.”h]”(hŒÜThese configurations could create dependency loops, particularly during filesystem shutdown or unmount sequences, leading to deadlocks or system instability. This is conceptually similar to the risks associated with the ”…””}”(hj)h²hh³Nh´Nubj)”}”(hŒ``LOOP_SET_FD``”h]”hŒ LOOP_SET_FD”…””}”(hj1h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj)ubhŒ ioctl, which also requires ”…””}”(hj)h²hh³Nh´Nubj)”}”(hŒ``CAP_SYS_ADMIN``”h]”hŒ CAP_SYS_ADMIN”…””}”(hjCh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj)ubhŒ.”…””}”(hj)h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´Kmhj°h²hubhï)”}”(hX«To mitigate this, FUSE passthrough already incorporates checks based on filesystem stacking depth (``sb->s_stack_depth`` and ``fc->max_stack_depth``). For example, during the ``FUSE_INIT`` handshake, the FUSE daemon can negotiate the ``max_stack_depth`` it supports. When a backing file is registered via ``FUSE_DEV_IOC_BACKING_OPEN``, the kernel checks if the backing file's filesystem stack depth is within the allowed limit.”h]”(hŒcTo mitigate this, FUSE passthrough already incorporates checks based on filesystem stacking depth (”…””}”(hj[h²hh³Nh´Nubj)”}”(hŒ``sb->s_stack_depth``”h]”hŒsb->s_stack_depth”…””}”(hjch²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj[ubhŒ and ”…””}”(hj[h²hh³Nh´Nubj)”}”(hŒ``fc->max_stack_depth``”h]”hŒfc->max_stack_depth”…””}”(hjuh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj[ubhŒ). For example, during the ”…””}”(hj[h²hh³Nh´Nubj)”}”(hŒ ``FUSE_INIT``”h]”hŒ FUSE_INIT”…””}”(hj‡h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj[ubhŒ. handshake, the FUSE daemon can negotiate the ”…””}”(hj[h²hh³Nh´Nubj)”}”(hŒ``max_stack_depth``”h]”hŒmax_stack_depth”…””}”(hj™h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj[ubhŒ4 it supports. When a backing file is registered via ”…””}”(hj[h²hh³Nh´Nubj)”}”(hŒ``FUSE_DEV_IOC_BACKING_OPEN``”h]”hŒFUSE_DEV_IOC_BACKING_OPEN”…””}”(hj«h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj[ubhŒ_, the kernel checks if the backing file’s filesystem stack depth is within the allowed limit.”…””}”(hj[h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´Krhj°h²hubhï)”}”(hŒ«The ``CAP_SYS_ADMIN`` requirement provides an additional layer of security, ensuring that only privileged users can create these potentially complex stacking arrangements.”h]”(hŒThe ”…””}”(hjÃh²hh³Nh´Nubj)”}”(hŒ``CAP_SYS_ADMIN``”h]”hŒ CAP_SYS_ADMIN”…””}”(hjËh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÃubhŒ– requirement provides an additional layer of security, ensuring that only privileged users can create these potentially complex stacking arrangements.”…””}”(hjÃh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´Kyhj°h²hubeh}”(h]”Œ&filesystem-stacking-and-shutdown-loops”ah ]”h"]”Œ&filesystem stacking and shutdown loops”ah$]”h&]”uh1hÈhj£h²hh³hÇh´KcubhÉ)”}”(hhh]”(hÎ)”}”(hŒGeneral Security Posture”h]”hŒGeneral Security Posture”…””}”(hjîh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjëh²hh³hÇh´K~ubhï)”}”(hX“As a general principle for new kernel features that allow userspace to instruct the kernel to perform direct operations on its behalf based on user-provided file descriptors, starting with a higher privilege requirement (like ``CAP_SYS_ADMIN``) is a conservative and common security practice. This allows the feature to be used and tested while further security implications are evaluated and addressed.”h]”(hŒâAs a general principle for new kernel features that allow userspace to instruct the kernel to perform direct operations on its behalf based on user-provided file descriptors, starting with a higher privilege requirement (like ”…””}”(hjüh²hh³Nh´Nubj)”}”(hŒ``CAP_SYS_ADMIN``”h]”hŒ CAP_SYS_ADMIN”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjüubhŒ ) is a conservative and common security practice. This allows the feature to be used and tested while further security implications are evaluated and addressed.”…””}”(hjüh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K€hjëh²hubeh}”(h]”Œgeneral-security-posture”ah ]”h"]”Œgeneral security posture”ah$]”h&]”uh1hÈhj£h²hh³hÇh´K~ubeh}”(h]”Œprivilege-requirements”ah ]”h"]”Œprivilege requirements”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K2ubeh}”(h]”Œfuse-passthrough”ah ]”h"]”Œfuse passthrough”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”jWŒ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”}”(j1j.jÕjÒj jj)j&j­jªjèjåj!juŒ nametypes”}”(j1‰jÕ‰j ‰j)‰j­‰jè‰j!‰uh}”(j.hÊjÒhÝjjØj&j£jªjÔjåj°jjë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.