Skip to content

F-5.12: Near Inode Exhaustion (DoS Risk)

Classification

  • Severity: Medium (Denial of Service)
  • CVSS Vector: Network / Low Complexity / Low Privileges Required
  • Affected Versions: NFSv2, NFSv3
  • RFC Reference: RFC 1813 S3.3.18 (FSSTAT total_files, free_files, avail_files)
  • Prerequisite: Valid file handle for the export root; write access for exploitation

Summary

The FSSTAT procedure (RFC 1813 S3.3.18) reports total, free, and available file slots (inodes) on the filesystem backing an export. When the number of available inodes drops below a critical threshold, an attacker with write access can exhaust the remaining capacity by creating many small files. This denies file creation for all users and processes on that filesystem, including services that write temporary files, logs, or spool data. The threshold is operationally significant because many applications fail catastrophically when they cannot create files -- databases crash, mail delivery fails, and system daemons stall.

Technical detail

FSSTAT fields

RFC 1813 S3.3.18 defines three file-slot counters:

Field Meaning
total_files Total inode capacity of the filesystem
free_files Free inodes (includes reserved slots)
avail_files Inodes available for unprivileged creation

The distinction between free_files and avail_files parallels the free_bytes/avail_bytes split: avail_files excludes reserved inodes that only root can use. On ext4, this reservation is typically 0, so the values are equal. On other filesystems, the gap may be meaningful.

Exhaustion attack

1. Call FSSTAT on the export root -> avail_files = 847
2. Estimate: 847 empty files needed to exhaust the filesystem
3. For each remaining slot:
     CREATE(dir, "junk_NNNN", mode=0644)  # 1 inode per file
4. After ~847 files: CREATE returns NFS3ERR_NOSPC
5. All users on the filesystem can no longer create files

Each empty file consumes exactly one inode regardless of file size. An attacker needs no disk space -- zero-length files suffice.

Impact amplification

Inode exhaustion is often worse than disk-space exhaustion because:

  • Invisible to df: Standard df shows disk space, not inode usage. Administrators may not notice until services fail.
  • Hard to diagnose: Applications report generic "No space left on device" (ENOSPC), even though disk-space df shows free space.
  • Cascading failures: Systems that rely on creating temporary files (e.g., /tmp on the same filesystem, lock files, PID files) stop functioning.
  • Cleanup complexity: Finding and removing the attacker's files requires find by owner/ctime, which itself may fail if it needs to create temporary files.

Filesystem-specific behaviors

Filesystem Inode Behavior Notes
ext4 Fixed at mkfs time Cannot add inodes without resizing
XFS Dynamic allocation Inodes allocated on demand up to maxpct (default 25% of space)
btrfs No fixed limit total_files = 0 -- FSSTAT reports unlimited; check not applicable
ZFS Dynamic Inodes limited by available space and recordsize

Exploitation

Automated (nfswolf)

# The analyzer checks FSSTAT during analysis:
nfswolf analyze target:/export

# Output when avail_files < 1000:
# [MEDIUM] F-5.12: Near inode exhaustion (DoS risk)
#   Evidence: total_files=524288, free_files=912, avail_files=847, usage=99%

Manual

# Check inode availability via showmount + rpcinfo:
showmount -e target
# Then mount and check:
mount -t nfs target:/export /mnt
df -i /mnt
# Filesystem     Inodes  IUsed   IFree IUse%
# target:/export 524288  523441  847   99%

Impact

  • Denial of service: File creation blocked for all users on the affected filesystem
  • Service disruption: Applications that create temporary files, log entries, or lock files will fail
  • Difficult recovery: Inode exhaustion may prevent administrators from creating the files needed to diagnose the problem
  • Exploitation is trivial: An attacker with write access needs only a loop creating empty files

Detection (nfswolf)

The analyzer calls FSSTAT on each export root handle and checks the avail_files field. If fewer than 1000 inodes remain, the finding fires at Medium severity. The evidence includes total_files, free_files, avail_files, the computed usage percentage, and byte-level capacity for context.

Remediation

  1. Monitor inode usage -- add inode monitoring to infrastructure alerting alongside disk-space monitoring:

    df -i /export
    

  2. Expand filesystem capacity -- resize the filesystem or migrate to one with dynamic inode allocation (XFS, ZFS)

  3. Restrict write access -- ensure NFS exports use root_squash and limit write access to authorized UIDs via export options:

    /export  client(rw,root_squash)
    

  4. Set quotas -- use filesystem quotas to limit the number of files per UID, preventing a single compromised account from exhausting all inodes

  5. Separate filesystems -- keep NFS exports on dedicated filesystems so inode exhaustion on one export does not affect system services