Skip to content

File accessAnti-forensics

XFS Forensics: Inode Timestamps, crtime and Deleted Files

XFS on RHEL-family Linux: v5 inode timestamps with crtime, bigtime, xfs_db inspection, the metadata log, and what remains after a file is deleted.

Location
/dev/<xfs-volume>
Proves
When files were created, modified, changed and read on an XFS volume, and sometimes what deleted files contained
Timestamps
Seconds plus nanoseconds since the Unix epoch, UTC; crtime on v5 inodes; bigtime counter on newer filesystems
Access
Any user for stat on accessible files; root or raw device access for xfs_db
Retention
Timestamps until overwritten; deleted inode extents and data blocks until reused
Collection
dd, ewfacquire, UAC, xfs_metadump

What it is

XFS is the default filesystem for RHEL 7 and later, and therefore for Rocky Linux, AlmaLinux, Oracle Linux and many cloud images. It is a journaling filesystem split into allocation groups, each with its own inodes and free-space trees. For an investigator it offers the same core timestamps as ext4, a creation time on modern volumes, and deletion behaviour that leaves more residue than ext4 does.

Where it lives

StructureWhereNotes
SuperblockStart of each allocation group (primary at offset 0)Version, features (crc, bigtime), UUID
InodesInode chunks inside allocation groupsVersion 3 inodes on v5 filesystems carry crtime
Directory entriesShort-form in the inode, or block/leaf/node directory blocksDeleted entries may keep part of the inode number
Log (journal)Internal log by defaultMetadata-only journaling

Check the format on a live system with xfs_info / (look for crc=1 meaning v5 and bigtime=1), or read-only on an image with xfs_db -r -c 'sb 0' -c 'print' <device>. mkfs.xfs has created v5 filesystems by default since RHEL 7.3, so RHEL 8 and later systems are normally v5; filesystems created on RHEL 7.0 to 7.2 are v4 without crtime.

What it proves

  • crtime (v3.crtime): inode creation on this filesystem, available on v5 only.
  • mtime, ctime, atime: content change, inode change and last read, with the same meaning and forgery caveats as on ext4 (touch can set mtime and atime, and moves ctime to the current time).
  • Deleted files: the directory entry often keeps the lower bytes of the inode number, and the deleted inode keeps its extent records, so file content can sometimes be located and recovered.
  • Not proven: the acting user or process; pair with auditd, shell history and logs.

Key fields

Inode field (xfs_db names)Meaning
core.atime, core.mtime, core.ctimeAccess, modify, change times (seconds and nanoseconds)
v3.crtimeCreation time (v5 filesystems)
core.mode, core.uid, core.gidType and permissions, owner
core.size, core.nextentsSize and extent count (both zeroed on deletion)
core.nlinkv2Link count
u3.bmxExtent list: file offset, start block, block count

Timestamps

All times are UTC. Classic XFS stores seconds and nanoseconds for each timestamp, limited to 2038. The bigtime feature (kernel 5.10 and later, enabled by default by mkfs.xfs from xfsprogs 5.15) stores a 64-bit nanosecond counter that extends the range to the year 2486; xfs_db decodes both. stat reports Birth on v5 volumes when coreutils, glibc and the kernel support statx.

stat --format='%n birth=%w modify=%y change=%z access=%x' /etc/shadow
ls -i /etc/shadow                                   # inode number
xfs_db -r -c 'inode 12345' -c 'print core.mtime core.ctime v3.crtime' /dev/mapper/rhel-root

The same relatime default as other Linux filesystems applies to atime.

Retention

  • Timestamps are overwritten by normal activity; image early.
  • On deletion XFS zeroes the inode's size and extent count, but the extent records themselves stay in the inode until it is reused, and data blocks stay in free space until reallocated.
  • The internal log holds recent metadata changes only briefly; it is circular.
  • Discard/TRIM on SSDs and thin-provisioned cloud volumes can remove freed data quickly.

Collection

Image the block device (or logical volume, since RHEL installs usually use LVM) read-only and hash it. For large volumes where only metadata is needed, xfs_metadump creates a metadata-only copy; it obfuscates file names by default, so pass -o to keep real names for forensic use. For live triage, UAC bodyfile output and Velociraptor timelines record paths and timestamps.

Parsing

  • xfs_db -r (read-only) to print superblocks, inodes, directories and extent maps.
  • libfsxfs (libyal) provides fsxfsinfo for listing and inspecting XFS v4/v5 volumes, and gives dfVFS and Plaso their XFS support; the libfsxfs project itself is marked experimental.
  • The Sleuth Kit shipped experimental XFS support in 4.13.0 and removed it in 4.14.0, so do not rely on fls/istat for XFS with current releases.
  • Deleted-file recovery is largely manual: locate the deleted directory entry and inode with xfs_db, read the remaining extent records, and extract blocks with dd, as demonstrated in Hal Pomeranz's XFS recovery write-up.

Investigator tips

  • Check crc=1 before promising a creation time: v4 filesystems have no crtime.
  • On LVM, image the logical volume or the whole physical disk, and record the mapping (lvs, pvs) so offsets can be reproduced.
  • Package-installed files keep the package's mtime; use crtime and package manager logs for install time.
  • ctime newer than all other times with a suspiciously round mtime suggests timestomping, exactly as on ext4.
  • Deleted staging files in /tmp and /var/tmp are often still recoverable on XFS because extents survive in the inode.
  • Always mount evidence read-only with -o ro,norecovery so the log is not replayed.

See also