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¶
- Enable
subtree_checkwhen using BTRFS subvolumes as exports - Export each subvolume on a separate filesystem (not just separate subvolume)
- Restrict snapshots to a separate BTRFS pool not shared with NFS exports
- Monitor snapshot access via NFS traffic analysis