Bug 1831404

Summary: Truncated LZNT1 compressed file seems to leak data from run-time buffer into file content data
Product: [Fedora] Fedora Reporter: Joachim Metz <joachim.metz>
Component: ntfs-3gAssignee: Tom "spot" Callaway <spotrh>
Status: CLOSED EOL QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 32CC: jean-pierre.andre
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: ---
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2021-05-25 16:08:46 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
data in compressed data run
none
Patch to avoid disclosing foreign data from a bad compressed sequence
none
Patch to avoid disclosing foreign data from a bad compressed sequence none

Description Joachim Metz 2020-05-05 05:48:08 UTC
Description of problem:

While testing NTFS3g I came across the following case (unclear if this is a corruption scenario or data format edge case)

....
reading data run: 0.
data run:
00000000: 31 08 48 d8 01                                     1.H..

value sizes                               : 1, 3
number of cluster blocks                  : 8 (size: 32768)
cluster block number                      : 120904 (120904) (offset: 0x1d848000)

reading data run: 1.
data run:
00000000: 01 08                                              ..

value sizes                               : 1, 0
number of cluster blocks                  : 8 (size: 32768)
cluster block number                      : 0 (0) (offset: 0x00000000)
        Is sparse
....

Contains the following data:

....
1d848000  bd b7 50 44 46 50 00 01  00 01 00 40 e0 00 07 0b  |..PDFP.....@....|
...
1d84c000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
1d84fff0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
....

This relates to a LZNT1 compressed block that appears to be truncated at offset
16384 (0x00004000).

when reading the file ntfs3g it decompressed the data upto offset 0x9000, which is expected based on the truncation.

But then ntfs3g starts repeating 
00009000  4b 42 32 39 33 34 30 31  38 7e 33 31 62 66 33 38  |KB2934018~31bf38|
00019000  4b 42 32 39 33 34 30 31  38 7e 33 31 62 66 33 38  |KB2934018~31bf38|
00029000  4b 42 32 39 33 34 30 31  38 7e 33 31 62 66 33 38  |KB2934018~31bf38|
...


This pattern changes when the file system is newly mounted.


while another NTFS implementation shows:

00009000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
005c24e0


Which makes me assume that this edge case is leaking data from currently in the buffer into file content data 


Version-Release number of selected component (if applicable):

dnf info ntfs-3g

Installed Packages
Name         : ntfs-3g
Epoch        : 2
Version      : 2017.3.23
Release      : 13.fc32
Architecture : x86_64
Size         : 671 k
Source       : ntfs-3g-2017.3.23-13.fc32.src.rpm
Repository   : @System
From repo    : fedora
Summary      : Linux NTFS userspace driver
URL          : http://www.ntfs-3g.org/
License      : GPLv2+
Description  : NTFS-3G is a stable, open source, GPL licensed, POSIX, read/write NTFS
             : driver for Linux and many other operating systems. It provides safe
             : handling of the Windows XP, Windows Server 2003, Windows 2000, Windows
             : Vista, Windows Server 2008 and Windows 7 NTFS file systems. NTFS-3G can
             : create, remove, rename, move files, directories, hard links, and streams;
             : it can read and write normal and transparently compressed files, including
             : streams and sparse files; it can handle special files like symbolic links,
             : devices, and FIFOs, ACL, extended attributes; moreover it provides full
             : file access right and ownership support.


How reproducible:

It is a bit flaky to observe, likely because internal buffers that leak into the file content are initialized with 0-byte values. So listing directories and other files before reading the truncated file might be necessary.


Steps to Reproduce:
1. Create NTFS with LZNT1 compressed file
2. Manually truncate the first compressed block e.g. at offset 0x4000
3. So various file system activities such a list directories
4. Read the file with ntfs3g

Actual results:

Decompressed file content followed by, what looks like, data leaking from internal buffer

Expected results:

Decompressed file content followed by 0-byte values

Additional info:

N/A

Comment 1 Jean-Pierre André 2020-05-05 09:21:32 UTC
Would you please be more explicit about how you truncate the data stream ? In particular are you forcing inconsistencies between the sizes (allocated, initialized, compressed) and the actual cluster allocations ?

