Skip to content

F-2.4: BTRFS Subvolume Handle Construction

Classification

  • Severity: High
  • CVSS Vector: Network / Low Complexity / No Auth Required
  • Affected Versions: NFSv3 on Linux with BTRFS
  • RFC Reference: RFC 1094 ยง2.3.3 (handles are server-specific)
  • Prerequisite: BTRFS filesystem, export on a subvolume, subtree_check disabled

Summary

BTRFS uses extended file handle types (fileid_type 0x4d-0x4f) that encode subvolume IDs. An attacker who can access any export on a BTRFS filesystem can construct file handles targeting other subvolumes โ€” including snapshots โ€” by manipulating the subvolume ID field. This enables access to data in subvolumes that were never exported, including historical snapshots that may contain older versions of sensitive files.

Technical detail

BTRFS handle structure

BTRFS file handles include a fileid_type in the range 0x4d-0x4f: - 0x4d: Regular file/directory - 0x4e: Directory with parent info - 0x4f: Root of a subvolume

The handle includes a subvolume ID field. BTRFS subvolume IDs start at 256 and increment:

btrfs subvolume list /
  ID 256 gen 100 top level 5 path @
  ID 257 gen 99  top level 5 path @home
  ID 258 gen 50  top level 5 path @snapshots/daily-2024-01-01

Cross-subvolume access

By constructing a handle with a different subvolume ID but the same filesystem UUID, the attacker accesses a different subvolume:

# From a handle on subvolume 256 (@)
# Change subvolume ID to 258 (@snapshots/daily-2024-01-01)
handle = construct_btrfs_handle(
    fileid_type=0x4f,
    subvol_id=258,
    inode=256  # root inode of target subvolume
)
# Now browse yesterday's snapshot
entries = nfs_readdirplus(target, handle)

Snapshot data exposure

Snapshots may contain: - Previous versions of /etc/shadow (before password changes) - Deleted sensitive files (still present in snapshot) - Configuration files from before security hardening - Database files from before data cleanup

Impact

  • Access to ALL subvolumes and snapshots on the BTRFS filesystem
  • Historical data exposure from snapshots
  • Bypass export boundary even when each subvolume was intended to be isolated
  • Potentially more damaging than F-2.1 โ€” accesses time-historical data

Detection (nfswolf)

The scanner should: 1. Detect BTRFS via fileid_type 0x4d-0x4f in exported handles 2. Enumerate subvolume IDs by probing handles with IDs 256-512 3. Report accessible subvolumes beyond the exported one

Remediation

  1. Enable subtree_check when using BTRFS subvolumes as exports
  2. Export each subvolume on a separate filesystem (not just separate subvolume)
  3. Restrict snapshots to a separate BTRFS pool not shared with NFS exports
  4. Monitor snapshot access via NFS traffic analysis