Skip to content

fix(fuse): enforce read-only flags for direct mounts#742

Open
you06 wants to merge 1 commit into
mem9-ai:mainfrom
you06:fix/direct-mount-read-only-flags
Open

fix(fuse): enforce read-only flags for direct mounts#742
you06 wants to merge 1 commit into
mem9-ai:mainfrom
you06:fix/direct-mount-read-only-flags

Conversation

@you06

@you06 you06 commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Summary

  • enforce MS_RDONLY for Linux read-only direct mounts
  • preserve go-fuse's default MS_NODEV | MS_NOSUID flags when overriding DirectMountFlags
  • keep the existing ro mount option for the fusermount path
  • add platform-specific flag helpers and regression coverage

Problem

Drive9 maps --read-only to the FUSE option string ro. This works through fusermount, which consumes -o ro, but the pinned go-fuse direct-mount path does not translate ro into the MS_RDONLY mount flag.

As a result, a read-only direct mount could be mounted successfully while the kernel still reported it as writable. Drive9's userspace handlers reject mutating operations, but the mount itself was not protected by the kernel's read-only boundary.

Fix

For Linux read-only mounts, set:

MS_NODEV | MS_NOSUID | MS_RDONLY

DirectMountFlags replaces go-fuse's defaults when nonzero, so MS_NODEV and MS_NOSUID must be retained explicitly. The existing ro option remains in place so the fusermount path continues to work unchanged.

The mount flags are implemented behind Linux/non-Linux build-tagged helpers so non-Linux builds do not reference Linux-only syscall.MS_* constants.

Validation

  • regression red/green check:
    • without the mapping: DirectMountFlags = 0x0, want 0x7
    • with the mapping: test passes
  • go test ./pkg/fuse -run 'Test(ReadOnlyDirectMountFlags|GoFuseMountOptionsMaps(ReadOnly|DirectMountStrict))' -count=1
  • go test ./pkg/fuse -count=1
  • Darwin amd64 pkg/fuse test cross-compile
  • Linux arm64 pkg/fuse test cross-compile
  • make lint
  • make build
  • git diff --check
    The repository-wide test run reached all non-database packages successfully, but database-backed packages could not start because the local environment does not have permission to access the Docker socket used by testcontainers.

Privileged runtime acceptance

A Linux environment with direct-mount privileges should additionally verify a --read-only --direct-mount-strict mount with:

  • findmnt reports ro
  • statvfs includes ST_RDONLY
  • file creation fails immediately with EROFS

Summary by CodeRabbit

  • Bug Fixes

    • Improved read-only mount handling by applying the appropriate direct-mount flags on Linux.
    • Preserved read-only behavior across non-Linux platforms.
  • Tests

    • Added coverage verifying read-only mount options and platform-specific flag behavior.

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 647d226f-c3ff-4c21-895d-fdc7e7fe796e

📥 Commits

Reviewing files that changed from the base of the PR and between 638bef9 and de222e6.

📒 Files selected for processing (5)
  • pkg/fuse/dat9fs_test.go
  • pkg/fuse/direct_mount_flags_linux.go
  • pkg/fuse/direct_mount_flags_linux_test.go
  • pkg/fuse/direct_mount_flags_other.go
  • pkg/fuse/mount.go

📝 Walkthrough

Walkthrough

Read-only FUSE mounts now set platform-specific direct mount flags. Linux combines MS_NODEV, MS_NOSUID, and MS_RDONLY; non-Linux builds use zero. Tests cover both the helper and mount option mapping.

Changes

Read-only mount option handling

Layer / File(s) Summary
Platform-specific read-only flags
pkg/fuse/direct_mount_flags_linux.go, pkg/fuse/direct_mount_flags_other.go, pkg/fuse/direct_mount_flags_linux_test.go
Linux returns the combined read-only mount flags, non-Linux returns zero, and Linux tests validate the combination.
Mount option mapping
pkg/fuse/mount.go, pkg/fuse/dat9fs_test.go
Read-only mounts now assign DirectMountFlags and are tested alongside the existing "ro" option.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • mem9-ai/drive9#729: Updates go-fuse mount option construction and adds related option-mapping tests.

Suggested reviewers: qiffang, mornyx

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: enforcing read-only flags for direct FUSE mounts.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: de222e6c16

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread pkg/fuse/mount.go
}
if opts.ReadOnly {
fuseOpts.Options = append(fuseOpts.Options, "ro")
fuseOpts.DirectMountFlags = readOnlyDirectMountFlags()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Translate ro instead of forwarding it to direct mount

When --read-only is combined with --direct-mount-strict on Linux, this still leaves ro in fuseOpts.Options. In the pinned go-fuse fork, mountDirect only translates nodev/dev/nosuid/suid/noexec/exec from Options; other strings are passed into the FUSE data string, and its own comment says unrecognized data makes syscall.Mount fail with EINVAL. As a result the new MS_RDONLY flag does not make direct read-only mounts work unless ro is omitted or translated for the direct-mount path.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant