adamhathcock/sharpcompress

Hang while opening BZip2

fuzzah opened this issue · 4 comments

In continuation of #841.
The following code results in an infinite loop in SharpCompress:

using System.IO;
using SharpCompress.Readers;
Stream stream = new MemoryStream(new byte[] {0x42, 0x5a, 0x68, 0x34, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0x35});
ReaderFactory.Open(stream);

The stack trace (created with the dotnet stack tool):

System.Private.CoreLib!System.IO.Stream.ReadByte()
SharpCompress!SharpCompress.Compressors.BZip2.CBZip2InputStream.BsR(int32)
SharpCompress!SharpCompress.Compressors.BZip2.CBZip2InputStream.RecvDecodingTables()
SharpCompress!SharpCompress.Compressors.BZip2.CBZip2InputStream.GetAndMoveToFrontDecode()
SharpCompress!SharpCompress.Compressors.BZip2.CBZip2InputStream.InitBlock()
SharpCompress!SharpCompress.Compressors.BZip2.CBZip2InputStream..ctor(class System.IO.Stream,bool)
SharpCompress!SharpCompress.Compressors.BZip2.BZip2Stream..ctor(class System.IO.Stream,value class SharpCompress.Compressors.CompressionMode,bool)
SharpCompress!SharpCompress.Factories.TarFactory.TryOpenReader(class SharpCompress.IO.RewindableStream,class SharpCompress.Readers.ReaderOptions,class SharpCompress.Readers.IReader&)
SharpCompress!SharpCompress.Readers.ReaderFactory.Open(class System.IO.Stream,class SharpCompress.Readers.ReaderOptions)
app!Program.<Main>$(class System.String[])

This byte sequence written to a file gets detected as "bzip2 compressed data" by the file tool, but bzip2 fails to read it with the error message "bzip2: Compressed file ends unexpectedly".

Found by Linux Verification Center (linuxtesting.org) with AFL++ and SharpFuzz.
Reporter: Valery Korolyov (v.korolyov@gardatech.ru)
Organization: Garda Technologies (info@gardatech.ru)

Stepping through, the code correctly identifies the EOF here:

if (thech == '\uffff')
{
CompressedStreamEOF();
}

and then proceeds to... do nothing?
private static void Cadvise()
{
//System.out.Println("CRC Error");
//throw new CCoruptionError();
}
private static void BadBGLengths() => Cadvise();
private static void BitStreamEOF() => Cadvise();
private static void CompressedStreamEOF() => Cadvise();

Perhaps the fix is just to make this function actually throw an exception instead of silently passing?

Seems like I should have ported the exception.

So as #850 is merged, this should be closed?

Thanks!