libextractor

GNU libextractor
Log | Files | Refs | Submodules | README | LICENSE

commit 4e38725fdcfc7c9216ecf38765a4321488b6f60c
parent a09ab061a5690800d1a388802d33692d380e6cb6
Author: Christian Grothoff <christian@grothoff.org>
Date:   Wed, 29 Jul 2026 11:04:48 +0200

preserve data on-stack to protect against override from subsequent read

Diffstat:
Msrc/plugins/png_extractor.c | 41+++++++++++++++++++++++++----------------
1 file changed, 25 insertions(+), 16 deletions(-)

diff --git a/src/plugins/png_extractor.c b/src/plugins/png_extractor.c @@ -489,40 +489,49 @@ EXTRACTOR_png_extract_method (struct EXTRACTOR_ExtractContext *ec) ret = 0; while (0 == ret) { - if (sizeof (uint32_t) + 4 != + char chunk[sizeof (uint32_t) + 4]; + + if (sizeof (chunk) != ec->read (ec->cls, &data, - sizeof (uint32_t) + 4)) + sizeof (chunk))) break; - length = get_int_at (data); + /* The pointer read() returns addresses the shared memory window and + is only valid until the next read() or seek() slides it. Both the + ec->seek() below and the process*() calls do that, so take a copy + of the chunk header before any of them runs. */ + memcpy (chunk, + data, + sizeof (chunk)); + length = get_int_at (chunk); if (0 > (pos = ec->seek (ec->cls, 0, SEEK_CUR))) break; pos += ((int64_t) length) + 4; /* Chunk type, data, crc */ - if (0 == strncmp ((char*) data + sizeof (uint32_t), + if (0 == strncmp (&chunk[sizeof (uint32_t)], "IHDR", 4)) ret = processIHDR (ec, length); - if (0 == strncmp ((char*) data + sizeof (uint32_t), - "iTXt", - 4)) + else if (0 == strncmp (&chunk[sizeof (uint32_t)], + "iTXt", + 4)) ret = processiTXt (ec, length); - if (0 == strncmp ((char*) data + sizeof (uint32_t), - "tEXt", - 4)) + else if (0 == strncmp (&chunk[sizeof (uint32_t)], + "tEXt", + 4)) ret = processtEXt (ec, length); - if (0 == strncmp ((char*) data + sizeof (uint32_t), - "zTXt", - 4)) + else if (0 == strncmp (&chunk[sizeof (uint32_t)], + "zTXt", + 4)) ret = processzTXt (ec, length); - if (0 == strncmp ((char*) data + sizeof (uint32_t), - "tIME", - 4)) + else if (0 == strncmp (&chunk[sizeof (uint32_t)], + "tIME", + 4)) ret = processtIME (ec, length); if (ret != 0)