aboutsummaryrefslogtreecommitdiffstats
path: root/main/tiff/CVE-2012-5581.patch
diff options
context:
space:
mode:
Diffstat (limited to 'main/tiff/CVE-2012-5581.patch')
-rw-r--r--main/tiff/CVE-2012-5581.patch311
1 files changed, 311 insertions, 0 deletions
diff --git a/main/tiff/CVE-2012-5581.patch b/main/tiff/CVE-2012-5581.patch
new file mode 100644
index 0000000000..21e3f53899
--- /dev/null
+++ b/main/tiff/CVE-2012-5581.patch
@@ -0,0 +1,311 @@
+diff -Naur tiff-3.9.6.fix/libtiff/tif_dir.c tiff-3.9.6/libtiff/tif_dir.c
+--- tiff-3.9.6.fix/libtiff/tif_dir.c 2010-07-08 21:47:59.000000000 +0530
++++ tiff-3.9.6/libtiff/tif_dir.c 2012-11-08 10:39:25.549268282 +0530
+@@ -493,94 +493,90 @@
+ status = 0;
+ goto end;
+ }
++ if (fip->field_tag == TIFFTAG_DOTRANGE
++ && strcmp(fip->field_name,"DotRange") == 0) {
++ /* TODO: This is an evil exception and should not have been
++ handled this way ... likely best if we move it into
++ the directory structure with an explicit field in
++ libtiff 4.1 and assign it a FIELD_ value */
++ uint16 v[2];
++ v[0] = (uint16)va_arg(ap, int);
++ v[1] = (uint16)va_arg(ap, int);
++ _TIFFmemcpy(tv->value, &v, 4);
++ }
++
++ else if (fip->field_passcount
++ || fip->field_writecount == TIFF_VARIABLE
++ || fip->field_writecount == TIFF_VARIABLE2
++ || fip->field_writecount == TIFF_SPP
++ || tv->count > 1) {
+
+- if ((fip->field_passcount
+- || fip->field_writecount == TIFF_VARIABLE
+- || fip->field_writecount == TIFF_VARIABLE2
+- || fip->field_writecount == TIFF_SPP
+- || tv->count > 1)
+- && fip->field_tag != TIFFTAG_PAGENUMBER
+- && fip->field_tag != TIFFTAG_HALFTONEHINTS
+- && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
+- && fip->field_tag != TIFFTAG_DOTRANGE) {
+ _TIFFmemcpy(tv->value, va_arg(ap, void *),
+ tv->count * tv_size);
+ } else {
+- /*
+- * XXX: The following loop required to handle
+- * TIFFTAG_PAGENUMBER, TIFFTAG_HALFTONEHINTS,
+- * TIFFTAG_YCBCRSUBSAMPLING and TIFFTAG_DOTRANGE tags.
+- * These tags are actually arrays and should be passed as
+- * array pointers to TIFFSetField() function, but actually
+- * passed as a list of separate values. This behaviour
+- * must be changed in the future!
+- */
+- int i;
++ assert( tv->count == 1 );
+ char *val = (char *)tv->value;
+-
+- for (i = 0; i < tv->count; i++, val += tv_size) {
+- switch (fip->field_type) {
+- case TIFF_BYTE:
+- case TIFF_UNDEFINED:
+- {
+- uint8 v = (uint8)va_arg(ap, int);
+- _TIFFmemcpy(val, &v, tv_size);
+- }
+- break;
+- case TIFF_SBYTE:
+- {
+- int8 v = (int8)va_arg(ap, int);
+- _TIFFmemcpy(val, &v, tv_size);
+- }
+- break;
+- case TIFF_SHORT:
+- {
+- uint16 v = (uint16)va_arg(ap, int);
+- _TIFFmemcpy(val, &v, tv_size);
+- }
+- break;
+- case TIFF_SSHORT:
+- {
+- int16 v = (int16)va_arg(ap, int);
+- _TIFFmemcpy(val, &v, tv_size);
+- }
+- break;
+- case TIFF_LONG:
+- case TIFF_IFD:
+- {
+- uint32 v = va_arg(ap, uint32);
+- _TIFFmemcpy(val, &v, tv_size);
+- }
+- break;
+- case TIFF_SLONG:
+- {
+- int32 v = va_arg(ap, int32);
+- _TIFFmemcpy(val, &v, tv_size);
+- }
+- break;
+- case TIFF_RATIONAL:
+- case TIFF_SRATIONAL:
+- case TIFF_FLOAT:
+- {
+- float v = (float)va_arg(ap, double);
+- _TIFFmemcpy(val, &v, tv_size);
+- }
+- break;
+- case TIFF_DOUBLE:
+- {
+- double v = va_arg(ap, double);
+- _TIFFmemcpy(val, &v, tv_size);
+- }
+- break;
+- default:
+- _TIFFmemset(val, 0, tv_size);
+- status = 0;
+- break;
++ switch (fip->field_type) {
++ case TIFF_BYTE:
++ case TIFF_UNDEFINED:
++ {
++ uint8 v = (uint8)va_arg(ap, int);
++ _TIFFmemcpy(val, &v, tv_size);
++ }
++ break;
++ case TIFF_SBYTE:
++ {
++ int8 v = (int8)va_arg(ap, int);
++ _TIFFmemcpy(val, &v, tv_size);
++ }
++ break;
++ case TIFF_SHORT:
++ {
++ uint16 v = (uint16)va_arg(ap, int);
++ _TIFFmemcpy(val, &v, tv_size);
++ }
++ break;
++ case TIFF_SSHORT:
++ {
++ int16 v = (int16)va_arg(ap, int);
++ _TIFFmemcpy(val, &v, tv_size);
++ }
++ break;
++ case TIFF_LONG:
++ case TIFF_IFD:
++ {
++ uint32 v = va_arg(ap, uint32);
++ _TIFFmemcpy(val, &v, tv_size);
++ }
++ break;
++ case TIFF_SLONG:
++ {
++ int32 v = va_arg(ap, int32);
++ _TIFFmemcpy(val, &v, tv_size);
++ }
++ break;
++ case TIFF_RATIONAL:
++ case TIFF_SRATIONAL:
++ case TIFF_FLOAT:
++ {
++ float v = (float)va_arg(ap, double);
++ _TIFFmemcpy(val, &v, tv_size);
++ }
++ break;
++ case TIFF_DOUBLE:
++ {
++ double v = va_arg(ap, double);
++ _TIFFmemcpy(val, &v, tv_size);
++ }
++ break;
++ default:
++ _TIFFmemset(val, 0, tv_size);
++ status = 0;
++ break;
+ }
+ }
+ }
+ }
+- }
+ }
+ if (status) {
+ TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit);
+@@ -868,75 +864,76 @@
+ *va_arg(ap, uint16*) = (uint16)tv->count;
+ *va_arg(ap, void **) = tv->value;
+ ret_val = 1;
++ } else if (fip->field_tag == TIFFTAG_DOTRANGE
++ && strcmp(fip->field_name,"DotRange") == 0) {
++ /* TODO: This is an evil exception and should not have been
++ handled this way ... likely best if we move it into
++ the directory structure with an explicit field in
++ libtiff 4.1 and assign it a FIELD_ value */
++ *va_arg(ap, uint16*) = ((uint16 *)tv->value)[0];
++ *va_arg(ap, uint16*) = ((uint16 *)tv->value)[1];
++ ret_val = 1;
+ } else {
+- if ((fip->field_type == TIFF_ASCII
++ if (fip->field_type == TIFF_ASCII
+ || fip->field_readcount == TIFF_VARIABLE
+ || fip->field_readcount == TIFF_VARIABLE2
+ || fip->field_readcount == TIFF_SPP
+- || tv->count > 1)
+- && fip->field_tag != TIFFTAG_PAGENUMBER
+- && fip->field_tag != TIFFTAG_HALFTONEHINTS
+- && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
+- && fip->field_tag != TIFFTAG_DOTRANGE) {
++ || tv->count > 1) {
+ *va_arg(ap, void **) = tv->value;
+ ret_val = 1;
+ } else {
+- int j;
+ char *val = (char *)tv->value;
+-
+- for (j = 0; j < tv->count;
+- j++, val += _TIFFDataSize(tv->info->field_type)) {
+- switch (fip->field_type) {
+- case TIFF_BYTE:
+- case TIFF_UNDEFINED:
+- *va_arg(ap, uint8*) =
+- *(uint8 *)val;
+- ret_val = 1;
+- break;
+- case TIFF_SBYTE:
+- *va_arg(ap, int8*) =
+- *(int8 *)val;
+- ret_val = 1;
+- break;
+- case TIFF_SHORT:
+- *va_arg(ap, uint16*) =
+- *(uint16 *)val;
+- ret_val = 1;
+- break;
+- case TIFF_SSHORT:
+- *va_arg(ap, int16*) =
+- *(int16 *)val;
+- ret_val = 1;
+- break;
+- case TIFF_LONG:
+- case TIFF_IFD:
+- *va_arg(ap, uint32*) =
+- *(uint32 *)val;
+- ret_val = 1;
+- break;
+- case TIFF_SLONG:
+- *va_arg(ap, int32*) =
+- *(int32 *)val;
+- ret_val = 1;
+- break;
+- case TIFF_RATIONAL:
+- case TIFF_SRATIONAL:
+- case TIFF_FLOAT:
+- *va_arg(ap, float*) =
+- *(float *)val;
+- ret_val = 1;
+- break;
+- case TIFF_DOUBLE:
+- *va_arg(ap, double*) =
+- *(double *)val;
+- ret_val = 1;
+- break;
+- default:
+- ret_val = 0;
+- break;
+- }
+- }
+- }
++ assert( tv->count == 1 );
++ switch (fip->field_type) {
++ case TIFF_BYTE:
++ case TIFF_UNDEFINED:
++ *va_arg(ap, uint8*) =
++ *(uint8 *)val;
++ ret_val = 1;
++ break;
++ case TIFF_SBYTE:
++ *va_arg(ap, int8*) =
++ *(int8 *)val;
++ ret_val = 1;
++ break;
++ case TIFF_SHORT:
++ *va_arg(ap, uint16*) =
++ *(uint16 *)val;
++ ret_val = 1;
++ break;
++ case TIFF_SSHORT:
++ *va_arg(ap, int16*) =
++ *(int16 *)val;
++ ret_val = 1;
++ break;
++ case TIFF_LONG:
++ case TIFF_IFD:
++ *va_arg(ap, uint32*) =
++ *(uint32 *)val;
++ ret_val = 1;
++ break;
++ case TIFF_SLONG:
++ *va_arg(ap, int32*) =
++ *(int32 *)val;
++ ret_val = 1;
++ break;
++ case TIFF_RATIONAL:
++ case TIFF_SRATIONAL:
++ case TIFF_FLOAT:
++ *va_arg(ap, float*) =
++ *(float *)val;
++ ret_val = 1;
++ break;
++ case TIFF_DOUBLE:
++ *va_arg(ap, double*) =
++ *(double *)val;
++ ret_val = 1;
++ break;
++ default:
++ ret_val = 0;
++ break;
++ }
++ }
+ }
+ break;
+ }