Skip to content

Images with Polyglot attacks cause Access Violation Exception #922

Description

@sport-monkey

Prerequisites

  • I have written a descriptive issue title
  • I have verified that I am running the latest version of ImageSharp
  • I have verified if the problem exist in both DEBUG and RELEASE mode
  • I have searched open and closed issues to ensure it has not already been reported

Description

When attempting to load a JPEG with a polyglot attack Image.Load throws an AccessViolationException. I've tried uploading the images directly but they appear to be cleaned - Images can be found here as well as some further examples on the previous link

This also stops the image reading after a given point in latest NuGet package (1.0.0-beta0006).
You also get some really interesting side effects by evaluating frame.GetPixelSpan().Slice(1390000, 5) and $"{frame.GetPixelSpan()[1390000]" whilst in Debug

Steps to Reproduce

Call Image.Load on attached files

System Configuration

  • ImageSharp version: SixLabors.ImageSharp.1.0.0-dev002709
  • Other ImageSharp packages and versions: SixLabors.Core.1.0.0-dev000108
  • Environment (Operating system, version and so on): OS X 10,13.2
  • .NET Framework version: core 3 preview 5
  • Additional information:

Activity

  1. JimBobSquarePants commented on Jun 3, 2019

    @JimBobSquarePants
    Member

    Thanks for reporting this @sport-monkey we really appreciate it!

    I'll take a look at this myself as I've already done the fuzz fixes for jpeg so I have a hunch where the issue will be

  2. JimBobSquarePants commented on Jun 3, 2019

    @JimBobSquarePants
    Member

    I'm not seeing this with 1.0.0-dev002715 on my Windows machine using NET Core 2.1 or Net Framework 4.6.2, 4.7.2

  3. sport-monkey commented on Jun 3, 2019

    @sport-monkey
    Author

    I've added the source code I use to run this, if I change the proj to target 2.1 it prints (1), if I use the 3.0 we get. (Net Core 2.1 on Win 10 x64)

    C:\Users\User\ImageSharp>dotnet run
    1
    System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
       at SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.HuffmanScanDecoder.DecodeBlockBaseline(SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.JpegComponent, SixLabors.ImageSharp.Formats.Jpeg.Components.Block8x8 ByRef, SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.HuffmanTable ByRef, SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.HuffmanTable ByRef)
       at SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.HuffmanScanDecoder.ParseBaselineDataInterleaved()
       at SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.HuffmanScanDecoder.ParseEntropyCodedData()
       at SixLabors.ImageSharp.Formats.Jpeg.JpegDecoderCore.ProcessStartOfScanMarker()
       at SixLabors.ImageSharp.Formats.Jpeg.JpegDecoderCore.ParseStream(System.IO.Stream, Boolean)
       at SixLabors.ImageSharp.Formats.Jpeg.JpegDecoderCore.Decode[[SixLabors.ImageSharp.PixelFormats.Rgba32, SixLabors.ImageSharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]](System.IO.Stream)
       at SixLabors.ImageSharp.Formats.Jpeg.JpegDecoder.Decode[[SixLabors.ImageSharp.PixelFormats.Rgba32, SixLabors.ImageSharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]](SixLabors.ImageSharp.Configuration, System.IO.Stream)
       at SixLabors.ImageSharp.Image.Decode(System.IO.Stream, SixLabors.ImageSharp.Configuration)
       at SixLabors.ImageSharp.Image.WithSeekableStream[[System.ValueTuple`2[[System.__Canon, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](SixLabors.ImageSharp.Configuration, System.IO.Stream, System.Func`2<System.IO.Stream,System.ValueTuple`2<System.__Canon,System.__Canon>>)
       at SixLabors.ImageSharp.Image.Load(SixLabors.ImageSharp.Configuration, System.IO.Stream, SixLabors.ImageSharp.Formats.IImageFormat ByRef)
       at SixLabors.ImageSharp.Image.Load(SixLabors.ImageSharp.Configuration, System.String, SixLabors.ImageSharp.Formats.IImageFormat ByRef)
       at SixLabors.ImageSharp.Image.Load(System.String)
       at ImageSharp.Program.Main(System.String[])
    
  4. JimBobSquarePants commented on Jun 3, 2019

    @JimBobSquarePants
    Member

    Ok. This looks like something we should be raising upstream on the CoreFX repo. Would you please do that and we’ll see what we can all work out together. Thanks!

  5. benaadams commented on Jun 3, 2019

    @benaadams

    Can the value in r cause the i read of zigzag to go out of bounds (as the indexer is not bounds checked)?

    i += r;
    s = buffer.Receive(s);
    Unsafe.Add(ref blockDataRef, zigzag[i++]) = (short)s;

  6. JimBobSquarePants commented on Jun 4, 2019

    @JimBobSquarePants
    Member

    @benaadams Looks like you might be onto something here.

    Running the following code. I can throw an IndexOutOfRangeException when h is 49.

    void Main()
    {
       byte[] zigzag =
       {
    		0,
    		1, 8,
    		16, 9, 2,
    		3, 10, 17, 24,
    		32, 25, 18, 11, 4,
    		5, 12, 19, 26, 33, 40,
    		48, 41, 34, 27, 20, 13, 6,
    		7, 14, 21, 28, 35, 42, 49, 56,
    		57, 50, 43, 36, 29, 22, 15,
    		23, 30, 37, 44, 51, 58,
    		59, 52, 45, 38, 31,
    		39, 46, 53, 60,
    		61, 54, 47,
    		55, 62,
    		63
    	};
    
    	var block = new short[64];
    
    	// s is read from a table of bytes 
    	for (int h = 0; h < 255; h++)
    	{
    		for (int i = 1; i < 64; i++)
    		{
    			int s = h;
    			int r = s >> 4;
    			s &= 15;
    
    			if (s != 0)
    			{
    				i += r;
    				// Ignore Extend
    				block[zigzag[i++]] = (short)s;
    			}
    			else
    			{
    				if (r == 0)
    				{
    					break;
    				}
    
    				i += 16;
    			}
    		}
    	}
    }

    However, look what libjpeg-turbo do. They pad out the zigzag array to handle such corrupted data.

    libjpeg zigzag data

    If I use their extended table then no exception is thrown.

  7. added a commit that references this issue on Jun 4, 2019
    dcbcf3c
  8. antonfirsov commented on Jun 4, 2019

    @antonfirsov
    Member

    @sport-monkey is the issue reproducible with this smaller image as well?

  9. sport-monkey commented on Jun 4, 2019

    @sport-monkey
    Author

    @sport-monkey is the issue reproducible with this smaller image as well?

    @antonfirsov I've just tried, it's not reproducible with that image.

  10. added a commit that references this issue on Jun 4, 2019
    8107587
  11. added a commit that references this issue on Aug 25, 2019
    9773e61
  12. added a commit that references this issue on Nov 11, 2019
    965e55e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions