Ascii85Encode() assembled the 32-bit tuple with
word = (uint32_t)((((raw[0] << 8) + raw[1]) << 16) +
(raw[2] << 8) + raw[3]);
The sub-expression ((raw[0] << 8) + raw[1]) has type int (the unsigned
char operands are promoted to int). When raw[0] >= 128 its value is
>= 0x8000, so the following "<< 16" shifts a set bit into and past the
sign bit and the result is not representable in int, which is undefined
behaviour.
The bytes passed to Ascii85Encode() are attacker controlled: among them
are the ColorMap values emitted by PS_Lvl2colorspace() via
Ascii85Put() -> Ascii85Encode() when a palette TIFF is converted with
"tiff2ps -a -2". UBSan reports, for a palette image whose colormap
contains a byte >= 128:
tools/tiff2ps.c:3474:46: runtime error: left shift of 36922 by 16
places cannot be represented in type 'int'
#0 Ascii85Encode tiff2ps.c:3474
#1 Ascii85Put tiff2ps.c:3512
#2 PS_Lvl2colorspace tiff2ps.c:2173
Compute the word using unsigned (uint32_t) shifts, matching the encoder
already used in Ascii85EncodeBlock(). The numeric result is unchanged on
two's-complement targets, so the generated PostScript is byte-identical.
---
diff --git a/tools/tiff2ps.c b/tools/tiff2ps.c
index be2f5a0..514f901 100644
--- a/tools/tiff2ps.c
+++ b/tools/tiff2ps.c
@@ -3470,8 +3470,8 @@ static char *Ascii85Encode(unsigned char *raw)
static char encoded[6];
uint32_t word;
- word =
- (uint32_t)((((raw[0] << 8) + raw[1]) << 16) + (raw[2] << 8) + raw[3]);
+ word = ((uint32_t)raw[0] << 24) | ((uint32_t)raw[1] << 16) |
+ ((uint32_t)raw[2] << 8) | (uint32_t)raw[3];
if (word != 0L)
{
uint32_t q;
--
2.50.1 (Apple Git-155)
_______________________________________________
Tiff mailing list
[email protected]
https://lists.osgeo.org/mailman/listinfo/tiff