Skip to content

fix: fuse directory traversal permission enforcement and setattr mode handling#213

Merged
lzjqsdd merged 2 commits intoCurvineIO:mainfrom
jlon:setattr
Aug 20, 2025
Merged

fix: fuse directory traversal permission enforcement and setattr mode handling#213
lzjqsdd merged 2 commits intoCurvineIO:mainfrom
jlon:setattr

Conversation

@jlon
Copy link
Copy Markdown
Contributor

@jlon jlon commented Aug 19, 2025

Problem

LTP access01 tests were failing due to two critical issues in the FUSE filesystem implementation:

  1. Missing directory search permission enforcement: The access(), lookup(), read_dir(), and open_dir() operations were not properly checking execute (search) permissions on parent directories during path traversal, allowing unauthorized users like nobody to access files they shouldn't be able to reach.

  2. Incorrect setattr mode handling: The fuse_setattr_to_opts() function was not respecting FUSE's valid bits and was passing file type bits along with permission bits, causing incorrect file permissions to be applied during chown/chmod operations.

Solution

  1. Added directory search permission checks:

    • Implemented enforce_directory_search_permission() helper function with DirectoryAction enum
    • Added mandatory parent directory execute bit validation in access(), lookup(), read_dir_common(), and open_dir()
    • Ensures POSIX-compliant path traversal permission enforcement
  2. Fixed setattr mode processing:

    • Modified fuse_setattr_to_opts() to only process UID/GID/mode when corresponding FATTR_* valid bits are set
    • Strip file type bits from mode, keeping only permission bits (0o7777 mask)
    • Added proper mode application in mkdir() and create() operations

Testing

  • Resolves LTP access01 test failures where nobody user was incorrectly granted file access
  • Maintains backward compatibility for normal file operations
  • Ensures proper permission isolation between different user contexts

This fix ensures that the FUSE filesystem correctly implements POSIX directory traversal semantics and file attribute management.

PR description (short)
This PR addresses multiple LTP failures in curvine-fuse and the backend by fixing permission checks, time attribute propagation, and symlink rename semantics, while preserving inode IDs and improving FUSE attribute/xattr behavior. It also adds fsync handling and makes journal deserialization backward-compatible.
Changes summary by file
curvine-common/proto/master.proto
Add optional atime/mtime to SetAttrOptsProto to propagate time updates from FUSE to master.
Purpose: Fix utime01 by carrying time changes end-to-end.
curvine-common/src/state/opts.rs
Extend SetAttrOpts with atime/mtime fields and mark them #[serde(default)] for backward compatibility.
Purpose: Avoid master panic on old journal logs and support time updates.
curvine-common/src/utils/proto_utils.rs
Map SetAttrOpts <-> Proto including atime/mtime.
Purpose: Ensure correct serialization/deserialization for time changes.
curvine-server/src/master/meta/inode/inode_view.rs
Apply atime/mtime in InodeView::set_attr for both files and dirs.
Purpose: Persist time updates in metadata; fix utime01.
curvine-fuse/src/fs/state/node_map.rs
Rename: preserve original inode ID by updating parent/name mappings instead of deleting and recreating.
Proactively remove existing destination entry from cache before rename (replace-if-exists semantics).
Purpose: Fix symlink rename01 lstat failures and inode mismatch; avoid EEXIST cache race.
curvine-fuse/src/lib.rs
Export/enable flags and constants used by FUSE options; minor additions for feature toggles.
Purpose: Align FUSE behavior/config exposure.
curvine-fuse/src/fs/curvine_file_system.rs
Permissions: centralize directory search (execute) enforcement with DirectoryAction, add root bypass, and fix access() parent traversal checks.
set_attr: correctly parse valid bits; convert atime/mtime between sec(ms); re-fetch status after backend set_attr to avoid stale uid/gid/mode.
status_to_attr: correct atime/mtime mapping from backend millis.
xattr: implement get_xattr/list_xattr/remove_xattr with silent ENODATA for capability/SELinux/ACLs to reduce noise.
mkdir/create: apply requested mode post-creation (mask file-type bits).
open/open_dir/read_dir_plus: enforce directory execute permissions consistently; add explicit file permission checks on open.
lookup/access: enforce parent directory search (skip for inode 0/root); add rich debug logging.
readlink/symlink: return stored target and improve validations; ln -s behavior without force.
rename: emulate replace-if-exists for files/symlinks by deleting destination if exists and log outcomes; update node map afterwards.
fsync: add best-effort flush for mkfs/loop use-cases.
Purpose: Fix access01, utime01, rename01; improve correctness and observability.
Impact
Fixes: access01, utime01, rename01 failures in LTP.
Stabilizes master after schema change via serde defaulting.
Ensures time attributes are persisted and reflected to kernel.
Aligns rename semantics with POSIX and preserves inode IDs to avoid stale lookups.
Reduces noisy logs for unsupported security xattrs.
Adds fsync handling to support tools expecting durability hints.
Note
Random write (write-at) remains unsupported by design; mkfs.ext2 on loop-backed files may still fail due to non-sequential write constraints. This PR does not implement random-write semantics.

@lzjqsdd lzjqsdd changed the title Fix FUSE directory traversal permission enforcement and setattr mode handling fix: FUSE directory traversal permission enforcement and setattr mode handling Aug 20, 2025
@lzjqsdd lzjqsdd changed the title fix: FUSE directory traversal permission enforcement and setattr mode handling fix: fuse directory traversal permission enforcement and setattr mode handling Aug 20, 2025
@lzjqsdd lzjqsdd merged commit e9edcba into CurvineIO:main Aug 20, 2025
3 of 6 checks passed
@jlon jlon deleted the setattr branch September 2, 2025 08:29
szbr9486 pushed a commit that referenced this pull request Sep 11, 2025
… handling (#213)

* Fix FUSE directory traversal permission enforcement and setattr mode handling

* Fix LTP permission, time, symlink-rename correctness and improve FUSE attr/xattr behavior
@lzjqsdd lzjqsdd added the bug Something isn't working label Sep 22, 2025
Coderlxl pushed a commit to Coderlxl/curvine that referenced this pull request Dec 25, 2025
… handling (CurvineIO#213)

* Fix FUSE directory traversal permission enforcement and setattr mode handling

* Fix LTP permission, time, symlink-rename correctness and improve FUSE attr/xattr behavior
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants