From 7cf036a471e5a170a8a0d9f3ca4d718bf31c4d18 Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Wed, 13 Jun 2012 18:31:09 +0900 Subject: [PATCH] windowscodecs: Check IFD structure when loading metadata. --- dlls/windowscodecs/metadatahandler.c | 33 ++++++++++++++++++++++++++++ include/wincodec.idl | 1 + 2 files changed, 34 insertions(+) diff --git a/dlls/windowscodecs/metadatahandler.c b/dlls/windowscodecs/metadatahandler.c index d2eb8b349c3..643313654f7 100644 --- a/dlls/windowscodecs/metadatahandler.c +++ b/dlls/windowscodecs/metadatahandler.c @@ -733,6 +733,39 @@ static HRESULT LoadIfdMetadata(IStream *input, const GUID *preferred_vendor, return hr; } + /* limit number of IFDs to 4096 to avoid infinite loop */ + for (i = 0; i < 4096; i++) + { + ULONG next_ifd_offset; + LARGE_INTEGER pos; + USHORT next_ifd_count; + + hr = IStream_Read(input, &next_ifd_offset, sizeof(next_ifd_offset), NULL); + if (FAILED(hr)) break; + + SWAP_ULONG(next_ifd_offset); + if (!next_ifd_offset) break; + + pos.QuadPart = next_ifd_offset; + hr = IStream_Seek(input, pos, SEEK_SET, NULL); + if (FAILED(hr)) break; + + hr = IStream_Read(input, &next_ifd_count, sizeof(next_ifd_count), NULL); + if (FAILED(hr)) break; + + SWAP_USHORT(next_ifd_count); + + pos.QuadPart = next_ifd_count * sizeof(*entry); + hr = IStream_Seek(input, pos, SEEK_CUR, NULL); + if (FAILED(hr)) break; + } + + if (FAILED(hr) || i == 4096) + { + HeapFree(GetProcessHeap(), 0, entry); + return WINCODEC_ERR_BADMETADATAHEADER; + } + result = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*result)); if (!result) { diff --git a/include/wincodec.idl b/include/wincodec.idl index c587ff47ea9..82f419c8652 100644 --- a/include/wincodec.idl +++ b/include/wincodec.idl @@ -206,6 +206,7 @@ cpp_quote("#define WINCODEC_ERR_CODECNOTHUMBNAIL 0x88982f44") cpp_quote("#define WINCODEC_ERR_PALETTEUNAVAILABLE 0x88982f45") cpp_quote("#define WINCODEC_ERR_COMPONENTNOTFOUND 0x88982f50") cpp_quote("#define WINCODEC_ERR_FRAMEMISSING 0x88982f62") +cpp_quote("#define WINCODEC_ERR_BADMETADATAHEADER 0x88982f63") cpp_quote("#define WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT 0x88982f80") cpp_quote("#define WINCODEC_ERR_UNSUPPORTEDOPERATION 0x88982f81") cpp_quote("#define WINCODEC_ERR_INSUFFICIENTBUFFER 0x88982f8c")