요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. SPDX-License-Identifier: GPL-2.0
================
FUSE Passthrough
================
Introduction
============
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".
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.
Currently, passthrough is supported for operations like ``read(2)``/``write(2)``
(via ``read_iter``/``write_iter``), ``splice(2)``, and ``mmap(2)``.
Enabling Passthrough
====================
To use FUSE passthrough:
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.
Privilege Requirements
======================
Setting 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.
Resource Accounting and Visibility
----------------------------------
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 ``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``.
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).
This behavior leads to two main issues for unprivileged FUSE daemons:
1. **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.
The ``CAP_SYS_ADMIN`` requirement acts as a safeguard against these issues,
restricting this powerful capability to trusted processes.
**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``.
Filesystem Stacking and Shutdown Loops
--------------------------------------
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:
* On the *same* FUSE filesystem.
* On another filesystem (like OverlayFS) which itself might have an upper or
lower layer that is a FUSE filesystem.
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
``LOOP_SET_FD`` ioctl, which also requires ``CAP_SYS_ADMIN``.
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.
The ``CAP_SYS_ADMIN`` requirement provides an additional layer of security,
ensuring that only privileged users can create these potentially complex
stacking arrangements.
General Security Posture
------------------------
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.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
Passthrough 목적과 backing file 연결
1-27FUSE passthrough는 FUSE filesystem의 I/O operation 성능을 높이기 위한 기능입니다. 일반 FUSE operation은 kernel과 사용자 공간 FUSE daemon 사이 통신 비용을 내지만, passthrough는 특정 FUSE file operation이 daemon을 우회해 하위 filesystem의 `backing file`에서 kernel에 의해 직접 실행되도록 합니다.
FUSE daemon은 하위 filesystem의 backing file을 가리키는 file descriptor를 FUSE kernel module에 등록합니다. kernel은 등록된 backing file을 식별하는 `backing_id`를 반환합니다.
나중에 FUSE file의 `OPEN` request를 처리할 때 daemon은 reply에 해당 `backing_id`를 넣고 `FOPEN_PASSTHROUGH` flag를 설정할 수 있습니다. 이 응답이 FUSE file과 하위 backing file 사이의 직접 연결을 특정 operation에 대해 성립시킵니다.
현재 passthrough가 지원하는 operation은 `read(2)`와 `write(2)`의 `read_iter`·`write_iter` 경로, `splice(2)`, `mmap(2)`입니다. metadata operation 전체를 우회하는 기능이 아니라 지정된 data-path operation의 최적화입니다.
daemon이 연결을 설정한 뒤 지원 I/O가 하위 파일로 직접 향하는 흐름입니다.
원문이 명시한 지원 operation만 정리했습니다.
.. SPDX-License-Identifier: GPL-2.0
================
FUSE Passthrough
================
Introduction
============
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".
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.
Currently, passthrough is supported for operations like ``read(2)``/``write(2)``
(via ``read_iter``/``write_iter``), ``splice(2)``, and ``mmap(2)``.
활성화 절차와 권한 요구
28-57FUSE passthrough를 사용하려면 먼저 kernel을 `CONFIG_FUSE_PASSTHROUGH`가 활성화된 상태로 빌드해야 합니다.
FUSE daemon은 `FUSE_INIT` handshake에서 `FUSE_PASSTHROUGH` capability를 협상하고 자신이 원하는 `max_stack_depth`를 지정합니다.
권한 있는 daemon은 `/dev/fuse` 같은 connection file descriptor에서 `FUSE_DEV_IOC_BACKING_OPEN` ioctl을 호출해 backing file descriptor를 등록하고 `backing_id`를 얻습니다.
FUSE file의 `OPEN` 또는 `CREATE` request를 처리할 때 daemon은 `fuse_open_out::open_flags`에 `FOPEN_PASSTHROUGH`를 설정하고 대응하는 `backing_id`를 `fuse_open_out::backing_id`에 넣습니다.
passthrough setup에 더 이상 필요하지 않은 backing file의 kernel reference를 해제하려면 daemon이 최종적으로 그 `backing_id`로 `FUSE_DEV_IOC_BACKING_CLOSE`를 호출해야 합니다.
현재 passthrough 설정에는 FUSE daemon의 `CAP_SYS_ADMIN` capability가 필요합니다. 이 제한은 자원 관리와 보안 문제를 보수적으로 통제하기 위한 것이며 관련 문제의 개선 방안은 계속 논의·개발 중입니다.
kernel 구성부터 backing reference 해제까지의 순서입니다.
Enabling Passthrough
====================
To use FUSE passthrough:
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.
Privilege Requirements
======================
Setting 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.
Resource accounting과 visibility 문제
58-97핵심 mechanism은 daemon이 backing file fd를 열고 `FUSE_DEV_IOC_BACKING_OPEN`으로 등록하는 것입니다. ioctl이 반환한 `backing_id`는 kernel 내부 `struct fuse_backing` object와 연결되며, 이 object는 backing `struct file` reference를 보유합니다.
등록 뒤 daemon이 자신의 backing fd를 닫아도 kernel은 `backing_id` 또는 passthrough mode로 열린 FUSE file과 연결된 동안 `struct fuse_backing`을 통해 `struct file` reference를 계속 보유합니다.
권한 없는 daemon에 이를 허용할 때 첫 문제는 `lsof`와 inspection tool에서 보이지 않는다는 점입니다. daemon fd table에서 fd가 사라진 뒤 kernel이 대신 보유한 open backing file은 process fd table을 검사하는 일반 도구로 찾을 수 없습니다.
이 visibility 부족은 system administrator가 resource usage를 추적하거나 unmount를 막는 open file 같은 문제를 debug하기 어렵게 만듭니다.
두 번째 문제는 `RLIMIT_NOFILE` 우회입니다. daemon은 열 수 있는 fd 수 제한을 받지만 backing file을 등록하고 자신의 fd를 닫는 동작을 반복하면, daemon 한도에 계산되지 않는 open `struct file` reference를 kernel에 제한 없이 남길 수 있습니다.
이 동작은 system-wide file resource를 고갈시키는 denial-of-service로 이어질 수 있습니다. `CAP_SYS_ADMIN` 요구는 강력한 등록 기능을 신뢰하는 process로 제한하는 방어선입니다.
비슷한 문제를 다루는 `io_uring`은 fixed file을 `fdinfo`에 표시하고 등록 사용자의 `RLIMIT_NOFILE`에 계산합니다. 원문은 이를 향후 FUSE resource accounting과 visibility 개선을 비교할 선례로 듭니다.
daemon fd와 kernel reference의 수명이 갈라지는 지점을 보여줍니다.
CAP_SYS_ADMIN이 현재 막는 두 가지 문제입니다.
Resource Accounting and Visibility
----------------------------------
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 ``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``.
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).
This behavior leads to two main issues for unprivileged FUSE daemons:
1. **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.
The ``CAP_SYS_ADMIN`` requirement acts as a safeguard against these issues,
restricting this powerful capability to trusted processes.
**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``.
Filesystem stacking과 보수적 보안 정책
98-133권한 없는 사용자가 passthrough를 구성하면 복잡하고 문제가 되는 filesystem stacking을 만들 수 있습니다. backing file이 같은 FUSE filesystem에 있거나, upper 또는 lower layer가 FUSE인 OverlayFS 같은 다른 filesystem에 있을 수 있습니다.
이런 구성은 특히 filesystem shutdown이나 unmount 순서에서 dependency loop를 만들어 deadlock 또는 system instability를 일으킬 수 있습니다. 위험 성격은 `CAP_SYS_ADMIN`을 요구하는 `LOOP_SET_FD` ioctl과 비슷합니다.
FUSE passthrough는 이미 `sb->s_stack_depth`와 `fc->max_stack_depth`를 바탕으로 stacking depth를 검사합니다. daemon은 `FUSE_INIT` handshake에서 지원하는 `max_stack_depth`를 협상합니다.
`FUSE_DEV_IOC_BACKING_OPEN`으로 backing file을 등록할 때 kernel은 backing file filesystem의 stack depth가 허용 한도 안인지 확인합니다.
depth 검사가 있더라도 `CAP_SYS_ADMIN`은 잠재적으로 복잡한 stacking arrangement를 권한 있는 사용자만 만들게 하는 추가 보안 계층입니다.
사용자 공간이 제공한 fd를 바탕으로 kernel이 사용자 대신 직접 operation을 수행하게 하는 새 kernel feature에는 처음에 `CAP_SYS_ADMIN` 같은 높은 권한을 요구하는 것이 보수적이고 일반적인 보안 관행입니다.
이 접근은 기능을 실제로 사용·시험할 수 있게 하면서 추가 보안 영향을 평가하고 해결할 시간을 확보합니다. 향후 accounting과 loop 방지가 충분히 강화되면 권한 요구를 재검토할 수 있지만, 이 문서가 설명하는 현재 interface에서는 권한 요구가 설계의 일부입니다.
협상된 depth 검사와 privilege가 겹쳐 작동합니다.
stacking dependency가 생길 수 있는 대표 구성을 정리했습니다.
Filesystem Stacking and Shutdown Loops
--------------------------------------
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:
* On the *same* FUSE filesystem.
* On another filesystem (like OverlayFS) which itself might have an upper or
lower layer that is a FUSE filesystem.
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
``LOOP_SET_FD`` ioctl, which also requires ``CAP_SYS_ADMIN``.
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.
The ``CAP_SYS_ADMIN`` requirement provides an additional layer of security,
ensuring that only privileged users can create these potentially complex
stacking arrangements.
General Security Posture
------------------------
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.
요약·해설
fuse-passthrough.rst:1-133FUSE passthrough는 daemon이 등록한 하위 backing file과 FUSE file을 `backing_id`로 연결해 read·write·splice·mmap data path를 kernel에서 직접 수행합니다. 성능 이득과 함께 backing `struct file`의 수명·visibility·accounting 책임이 kernel로 이동합니다.
현재 `CAP_SYS_ADMIN` 요구는 daemon fd를 닫은 뒤 `lsof`와 `RLIMIT_NOFILE`에서 벗어나는 reference, filesystem stacking의 shutdown loop를 통제하는 보수적 방어입니다. `max_stack_depth` 검사만으로 privilege 요구가 대체되지는 않습니다.
fd 등록이 성능 경로와 자원·stacking 위험을 동시에 만듭니다.