← Documents Documentation/filesystems/fuse/fuse-passthrough.rst GitHub 원문 ↗

Linux 6.18.37 · Filesystems

FUSE Passthrough

FUSE passthrough의 backing file 등록, 지원 I/O, resource accounting, stack depth와 CAP_SYS_ADMIN 보안 근거를 다루는 전문 번역입니다.

Source pathDocumentation/filesystems/fuse/fuse-passthrough.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

fuse-passthrough.rst:1-133

FUSE 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 요구가 대체되지는 않습니다.

Passthrough 신뢰 경계
권한 있는 daemon이 backing fd 등록kernel이 `struct fuse_backing` reference와 id 보유OPEN reply가 FUSE file에 backing id 연결지원 I/O는 daemon을 우회해 성능 향상kernel reference는 daemon fd보다 오래 생존 가능CLOSE ioctl·depth 검사·CAP_SYS_ADMIN으로 위험 통제

fd 등록이 성능 경로와 자원·stacking 위험을 동시에 만듭니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2
3 ================
4 FUSE Passthrough
5 ================
6
7 Introduction
8 ============
9
10 FUSE (Filesystem in Userspace) passthrough is a feature designed to improve the
11 performance of FUSE filesystems for I/O operations. Typically, FUSE operations
12 involve communication between the kernel and a userspace FUSE daemon, which can
13 incur overhead. Passthrough allows certain operations on a FUSE file to bypass
14 the userspace daemon and be executed directly by the kernel on an underlying
15 "backing file".
16
17 This is achieved by the FUSE daemon registering a file descriptor (pointing to
18 the backing file on a lower filesystem) with the FUSE kernel module. The kernel
19 then receives an identifier (``backing_id``) for this registered backing file.
20 When a FUSE file is subsequently opened, the FUSE daemon can, in its response to
21 the ``OPEN`` request, include this ``backing_id`` and set the
22 ``FOPEN_PASSTHROUGH`` flag. This establishes a direct link for specific
23 operations.
24
25 Currently, passthrough is supported for operations like ``read(2)``/``write(2)``
26 (via ``read_iter``/``write_iter``), ``splice(2)``, and ``mmap(2)``.
27
28 Enabling Passthrough
29 ====================
30
31 To use FUSE passthrough:
32
33 1. The FUSE filesystem must be compiled with ``CONFIG_FUSE_PASSTHROUGH``
34 enabled.
35 2. The FUSE daemon, during the ``FUSE_INIT`` handshake, must negotiate the
36 ``FUSE_PASSTHROUGH`` capability and specify its desired
37 ``max_stack_depth``.
38 3. The (privileged) FUSE daemon uses the ``FUSE_DEV_IOC_BACKING_OPEN`` ioctl
39 on its connection file descriptor (e.g., ``/dev/fuse``) to register a
40 backing file descriptor and obtain a ``backing_id``.
41 4. When handling an ``OPEN`` or ``CREATE`` request for a FUSE file, the daemon
42 replies with the ``FOPEN_PASSTHROUGH`` flag set in
43 ``fuse_open_out::open_flags`` and provides the corresponding ``backing_id``
44 in ``fuse_open_out::backing_id``.
45 5. The FUSE daemon should eventually call ``FUSE_DEV_IOC_BACKING_CLOSE`` with
46 the ``backing_id`` to release the kernel's reference to the backing file
47 when it's no longer needed for passthrough setups.
48
49 Privilege Requirements
50 ======================
51
52 Setting up passthrough functionality currently requires the FUSE daemon to
53 possess the ``CAP_SYS_ADMIN`` capability. This requirement stems from several
54 security and resource management considerations that are actively being
55 discussed and worked on. The primary reasons for this restriction are detailed
56 below.
57
58 Resource Accounting and Visibility
59 ----------------------------------
60
61 The core mechanism for passthrough involves the FUSE daemon opening a file
62 descriptor to a backing file and registering it with the FUSE kernel module via
63 the ``FUSE_DEV_IOC_BACKING_OPEN`` ioctl. This ioctl returns a ``backing_id``
64 associated with a kernel-internal ``struct fuse_backing`` object, which holds a
65 reference to the backing ``struct file``.
66
67 A significant concern arises because the FUSE daemon can close its own file
68 descriptor to the backing file after registration. The kernel, however, will
69 still hold a reference to the ``struct file`` via the ``struct fuse_backing``
70 object as long as it's associated with a ``backing_id`` (or subsequently, with
71 an open FUSE file in passthrough mode).
72
73 This behavior leads to two main issues for unprivileged FUSE daemons:
74
75 1. **Invisibility to lsof and other inspection tools**: Once the FUSE
76 daemon closes its file descriptor, the open backing file held by the kernel
77 becomes "hidden." Standard tools like ``lsof``, which typically inspect
78 process file descriptor tables, would not be able to identify that this
79 file is still open by the system on behalf of the FUSE filesystem. This
80 makes it difficult for system administrators to track resource usage or
81 debug issues related to open files (e.g., preventing unmounts).
82
83 2. **Bypassing RLIMIT_NOFILE**: The FUSE daemon process is subject to
84 resource limits, including the maximum number of open file descriptors
85 (``RLIMIT_NOFILE``). If an unprivileged daemon could register backing files
86 and then close its own FDs, it could potentially cause the kernel to hold
87 an unlimited number of open ``struct file`` references without these being
88 accounted against the daemon's ``RLIMIT_NOFILE``. This could lead to a
89 denial-of-service (DoS) by exhausting system-wide file resources.
90
91 The ``CAP_SYS_ADMIN`` requirement acts as a safeguard against these issues,
92 restricting this powerful capability to trusted processes.
93
94 **NOTE**: ``io_uring`` solves this similar issue by exposing its "fixed files",
95 which are visible via ``fdinfo`` and accounted under the registering user's
96 ``RLIMIT_NOFILE``.
97
98 Filesystem Stacking and Shutdown Loops
99 --------------------------------------
100
101 Another concern relates to the potential for creating complex and problematic
102 filesystem stacking scenarios if unprivileged users could set up passthrough.
103 A FUSE passthrough filesystem might use a backing file that resides:
104
105 * On the *same* FUSE filesystem.
106 * On another filesystem (like OverlayFS) which itself might have an upper or
107 lower layer that is a FUSE filesystem.
108
109 These configurations could create dependency loops, particularly during
110 filesystem shutdown or unmount sequences, leading to deadlocks or system
111 instability. This is conceptually similar to the risks associated with the
112 ``LOOP_SET_FD`` ioctl, which also requires ``CAP_SYS_ADMIN``.
113
114 To mitigate this, FUSE passthrough already incorporates checks based on
115 filesystem stacking depth (``sb->s_stack_depth`` and ``fc->max_stack_depth``).
116 For example, during the ``FUSE_INIT`` handshake, the FUSE daemon can negotiate
117 the ``max_stack_depth`` it supports. When a backing file is registered via
118 ``FUSE_DEV_IOC_BACKING_OPEN``, the kernel checks if the backing file's
119 filesystem stack depth is within the allowed limit.
120
121 The ``CAP_SYS_ADMIN`` requirement provides an additional layer of security,
122 ensuring that only privileged users can create these potentially complex
123 stacking arrangements.
124
125 General Security Posture
126 ------------------------
127
128 As a general principle for new kernel features that allow userspace to instruct
129 the kernel to perform direct operations on its behalf based on user-provided
130 file descriptors, starting with a higher privilege requirement (like
131 ``CAP_SYS_ADMIN``) is a conservative and common security practice. This allows
132 the feature to be used and tested while further security implications are
133 evaluated and addressed.
134

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