Comment 2 Joachim Metz 2020-05-05 10:16:13 UTC
> Would you please be more explicit about how you truncate the data stream ? 

So I'm not deliberately truncating the data of the cluster block in my test data (I'm not fuzzing, think more in lines of a corrupted file system)

The first 0x4000 bytes are filled with LZNT1 compressed data after that the compressed data run is filled with 0-byte values

Which would look like something like:

....
1d848000  bd b7 50 44 46 50 00 01  00 01 00 40 e0 00 07 0b  |..PDFP.....@....|
...
1d84c000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
1d84fff0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
....


> In particular are you forcing inconsistencies between the sizes (allocated, initialized, compressed) and the actual cluster allocations ?

Nope in my test data the other file system metadata checks out, but part of the actual LZNT1 compressed data seems to be filled with 0-byte values.

Comment 3 Joachim Metz 2020-05-05 10:52:39 UTC
Created attachment 1685164 [details]
data in compressed data run

Comment 4 Joachim Metz 2020-05-05 10:56:03 UTC
I've attached the data in the 32k data run, hope that helps to reproduce the issue.

One additional factor here could be that the "truncated" LZNT1 data does NOT trigger a decompression error.

Whereas other files on in the same file system do, e.g. "Value too large for defined data type"

Comment 5 Jean-Pierre André 2020-05-05 16:04:56 UTC
By zeroing a part of the compressed stream, you replaced a compressed sequence by an uncompressed sequence of zeroes. Now, uncompressing the uncompressed sequence yields fewer bytes than by uncompressing the original sequence, and only part of the uncompressed buffer is filled when the source data is exhausted, and unrelated data can be seen.

A simple fix is to zero the end of buffer in this case. I cannot throw an error, because this is a normal condition when reaching the end of file.

Comment 6 Jean-Pierre André 2020-05-05 16:09:46 UTC
Created attachment 1685278 [details]
Patch to avoid disclosing foreign data from a bad compressed sequence

Zero the end of decompression buffer when not filled by decompressing input data.

Comment 7 Jean-Pierre André 2020-05-05 16:15:55 UTC
Created attachment 1685296 [details]
Patch to avoid disclosing foreign data from a bad compressed sequence

Zero the end of decompression buffer when the input data does not lead to filling it.

Comment 8 Joachim Metz 2020-05-05 16:19:00 UTC
Thx, yes that makes sense to me. Other NTFS implementations appear to use a similar approach.

Comment 10 Fedora Program Management 2021-04-29 16:23:52 UTC
This message is a reminder that Fedora 32 is nearing its end of life.
Fedora will stop maintaining and issuing updates for Fedora 32 on 2021-05-25.
It is Fedora's policy to close all bug reports from releases that are no longer
maintained. At that time this bug will be closed as EOL if it remains open with a
Fedora 'version' of '32'.

Package Maintainer: If you wish for this bug to remain open because you
plan to fix it in a currently maintained version, simply change the 'version' 
to a later Fedora version.

Thank you for reporting this issue and we are sorry that we were not 
able to fix it before Fedora 32 is end of life. If you would still like 
to see this bug fixed and are able to reproduce it against a later version 
of Fedora, you are encouraged  change the 'version' to a later Fedora 
version prior this bug is closed as described in the policy above.

Although we aim to fix as many bugs as possible during every release's 
lifetime, sometimes those efforts are overtaken by events. Often a 
more recent Fedora release includes newer upstream software that fixes 
bugs or makes them obsolete.

Comment 11 Ben Cotton 2021-05-25 16:08:46 UTC
Fedora 32 changed to end-of-life (EOL) status on 2021-05-25. Fedora 32 is
no longer maintained, which means that it will not receive any further
security or bug fix updates. As a result we are closing this bug.

If you can reproduce this bug against a currently maintained version of
Fedora please feel free to reopen this bug against that version. If you
are unable to reopen this bug, please file a new report against the
current release. If you experience problems, please add a comment to this
bug.

Thank you for reporting this bug and we are sorry it could not be fixed.