exfat icon indicating copy to clipboard operation
exfat copied to clipboard

Information disclosure in fuse-exfat

Open msuhanov opened this issue 2 years ago • 2 comments

Affected versions: 1.3.0 and latest code (11e4f03).

Details: In the exFAT file system, each file has a stream extension with the following fields defined (among others): DataLength and ValidDataLength (https://docs.microsoft.com/en-us/windows/win32/fileio/exfat-specification#76-stream-extension-directory-entry). The former refers to the file size, the latter refers to the highest file offset written.

According to the official exFAT specification, bytes after ValidDataLength are undefined and "[i]mplementations shall return zeroes for read operations beyond the valid data length" (https://docs.microsoft.com/en-us/windows/win32/fileio/exfat-specification#765-validdatalength-field).

In Windows, it’s possible to allocate a file with DataLength larger than ValidDataLength. One needs to call the NtSetInformationFile function using the FileEndOfFileInformation argument (https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/ns-ntddk-_file_end_of_file_information) to set DataLength larger than ValidDataLength. This call will allocate additional clusters for the file as needed but will not zero them out.

When the file handle is closed, these newly allocated clusters will be zeroed out as needed (so data between ValidDataLength and DataLength will consist of null bytes only), but while the handle is open, these clusters contain remnant (deleted) data. If the volume is detached from the system without closing the handle, the following state is observed: a. the file has ValidDataLength smaller than DataLength; b. clusters beyond ValidDataLength (up to DataLength) contain remnant (deleted) data.

(It’s possible that more than one way to allocate clusters without zeroing them out exist.)

Attaching the same volume to the Windows system again will not wipe (zero out) clusters beyond ValidDataLength. So, there will be a file with some of its clusters containing remnant (deleted) data.

When reading such a file in WIndows, null bytes are returned for offsets beyond ValidDataLength. This behavior is expected and it matches the specification. No remnant (deleted) data is exposed as file data.

When reading such a file using fuse-exfat, remnant data is returned to the caller for offsets beyond ValidDataLength. This behavior violates the specification.

I am attaching two screenshots and a gzipped file system image to demonstrate this behavior (this image was used to produce both screenshots). The image was filled with the "PTRN" byte pattern before the format operation, so returning these bytes to the caller reading the "/test.bin" file is actually exposing remnant data (which existed before the format).

If a particular setup allows an unprivileged user to read from a mounted exFAT volume, exposing remnant (deleted) data to this user is a vulnerability (for example, a similar vulnerability is described here: https://access.redhat.com/security/cve/cve-2021-4155).

Solution: respect the ValidDataLength field when reading a file, return null bytes for offsets beyond this value.


Report date (https://github.com/relan/exfat/issues/180): 2022-01-27.

Attached files: exfat_allocation.raw.gz exfat_win exfat_freebsd

msuhanov avatar May 01 '22 23:05 msuhanov

The fix (needs a bit of polishing): https://github.com/relan/exfat/tree/validsize

relan avatar May 02 '22 09:05 relan

Why not open a PR with the fix?

ajakk avatar May 02 '22 18:05 ajakk

Is there any progress on this issue?

carnil avatar Dec 29 '22 09:12 carnil

Is there any progress on this issue?

Yep, I'm preparing to merge https://github.com/relan/exfat/tree/validsize that closes this risk.

relan avatar Dec 29 '22 10:12 relan

Fixed in v1.4.0.

relan avatar Mar 02 '23 20:03 relan