Passthrough 목적과 backing file 연결

1-27

FUSE 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의 최적화입니다.

Passthrough 데이터 경로
daemon이 lower filesystem의 backing file fd 열기fd를 kernel에 등록하고 `backing_id` 수신FUSE `OPEN` reply에 `FOPEN_PASSTHROUGH`와 `backing_id` 지정kernel이 FUSE file과 backing `struct file` 연결`read_iter`·`write_iter`·`splice`·`mmap`을 backing file로 직접 실행

daemon이 연결을 설정한 뒤 지원 I/O가 하위 파일로 직접 향하는 흐름입니다.

현재 passthrough 범위
사용자 APIkernel 경로passthrough
`read(2)``read_iter`지원
`write(2)``write_iter`지원
`splice(2)`splice data path지원
`mmap(2)`mapping path지원

원문이 명시한 지원 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-57

FUSE 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가 필요합니다. 이 제한은 자원 관리와 보안 문제를 보수적으로 통제하기 위한 것이며 관련 문제의 개선 방안은 계속 논의·개발 중입니다.

Passthrough 활성화 수명 주기
`CONFIG_FUSE_PASSTHROUGH` 활성 kernel 사용`FUSE_INIT`에서 `FUSE_PASSTHROUGH`와 `max_stack_depth` 협상`FUSE_DEV_IOC_BACKING_OPEN`으로 fd 등록반환된 `backing_id`를 OPEN·CREATE reply에 연결지원 I/O를 passthrough로 수행사용 종료 시 `FUSE_DEV_IOC_BACKING_CLOSE(backing_id)`

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 개선을 비교할 선례로 듭니다.

숨은 backing reference가 생기는 과정
daemon이 backing file fd를 열어 RLIMIT_NOFILE에 계산BACKING_OPEN이 `struct fuse_backing`과 `struct file` reference 생성daemon이 자신의 fd를 닫아 fd table에서 제거kernel reference는 `backing_id` 때문에 계속 생존`lsof` visibility와 daemon RLIMIT accounting에서 벗어남대량 반복 시 system-wide file resource DoS 가능

daemon fd와 kernel reference의 수명이 갈라지는 지점을 보여줍니다.

권한 제한의 자원 근거
문제원인영향
inspection visibilitykernel reference가 process fd table에 없음`lsof` 추적·unmount 진단 곤란
`RLIMIT_NOFILE` 우회daemon fd close 뒤 reference 생존무제한 `struct file`로 DoS 가능
io_uring 비교fixed files를 `fdinfo`와 사용자 한도에 연결향후 개선의 참고 모델

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에서는 권한 요구가 설계의 일부입니다.

Stacking loop 방어
daemon이 `FUSE_INIT`에서 `max_stack_depth` 제시BACKING_OPEN 대상 filesystem의 `sb->s_stack_depth` 조회kernel이 `fc->max_stack_depth`와 비교허용 범위를 넘는 backing registration 거부범위 안이어도 설정 주체에 `CAP_SYS_ADMIN` 요구shutdown·unmount dependency loop 위험을 이중 제한

협상된 depth 검사와 privilege가 겹쳐 작동합니다.

위험한 backing 배치
배치위험
같은 FUSE filesystem의 file자기 참조 dependency
다른 FUSE filesystem상호 shutdown 순서 loop
FUSE layer를 가진 OverlayFS간접 upper·lower dependency
loop device와 유사한 fd 연결`LOOP_SET_FD`와 같은 관리 위험

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.