fuse: check O_LARGEFILE before masking it out of the open flags - #13969
Open
copybara-service[bot] wants to merge 1 commit into
Open
fuse: check O_LARGEFILE before masking it out of the open flags#13969copybara-service[bot] wants to merge 1 commit into
copybara-service[bot] wants to merge 1 commit into
Conversation
copybara-service
Bot
force-pushed
the
test/cl958610773
branch
from
August 3, 2026 22:46
b6abb6e to
8f9dabf
Compare
Files larger than 2GiB on a FUSE mount cannot be opened inside the sandbox: every
`open()` fails with `EOVERFLOW` ("Value too large for defined data type"), no matter what
flags the caller passes.
In `pkg/sentry/fsimpl/fuse/inode.go`, `Open()` masks the open flags against a whitelist
that does not include `O_LARGEFILE` on the line immediately before testing for it:
```go
opts.Flags &= linux.O_ACCMODE | linux.O_CREAT | linux.O_EXCL | linux.O_TRUNC |
linux.O_DIRECTORY | linux.O_NOFOLLOW | linux.O_NONBLOCK | linux.O_NOCTTY |
linux.O_APPEND | linux.O_DIRECT
i.attrMu.Lock()
defer i.attrMu.Unlock()
if opts.Flags&linux.O_LARGEFILE == 0 && i.size.Load() > linux.MAX_NON_LFS {
return nil, linuxerr.EOVERFLOW
}
```
`O_LARGEFILE` is always clear by the time it is tested, so the guard is unconditional for
any file over `MAX_NON_LFS`. This is not an obscure path: `openat(2)` adds `O_LARGEFILE`
for all 64-bit callers (`pkg/sentry/syscalls/linux/sys_file.go`) and the VFS layer
preserves it (`pkg/sentry/vfs/vfs.go`), so the flag is set on essentially every open and
the check should essentially never fire. No other filesystem implementation has this
check, which is why only FUSE mounts are affected.
Present since 298b5f3 ("Refactor FUSE inode implementation.", 2023-02-01), so in every
release from `release-20230214.0` onwards.
Reproduced with rclone's FUSE mount under `runsc do`: reading a 3GiB file through the
mount fails at `open()`, a 1GiB file on the same mount succeeds, and the same 3GiB file
read outside the mount succeeds.
The fix moves the mask below the check. `TestFUSEOpenLargeFile` covers both directions —
a file over `MAX_NON_LFS` opens with `O_LARGEFILE` and still returns `EOVERFLOW` without
it — and fails on the unpatched `inode.go`.
Assisted-by: Claude Code
FUTURE_COPYBARA_INTEGRATE_REVIEW=#13957 from jbbakeng:jbbakeng/fuse-largefile-open 3115757
PiperOrigin-RevId: 958610773
copybara-service
Bot
force-pushed
the
test/cl958610773
branch
from
August 3, 2026 23:05
8f9dabf to
a0cffb1
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
fuse: check O_LARGEFILE before masking it out of the open flags
Files larger than 2GiB on a FUSE mount cannot be opened inside the sandbox: every
open()fails withEOVERFLOW("Value too large for defined data type"), no matter whatflags the caller passes.
In
pkg/sentry/fsimpl/fuse/inode.go,Open()masks the open flags against a whitelistthat does not include
O_LARGEFILEon the line immediately before testing for it:O_LARGEFILEis always clear by the time it is tested, so the guard is unconditional forany file over
MAX_NON_LFS. This is not an obscure path:openat(2)addsO_LARGEFILEfor all 64-bit callers (
pkg/sentry/syscalls/linux/sys_file.go) and the VFS layerpreserves it (
pkg/sentry/vfs/vfs.go), so the flag is set on essentially every open andthe check should essentially never fire. No other filesystem implementation has this
check, which is why only FUSE mounts are affected.
Present since 298b5f3 ("Refactor FUSE inode implementation.", 2023-02-01), so in every
release from
release-20230214.0onwards.Reproduced with rclone's FUSE mount under
runsc do: reading a 3GiB file through themount fails at
open(), a 1GiB file on the same mount succeeds, and the same 3GiB fileread outside the mount succeeds.
The fix moves the mask below the check.
TestFUSEOpenLargeFilecovers both directions —a file over
MAX_NON_LFSopens withO_LARGEFILEand still returnsEOVERFLOWwithoutit — and fails on the unpatched
inode.go.Assisted-by: Claude Code
FUTURE_COPYBARA_INTEGRATE_REVIEW=#13957 from jbbakeng:jbbakeng/fuse-largefile-open 3115757