2008.08.29 22:53 "[Tiff] Some security fixes from RHEL", by Even Rouault

2008.08.29 22:53 "[Tiff] Some security fixes from RHEL", by Even Rouault

I've just read http://lwn.net/Articles/296197 and I downloaded the source rpm.

I've attached here 2 vendor security patches from Redhat for their RHELs that aren't yet applied to CVS head (I haven't check for 3.9 branch): - libtiff-3.8.2-CVE-2006-2193.patch

- libtiff-3.8.2-lzw-bugs.patch: Fixes for CVE-2008-2327. Partly reported and proposed patch in http://bugzilla.maptools.org/show_bug.cgi?id=1929. But Redhat's patch has a few extra lines. See https://bugzilla.redhat.com/show_bug.cgi?id=458674

I'm just curious about how vendors usually interact with libtiff upstream team? It would have been nice if they had dropped a word on it on libtiff bugzilla...

Fixes for CVE-2008-2327

diff -Naur tiff-3.8.2.orig/libtiff/tif_lzw.c tiff-3.8.2/libtiff/tif_lzw.c

--- tiff-3.8.2.orig/libtiff/tif_lzw.c   2006-03-21 11:42:50.000000000 -0500
+++ tiff-3.8.2/libtiff/tif_lzw.c        2008-08-22 16:26:01.000000000 -0400

@@ -237,6 +237,11 @@
                     sp->dec_codetab[code].length = 1;
                     sp->dec_codetab[code].next = NULL;
                 } while (code--);

+               /*
+                * Zero-out the unused entries
+                */
+               _TIFFmemset(&sp->dec_codetab[CODE_CLEAR], 0,
+                           (CODE_FIRST-CODE_CLEAR)*sizeof (code_t));

        }
        return (1);
 }
@@ -408,12 +413,19 @@
                        break;
                if (code == CODE_CLEAR) {

                        free_entp = sp->dec_codetab + CODE_FIRST;
+                       _TIFFmemset(free_entp, 0, (CSIZE-CODE_FIRST)*sizeof (code_t));
                        nbits = BITS_MIN;
                        nbitsmask = MAXCODE(BITS_MIN);
                        maxcodep = sp->dec_codetab + nbitsmask-1;
                        NextCode(tif, sp, bp, code, GetNextCode);
                        if (code == CODE_EOI)
                                break;
+                       if (code == CODE_CLEAR) {
+                               TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+                               "LZWDecode: Corrupted LZW table at scanline %d",
+                               tif->tif_row);
+                               return (0);
+                       }
                        *op++ = (char)code, occ--;
                        oldcodep = sp->dec_codetab + code;
                        continue;
@@ -604,12 +616,19 @@
                        break;
                if (code == CODE_CLEAR) {
                        free_entp = sp->dec_codetab + CODE_FIRST;
+                       _TIFFmemset(free_entp, 0, (CSIZE-CODE_FIRST)*sizeof (code_t));
                        nbits = BITS_MIN;
                        nbitsmask = MAXCODE(BITS_MIN);
                        maxcodep = sp->dec_codetab + nbitsmask;
                        NextCode(tif, sp, bp, code, GetNextCodeCompat);
                        if (code == CODE_EOI)
                                break;
+                       if (code == CODE_CLEAR) {
+                               TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+                               "LZWDecodeCompat: Corrupted LZW table at scanline %d",
+                               tif->tif_row);
+                               return (0);
+                       }
                        *op++ = code, occ--;
                        oldcodep = sp->dec_codetab + code;
                        continue;

--- tiff-3.8.2/tools/tiff2pdf.c.CVE-2006-2193   2006-03-21 17:42:51.000000000 +0100
+++ tiff-3.8.2/tools/tiff2pdf.c 2006-09-05 10:47:51.000000000 +0200

@@ -3668,7 +3668,7 @@
        written += TIFFWriteFile(output, (tdata_t) "(", 1);
        for (i=0;i<len;i++){

                if((pdfstr[i]&0x80) || (pdfstr[i]==127) || (pdfstr[i]<32)){

-                       sprintf(buffer, "\\%.3o", pdfstr[i]);
+                       snprintf(buffer, sizeof(buffer), "\\%.3o", (unsigned char) pdfstr[i]);

                        written += TIFFWriteFile(output, (tdata_t) buffer, 4);
                } else {
                        switch (pdfstr[i]){