Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Information disclosure in fuse-exfat #185

Closed
msuhanov opened this issue May 1, 2022 · 5 comments
Closed

Information disclosure in fuse-exfat #185

msuhanov opened this issue May 1, 2022 · 5 comments
Milestone

Comments

@msuhanov
Copy link

msuhanov commented May 1, 2022

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 (#180): 2022-01-27.

Attached files:
exfat_allocation.raw.gz
exfat_win
exfat_freebsd

@relan
Copy link
Owner

relan commented May 2, 2022

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

@ajakk
Copy link

ajakk commented May 2, 2022

Why not open a PR with the fix?

@carnil
Copy link

carnil commented Dec 29, 2022

Is there any progress on this issue?

@relan relan added this to the 1.4.0 milestone Dec 29, 2022
@relan
Copy link
Owner

relan commented Dec 29, 2022

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
Copy link
Owner

relan commented Mar 2, 2023

Fixed in v1.4.0.

@relan relan closed this as completed Mar 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants