|
|
e4d7d2 |
Upstream patch for CVE-2012-4447. This also covers an out-of-bounds-read
|
|
|
e4d7d2 |
possibility in the same file, which wasn't given a separate CVE.
|
|
|
e4d7d2 |
|
|
|
e4d7d2 |
|
|
|
e4d7d2 |
diff -Naur tiff-3.9.4.orig/libtiff/tif_pixarlog.c tiff-3.9.4/libtiff/tif_pixarlog.c
|
|
|
e4d7d2 |
--- tiff-3.9.4.orig/libtiff/tif_pixarlog.c 2010-06-08 14:50:42.000000000 -0400
|
|
|
e4d7d2 |
+++ tiff-3.9.4/libtiff/tif_pixarlog.c 2012-12-10 15:50:14.421538317 -0500
|
|
|
e4d7d2 |
@@ -117,9 +117,9 @@
|
|
|
e4d7d2 |
if (n >= stride) {
|
|
|
e4d7d2 |
mask = CODE_MASK;
|
|
|
e4d7d2 |
if (stride == 3) {
|
|
|
e4d7d2 |
- t0 = ToLinearF[cr = wp[0]];
|
|
|
e4d7d2 |
- t1 = ToLinearF[cg = wp[1]];
|
|
|
e4d7d2 |
- t2 = ToLinearF[cb = wp[2]];
|
|
|
e4d7d2 |
+ t0 = ToLinearF[cr = (wp[0] & mask)];
|
|
|
e4d7d2 |
+ t1 = ToLinearF[cg = (wp[1] & mask)];
|
|
|
e4d7d2 |
+ t2 = ToLinearF[cb = (wp[2] & mask)];
|
|
|
e4d7d2 |
op[0] = t0;
|
|
|
e4d7d2 |
op[1] = t1;
|
|
|
e4d7d2 |
op[2] = t2;
|
|
|
e4d7d2 |
@@ -136,10 +136,10 @@
|
|
|
e4d7d2 |
op[2] = t2;
|
|
|
e4d7d2 |
}
|
|
|
e4d7d2 |
} else if (stride == 4) {
|
|
|
e4d7d2 |
- t0 = ToLinearF[cr = wp[0]];
|
|
|
e4d7d2 |
- t1 = ToLinearF[cg = wp[1]];
|
|
|
e4d7d2 |
- t2 = ToLinearF[cb = wp[2]];
|
|
|
e4d7d2 |
- t3 = ToLinearF[ca = wp[3]];
|
|
|
e4d7d2 |
+ t0 = ToLinearF[cr = (wp[0] & mask)];
|
|
|
e4d7d2 |
+ t1 = ToLinearF[cg = (wp[1] & mask)];
|
|
|
e4d7d2 |
+ t2 = ToLinearF[cb = (wp[2] & mask)];
|
|
|
e4d7d2 |
+ t3 = ToLinearF[ca = (wp[3] & mask)];
|
|
|
e4d7d2 |
op[0] = t0;
|
|
|
e4d7d2 |
op[1] = t1;
|
|
|
e4d7d2 |
op[2] = t2;
|
|
|
e4d7d2 |
@@ -183,9 +183,9 @@
|
|
|
e4d7d2 |
if (n >= stride) {
|
|
|
e4d7d2 |
mask = CODE_MASK;
|
|
|
e4d7d2 |
if (stride == 3) {
|
|
|
e4d7d2 |
- t0 = ToLinearF[cr = wp[0]] * SCALE12;
|
|
|
e4d7d2 |
- t1 = ToLinearF[cg = wp[1]] * SCALE12;
|
|
|
e4d7d2 |
- t2 = ToLinearF[cb = wp[2]] * SCALE12;
|
|
|
e4d7d2 |
+ t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12;
|
|
|
e4d7d2 |
+ t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12;
|
|
|
e4d7d2 |
+ t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12;
|
|
|
e4d7d2 |
op[0] = CLAMP12(t0);
|
|
|
e4d7d2 |
op[1] = CLAMP12(t1);
|
|
|
e4d7d2 |
op[2] = CLAMP12(t2);
|
|
|
e4d7d2 |
@@ -202,10 +202,10 @@
|
|
|
e4d7d2 |
op[2] = CLAMP12(t2);
|
|
|
e4d7d2 |
}
|
|
|
e4d7d2 |
} else if (stride == 4) {
|
|
|
e4d7d2 |
- t0 = ToLinearF[cr = wp[0]] * SCALE12;
|
|
|
e4d7d2 |
- t1 = ToLinearF[cg = wp[1]] * SCALE12;
|
|
|
e4d7d2 |
- t2 = ToLinearF[cb = wp[2]] * SCALE12;
|
|
|
e4d7d2 |
- t3 = ToLinearF[ca = wp[3]] * SCALE12;
|
|
|
e4d7d2 |
+ t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12;
|
|
|
e4d7d2 |
+ t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12;
|
|
|
e4d7d2 |
+ t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12;
|
|
|
e4d7d2 |
+ t3 = ToLinearF[ca = (wp[3] & mask)] * SCALE12;
|
|
|
e4d7d2 |
op[0] = CLAMP12(t0);
|
|
|
e4d7d2 |
op[1] = CLAMP12(t1);
|
|
|
e4d7d2 |
op[2] = CLAMP12(t2);
|
|
|
e4d7d2 |
@@ -247,9 +247,9 @@
|
|
|
e4d7d2 |
if (n >= stride) {
|
|
|
e4d7d2 |
mask = CODE_MASK;
|
|
|
e4d7d2 |
if (stride == 3) {
|
|
|
e4d7d2 |
- op[0] = ToLinear16[cr = wp[0]];
|
|
|
e4d7d2 |
- op[1] = ToLinear16[cg = wp[1]];
|
|
|
e4d7d2 |
- op[2] = ToLinear16[cb = wp[2]];
|
|
|
e4d7d2 |
+ op[0] = ToLinear16[cr = (wp[0] & mask)];
|
|
|
e4d7d2 |
+ op[1] = ToLinear16[cg = (wp[1] & mask)];
|
|
|
e4d7d2 |
+ op[2] = ToLinear16[cb = (wp[2] & mask)];
|
|
|
e4d7d2 |
n -= 3;
|
|
|
e4d7d2 |
while (n > 0) {
|
|
|
e4d7d2 |
wp += 3;
|
|
|
e4d7d2 |
@@ -260,10 +260,10 @@
|
|
|
e4d7d2 |
op[2] = ToLinear16[(cb += wp[2]) & mask];
|
|
|
e4d7d2 |
}
|
|
|
e4d7d2 |
} else if (stride == 4) {
|
|
|
e4d7d2 |
- op[0] = ToLinear16[cr = wp[0]];
|
|
|
e4d7d2 |
- op[1] = ToLinear16[cg = wp[1]];
|
|
|
e4d7d2 |
- op[2] = ToLinear16[cb = wp[2]];
|
|
|
e4d7d2 |
- op[3] = ToLinear16[ca = wp[3]];
|
|
|
e4d7d2 |
+ op[0] = ToLinear16[cr = (wp[0] & mask)];
|
|
|
e4d7d2 |
+ op[1] = ToLinear16[cg = (wp[1] & mask)];
|
|
|
e4d7d2 |
+ op[2] = ToLinear16[cb = (wp[2] & mask)];
|
|
|
e4d7d2 |
+ op[3] = ToLinear16[ca = (wp[3] & mask)];
|
|
|
e4d7d2 |
n -= 4;
|
|
|
e4d7d2 |
while (n > 0) {
|
|
|
e4d7d2 |
wp += 4;
|
|
|
e4d7d2 |
@@ -342,9 +342,9 @@
|
|
|
e4d7d2 |
if (n >= stride) {
|
|
|
e4d7d2 |
mask = CODE_MASK;
|
|
|
e4d7d2 |
if (stride == 3) {
|
|
|
e4d7d2 |
- op[0] = ToLinear8[cr = wp[0]];
|
|
|
e4d7d2 |
- op[1] = ToLinear8[cg = wp[1]];
|
|
|
e4d7d2 |
- op[2] = ToLinear8[cb = wp[2]];
|
|
|
e4d7d2 |
+ op[0] = ToLinear8[cr = (wp[0] & mask)];
|
|
|
e4d7d2 |
+ op[1] = ToLinear8[cg = (wp[1] & mask)];
|
|
|
e4d7d2 |
+ op[2] = ToLinear8[cb = (wp[2] & mask)];
|
|
|
e4d7d2 |
n -= 3;
|
|
|
e4d7d2 |
while (n > 0) {
|
|
|
e4d7d2 |
n -= 3;
|
|
|
e4d7d2 |
@@ -355,10 +355,10 @@
|
|
|
e4d7d2 |
op[2] = ToLinear8[(cb += wp[2]) & mask];
|
|
|
e4d7d2 |
}
|
|
|
e4d7d2 |
} else if (stride == 4) {
|
|
|
e4d7d2 |
- op[0] = ToLinear8[cr = wp[0]];
|
|
|
e4d7d2 |
- op[1] = ToLinear8[cg = wp[1]];
|
|
|
e4d7d2 |
- op[2] = ToLinear8[cb = wp[2]];
|
|
|
e4d7d2 |
- op[3] = ToLinear8[ca = wp[3]];
|
|
|
e4d7d2 |
+ op[0] = ToLinear8[cr = (wp[0] & mask)];
|
|
|
e4d7d2 |
+ op[1] = ToLinear8[cg = (wp[1] & mask)];
|
|
|
e4d7d2 |
+ op[2] = ToLinear8[cb = (wp[2] & mask)];
|
|
|
e4d7d2 |
+ op[3] = ToLinear8[ca = (wp[3] & mask)];
|
|
|
e4d7d2 |
n -= 4;
|
|
|
e4d7d2 |
while (n > 0) {
|
|
|
e4d7d2 |
n -= 4;
|
|
|
e4d7d2 |
@@ -393,9 +393,9 @@
|
|
|
e4d7d2 |
mask = CODE_MASK;
|
|
|
e4d7d2 |
if (stride == 3) {
|
|
|
e4d7d2 |
op[0] = 0;
|
|
|
e4d7d2 |
- t1 = ToLinear8[cb = wp[2]];
|
|
|
e4d7d2 |
- t2 = ToLinear8[cg = wp[1]];
|
|
|
e4d7d2 |
- t3 = ToLinear8[cr = wp[0]];
|
|
|
e4d7d2 |
+ t1 = ToLinear8[cb = (wp[2] & mask)];
|
|
|
e4d7d2 |
+ t2 = ToLinear8[cg = (wp[1] & mask)];
|
|
|
e4d7d2 |
+ t3 = ToLinear8[cr = (wp[0] & mask)];
|
|
|
e4d7d2 |
op[1] = t1;
|
|
|
e4d7d2 |
op[2] = t2;
|
|
|
e4d7d2 |
op[3] = t3;
|
|
|
e4d7d2 |
@@ -413,10 +413,10 @@
|
|
|
e4d7d2 |
op[3] = t3;
|
|
|
e4d7d2 |
}
|
|
|
e4d7d2 |
} else if (stride == 4) {
|
|
|
e4d7d2 |
- t0 = ToLinear8[ca = wp[3]];
|
|
|
e4d7d2 |
- t1 = ToLinear8[cb = wp[2]];
|
|
|
e4d7d2 |
- t2 = ToLinear8[cg = wp[1]];
|
|
|
e4d7d2 |
- t3 = ToLinear8[cr = wp[0]];
|
|
|
e4d7d2 |
+ t0 = ToLinear8[ca = (wp[3] & mask)];
|
|
|
e4d7d2 |
+ t1 = ToLinear8[cb = (wp[2] & mask)];
|
|
|
e4d7d2 |
+ t2 = ToLinear8[cg = (wp[1] & mask)];
|
|
|
e4d7d2 |
+ t3 = ToLinear8[cr = (wp[0] & mask)];
|
|
|
e4d7d2 |
op[0] = t0;
|
|
|
e4d7d2 |
op[1] = t1;
|
|
|
e4d7d2 |
op[2] = t2;
|
|
|
e4d7d2 |
@@ -630,10 +630,10 @@
|
|
|
e4d7d2 |
return guess;
|
|
|
e4d7d2 |
}
|
|
|
e4d7d2 |
|
|
|
e4d7d2 |
-static uint32
|
|
|
e4d7d2 |
-multiply(size_t m1, size_t m2)
|
|
|
e4d7d2 |
+static tsize_t
|
|
|
e4d7d2 |
+multiply(tsize_t m1, tsize_t m2)
|
|
|
e4d7d2 |
{
|
|
|
e4d7d2 |
- uint32 bytes = m1 * m2;
|
|
|
e4d7d2 |
+ tsize_t bytes = m1 * m2;
|
|
|
e4d7d2 |
|
|
|
e4d7d2 |
if (m1 && bytes / m1 != m2)
|
|
|
e4d7d2 |
bytes = 0;
|
|
|
e4d7d2 |
@@ -641,6 +641,20 @@
|
|
|
e4d7d2 |
return bytes;
|
|
|
e4d7d2 |
}
|
|
|
e4d7d2 |
|
|
|
e4d7d2 |
+static tsize_t
|
|
|
e4d7d2 |
+add_ms(tsize_t m1, tsize_t m2)
|
|
|
e4d7d2 |
+{
|
|
|
e4d7d2 |
+ tsize_t bytes = m1 + m2;
|
|
|
e4d7d2 |
+
|
|
|
e4d7d2 |
+ /* if either input is zero, assume overflow already occurred */
|
|
|
e4d7d2 |
+ if (m1 == 0 || m2 == 0)
|
|
|
e4d7d2 |
+ bytes = 0;
|
|
|
e4d7d2 |
+ else if (bytes <= m1 || bytes <= m2)
|
|
|
e4d7d2 |
+ bytes = 0;
|
|
|
e4d7d2 |
+
|
|
|
e4d7d2 |
+ return bytes;
|
|
|
e4d7d2 |
+}
|
|
|
e4d7d2 |
+
|
|
|
e4d7d2 |
static int
|
|
|
e4d7d2 |
PixarLogSetupDecode(TIFF* tif)
|
|
|
e4d7d2 |
{
|
|
|
e4d7d2 |
@@ -661,6 +675,8 @@
|
|
|
e4d7d2 |
td->td_samplesperpixel : 1);
|
|
|
e4d7d2 |
tbuf_size = multiply(multiply(multiply(sp->stride, td->td_imagewidth),
|
|
|
e4d7d2 |
td->td_rowsperstrip), sizeof(uint16));
|
|
|
e4d7d2 |
+ /* add one more stride in case input ends mid-stride */
|
|
|
e4d7d2 |
+ tbuf_size = add_ms(tbuf_size, sizeof(uint16) * sp->stride);
|
|
|
e4d7d2 |
if (tbuf_size == 0)
|
|
|
e4d7d2 |
return (0);
|
|
|
e4d7d2 |
sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size);
|