|
|
7c98bb |
Fix unsafe handling of DotRange and related tags. Back-port of upstream
|
|
|
7c98bb |
patch for CVE-2012-5581. (Note: I have not pushed this into upstream CVS
|
|
|
7c98bb |
for the 3.9 branch, because I'm not entirely convinced that it won't create
|
|
|
7c98bb |
application compatibility issues --- tgl)
|
|
|
7c98bb |
|
|
|
7c98bb |
|
|
|
7c98bb |
diff -Naur tiff-3.9.4.orig/libtiff/tif_dir.c tiff-3.9.4/libtiff/tif_dir.c
|
|
|
7c98bb |
--- tiff-3.9.4.orig/libtiff/tif_dir.c 2010-06-09 17:15:27.000000000 -0400
|
|
|
7c98bb |
+++ tiff-3.9.4/libtiff/tif_dir.c 2012-12-10 15:12:38.442326919 -0500
|
|
|
7c98bb |
@@ -492,31 +492,28 @@
|
|
|
7c98bb |
goto end;
|
|
|
7c98bb |
}
|
|
|
7c98bb |
|
|
|
7c98bb |
- if ((fip->field_passcount
|
|
|
7c98bb |
+ if (fip->field_tag == TIFFTAG_DOTRANGE
|
|
|
7c98bb |
+ && strcmp(fip->field_name,"DotRange") == 0) {
|
|
|
7c98bb |
+ /* TODO: This is an evil exception and should not have been
|
|
|
7c98bb |
+ handled this way ... likely best if we move it into
|
|
|
7c98bb |
+ the directory structure with an explicit field in
|
|
|
7c98bb |
+ libtiff 4.1 and assign it a FIELD_ value */
|
|
|
7c98bb |
+ uint16 v[2];
|
|
|
7c98bb |
+ v[0] = (uint16)va_arg(ap, int);
|
|
|
7c98bb |
+ v[1] = (uint16)va_arg(ap, int);
|
|
|
7c98bb |
+ _TIFFmemcpy(tv->value, v, 4);
|
|
|
7c98bb |
+ }
|
|
|
7c98bb |
+ else if (fip->field_passcount
|
|
|
7c98bb |
|| fip->field_writecount == TIFF_VARIABLE
|
|
|
7c98bb |
|| fip->field_writecount == TIFF_VARIABLE2
|
|
|
7c98bb |
|| fip->field_writecount == TIFF_SPP
|
|
|
7c98bb |
- || tv->count > 1)
|
|
|
7c98bb |
- && fip->field_tag != TIFFTAG_PAGENUMBER
|
|
|
7c98bb |
- && fip->field_tag != TIFFTAG_HALFTONEHINTS
|
|
|
7c98bb |
- && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
|
|
|
7c98bb |
- && fip->field_tag != TIFFTAG_DOTRANGE) {
|
|
|
7c98bb |
+ || tv->count > 1) {
|
|
|
7c98bb |
_TIFFmemcpy(tv->value, va_arg(ap, void *),
|
|
|
7c98bb |
tv->count * tv_size);
|
|
|
7c98bb |
} else {
|
|
|
7c98bb |
- /*
|
|
|
7c98bb |
- * XXX: The following loop required to handle
|
|
|
7c98bb |
- * TIFFTAG_PAGENUMBER, TIFFTAG_HALFTONEHINTS,
|
|
|
7c98bb |
- * TIFFTAG_YCBCRSUBSAMPLING and TIFFTAG_DOTRANGE tags.
|
|
|
7c98bb |
- * These tags are actually arrays and should be passed as
|
|
|
7c98bb |
- * array pointers to TIFFSetField() function, but actually
|
|
|
7c98bb |
- * passed as a list of separate values. This behaviour
|
|
|
7c98bb |
- * must be changed in the future!
|
|
|
7c98bb |
- */
|
|
|
7c98bb |
- int i;
|
|
|
7c98bb |
char *val = (char *)tv->value;
|
|
|
7c98bb |
|
|
|
7c98bb |
- for (i = 0; i < tv->count; i++, val += tv_size) {
|
|
|
7c98bb |
+ assert( tv->count == 1 );
|
|
|
7c98bb |
switch (fip->field_type) {
|
|
|
7c98bb |
case TIFF_BYTE:
|
|
|
7c98bb |
case TIFF_UNDEFINED:
|
|
|
7c98bb |
@@ -575,7 +572,6 @@
|
|
|
7c98bb |
status = 0;
|
|
|
7c98bb |
break;
|
|
|
7c98bb |
}
|
|
|
7c98bb |
- }
|
|
|
7c98bb |
}
|
|
|
7c98bb |
}
|
|
|
7c98bb |
}
|
|
|
7c98bb |
@@ -866,24 +862,27 @@
|
|
|
7c98bb |
*va_arg(ap, uint16*) = (uint16)tv->count;
|
|
|
7c98bb |
*va_arg(ap, void **) = tv->value;
|
|
|
7c98bb |
ret_val = 1;
|
|
|
7c98bb |
- } else {
|
|
|
7c98bb |
- if ((fip->field_type == TIFF_ASCII
|
|
|
7c98bb |
+ } else if (fip->field_tag == TIFFTAG_DOTRANGE
|
|
|
7c98bb |
+ && strcmp(fip->field_name,"DotRange") == 0) {
|
|
|
7c98bb |
+ /* TODO: This is an evil exception and should not have been
|
|
|
7c98bb |
+ handled this way ... likely best if we move it into
|
|
|
7c98bb |
+ the directory structure with an explicit field in
|
|
|
7c98bb |
+ libtiff 4.1 and assign it a FIELD_ value */
|
|
|
7c98bb |
+ *va_arg(ap, uint16*) = ((uint16 *)tv->value)[0];
|
|
|
7c98bb |
+ *va_arg(ap, uint16*) = ((uint16 *)tv->value)[1];
|
|
|
7c98bb |
+ ret_val = 1;
|
|
|
7c98bb |
+ } else {
|
|
|
7c98bb |
+ if (fip->field_type == TIFF_ASCII
|
|
|
7c98bb |
|| fip->field_readcount == TIFF_VARIABLE
|
|
|
7c98bb |
|| fip->field_readcount == TIFF_VARIABLE2
|
|
|
7c98bb |
|| fip->field_readcount == TIFF_SPP
|
|
|
7c98bb |
- || tv->count > 1)
|
|
|
7c98bb |
- && fip->field_tag != TIFFTAG_PAGENUMBER
|
|
|
7c98bb |
- && fip->field_tag != TIFFTAG_HALFTONEHINTS
|
|
|
7c98bb |
- && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
|
|
|
7c98bb |
- && fip->field_tag != TIFFTAG_DOTRANGE) {
|
|
|
7c98bb |
+ || tv->count > 1) {
|
|
|
7c98bb |
*va_arg(ap, void **) = tv->value;
|
|
|
7c98bb |
ret_val = 1;
|
|
|
7c98bb |
} else {
|
|
|
7c98bb |
- int j;
|
|
|
7c98bb |
char *val = (char *)tv->value;
|
|
|
7c98bb |
|
|
|
7c98bb |
- for (j = 0; j < tv->count;
|
|
|
7c98bb |
- j++, val += _TIFFDataSize(tv->info->field_type)) {
|
|
|
7c98bb |
+ assert( tv->count == 1 );
|
|
|
7c98bb |
switch (fip->field_type) {
|
|
|
7c98bb |
case TIFF_BYTE:
|
|
|
7c98bb |
case TIFF_UNDEFINED:
|
|
|
7c98bb |
@@ -933,7 +932,6 @@
|
|
|
7c98bb |
ret_val = 0;
|
|
|
7c98bb |
break;
|
|
|
7c98bb |
}
|
|
|
7c98bb |
- }
|
|
|
7c98bb |
}
|
|
|
7c98bb |
}
|
|
|
7c98bb |
break;
|
|
|
7c98bb |
diff -Naur tiff-3.9.4.orig/libtiff/tif_print.c tiff-3.9.4/libtiff/tif_print.c
|
|
|
7c98bb |
--- tiff-3.9.4.orig/libtiff/tif_print.c 2010-06-08 14:50:42.000000000 -0400
|
|
|
7c98bb |
+++ tiff-3.9.4/libtiff/tif_print.c 2012-12-10 15:41:42.860710914 -0500
|
|
|
7c98bb |
@@ -112,16 +112,22 @@
|
|
|
7c98bb |
}
|
|
|
7c98bb |
|
|
|
7c98bb |
static int
|
|
|
7c98bb |
-_TIFFPrettyPrintField(TIFF* tif, FILE* fd, ttag_t tag,
|
|
|
7c98bb |
+_TIFFPrettyPrintField(TIFF* tif, const TIFFFieldInfo *fip, FILE* fd, ttag_t tag,
|
|
|
7c98bb |
uint32 value_count, void *raw_data)
|
|
|
7c98bb |
{
|
|
|
7c98bb |
TIFFDirectory *td = &tif->tif_dir;
|
|
|
7c98bb |
|
|
|
7c98bb |
+ /* do not try to pretty print auto-defined fields */
|
|
|
7c98bb |
+ if (strncmp(fip->field_name,"Tag ", 4) == 0) {
|
|
|
7c98bb |
+ return 0;
|
|
|
7c98bb |
+ }
|
|
|
7c98bb |
+
|
|
|
7c98bb |
switch (tag)
|
|
|
7c98bb |
{
|
|
|
7c98bb |
case TIFFTAG_INKSET:
|
|
|
7c98bb |
- fprintf(fd, " Ink Set: ");
|
|
|
7c98bb |
- switch (*((uint16*)raw_data)) {
|
|
|
7c98bb |
+ if (value_count == 2 && fip->field_type == TIFF_SHORT) {
|
|
|
7c98bb |
+ fprintf(fd, " Ink Set: ");
|
|
|
7c98bb |
+ switch (*((uint16*)raw_data)) {
|
|
|
7c98bb |
case INKSET_CMYK:
|
|
|
7c98bb |
fprintf(fd, "CMYK\n");
|
|
|
7c98bb |
break;
|
|
|
7c98bb |
@@ -130,15 +136,26 @@
|
|
|
7c98bb |
*((uint16*)raw_data),
|
|
|
7c98bb |
*((uint16*)raw_data));
|
|
|
7c98bb |
break;
|
|
|
7c98bb |
+ }
|
|
|
7c98bb |
+ return 1;
|
|
|
7c98bb |
}
|
|
|
7c98bb |
- return 1;
|
|
|
7c98bb |
+ return 0;
|
|
|
7c98bb |
+
|
|
|
7c98bb |
case TIFFTAG_DOTRANGE:
|
|
|
7c98bb |
- fprintf(fd, " Dot Range: %u-%u\n",
|
|
|
7c98bb |
- ((uint16*)raw_data)[0], ((uint16*)raw_data)[1]);
|
|
|
7c98bb |
- return 1;
|
|
|
7c98bb |
+ if (value_count == 2 && fip->field_type == TIFF_SHORT) {
|
|
|
7c98bb |
+ fprintf(fd, " Dot Range: %u-%u\n",
|
|
|
7c98bb |
+ ((uint16*)raw_data)[0], ((uint16*)raw_data)[1]);
|
|
|
7c98bb |
+ return 1;
|
|
|
7c98bb |
+ }
|
|
|
7c98bb |
+ return 0;
|
|
|
7c98bb |
+
|
|
|
7c98bb |
case TIFFTAG_WHITEPOINT:
|
|
|
7c98bb |
- fprintf(fd, " White Point: %g-%g\n",
|
|
|
7c98bb |
- ((float *)raw_data)[0], ((float *)raw_data)[1]); return 1;
|
|
|
7c98bb |
+ if (value_count == 2 && fip->field_type == TIFF_RATIONAL) {
|
|
|
7c98bb |
+ fprintf(fd, " White Point: %g-%g\n",
|
|
|
7c98bb |
+ ((float *)raw_data)[0], ((float *)raw_data)[1]); return 1;
|
|
|
7c98bb |
+ }
|
|
|
7c98bb |
+ return 0;
|
|
|
7c98bb |
+
|
|
|
7c98bb |
case TIFFTAG_REFERENCEBLACKWHITE:
|
|
|
7c98bb |
{
|
|
|
7c98bb |
uint16 i;
|
|
|
7c98bb |
@@ -178,10 +195,13 @@
|
|
|
7c98bb |
(unsigned long) value_count);
|
|
|
7c98bb |
return 1;
|
|
|
7c98bb |
case TIFFTAG_STONITS:
|
|
|
7c98bb |
- fprintf(fd,
|
|
|
7c98bb |
- " Sample to Nits conversion factor: %.4e\n",
|
|
|
7c98bb |
- *((double*)raw_data));
|
|
|
7c98bb |
- return 1;
|
|
|
7c98bb |
+ if (value_count == 1 && fip->field_type == TIFF_DOUBLE) {
|
|
|
7c98bb |
+ fprintf(fd,
|
|
|
7c98bb |
+ " Sample to Nits conversion factor: %.4e\n",
|
|
|
7c98bb |
+ *((double*)raw_data));
|
|
|
7c98bb |
+ return 1;
|
|
|
7c98bb |
+ }
|
|
|
7c98bb |
+ return 0;
|
|
|
7c98bb |
}
|
|
|
7c98bb |
|
|
|
7c98bb |
return 0;
|
|
|
7c98bb |
@@ -528,44 +548,28 @@
|
|
|
7c98bb |
value_count = td->td_samplesperpixel;
|
|
|
7c98bb |
else
|
|
|
7c98bb |
value_count = fip->field_readcount;
|
|
|
7c98bb |
- if ((fip->field_type == TIFF_ASCII
|
|
|
7c98bb |
+ if (fip->field_tag == TIFFTAG_DOTRANGE
|
|
|
7c98bb |
+ && strcmp(fip->field_name,"DotRange") == 0) {
|
|
|
7c98bb |
+ /* TODO: This is an evil exception and should not have been
|
|
|
7c98bb |
+ handled this way ... likely best if we move it into
|
|
|
7c98bb |
+ the directory structure with an explicit field in
|
|
|
7c98bb |
+ libtiff 4.1 and assign it a FIELD_ value */
|
|
|
7c98bb |
+ static uint16 dotrange[2];
|
|
|
7c98bb |
+ raw_data = dotrange;
|
|
|
7c98bb |
+ TIFFGetField(tif, tag, dotrange+0, dotrange+1);
|
|
|
7c98bb |
+ } else if (fip->field_type == TIFF_ASCII
|
|
|
7c98bb |
|| fip->field_readcount == TIFF_VARIABLE
|
|
|
7c98bb |
|| fip->field_readcount == TIFF_VARIABLE2
|
|
|
7c98bb |
|| fip->field_readcount == TIFF_SPP
|
|
|
7c98bb |
- || value_count > 1)
|
|
|
7c98bb |
- && fip->field_tag != TIFFTAG_PAGENUMBER
|
|
|
7c98bb |
- && fip->field_tag != TIFFTAG_HALFTONEHINTS
|
|
|
7c98bb |
- && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
|
|
|
7c98bb |
- && fip->field_tag != TIFFTAG_DOTRANGE) {
|
|
|
7c98bb |
+ || value_count > 1) {
|
|
|
7c98bb |
if(TIFFGetField(tif, tag, &raw_data) != 1)
|
|
|
7c98bb |
continue;
|
|
|
7c98bb |
- } else if (fip->field_tag != TIFFTAG_PAGENUMBER
|
|
|
7c98bb |
- && fip->field_tag != TIFFTAG_HALFTONEHINTS
|
|
|
7c98bb |
- && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
|
|
|
7c98bb |
- && fip->field_tag != TIFFTAG_DOTRANGE) {
|
|
|
7c98bb |
- raw_data = _TIFFmalloc(
|
|
|
7c98bb |
- _TIFFDataSize(fip->field_type)
|
|
|
7c98bb |
- * value_count);
|
|
|
7c98bb |
- mem_alloc = 1;
|
|
|
7c98bb |
- if(TIFFGetField(tif, tag, raw_data) != 1) {
|
|
|
7c98bb |
- _TIFFfree(raw_data);
|
|
|
7c98bb |
- continue;
|
|
|
7c98bb |
- }
|
|
|
7c98bb |
} else {
|
|
|
7c98bb |
- /*
|
|
|
7c98bb |
- * XXX: Should be fixed and removed, see the
|
|
|
7c98bb |
- * notes related to TIFFTAG_PAGENUMBER,
|
|
|
7c98bb |
- * TIFFTAG_HALFTONEHINTS,
|
|
|
7c98bb |
- * TIFFTAG_YCBCRSUBSAMPLING and
|
|
|
7c98bb |
- * TIFFTAG_DOTRANGE tags in tif_dir.c. */
|
|
|
7c98bb |
- char *tmp;
|
|
|
7c98bb |
raw_data = _TIFFmalloc(
|
|
|
7c98bb |
_TIFFDataSize(fip->field_type)
|
|
|
7c98bb |
* value_count);
|
|
|
7c98bb |
- tmp = raw_data;
|
|
|
7c98bb |
mem_alloc = 1;
|
|
|
7c98bb |
- if(TIFFGetField(tif, tag, tmp,
|
|
|
7c98bb |
- tmp + _TIFFDataSize(fip->field_type)) != 1) {
|
|
|
7c98bb |
+ if(TIFFGetField(tif, tag, raw_data) != 1) {
|
|
|
7c98bb |
_TIFFfree(raw_data);
|
|
|
7c98bb |
continue;
|
|
|
7c98bb |
}
|
|
|
7c98bb |
@@ -578,7 +582,7 @@
|
|
|
7c98bb |
* _TIFFPrettyPrintField() fall down and print it as any other
|
|
|
7c98bb |
* tag.
|
|
|
7c98bb |
*/
|
|
|
7c98bb |
- if (_TIFFPrettyPrintField(tif, fd, tag, value_count, raw_data)) {
|
|
|
7c98bb |
+ if (_TIFFPrettyPrintField(tif, fip, fd, tag, value_count, raw_data)) {
|
|
|
7c98bb |
if(mem_alloc)
|
|
|
7c98bb |
_TIFFfree(raw_data);
|
|
|
7c98bb |
continue;
|