From 53a3abdb3fcd0fdbbe9c530f95ac762bb7e99604 Mon Sep 17 00:00:00 2001 From: Natanael Copa Date: Thu, 17 Jan 2013 15:18:59 +0000 Subject: main/tiff: fix CVE-2012-5581 fixes #1559 --- main/tiff/APKBUILD | 6 +- main/tiff/CVE-2012-5581.patch | 311 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 315 insertions(+), 2 deletions(-) create mode 100644 main/tiff/CVE-2012-5581.patch diff --git a/main/tiff/APKBUILD b/main/tiff/APKBUILD index fe21fd3648..33bab1eabc 100644 --- a/main/tiff/APKBUILD +++ b/main/tiff/APKBUILD @@ -2,7 +2,7 @@ # Maintainer: Michael Mason pkgname=tiff pkgver=3.9.6 -pkgrel=1 +pkgrel=2 pkgdesc="Provides support for the Tag Image File Format or TIFF" url="http://www.libtiff.org/" license="GPL" @@ -13,6 +13,7 @@ subpackages="$pkgname-doc $pkgname-dev" source="ftp://ftp.remotesensing.org/pub/libtiff/$pkgname-$pkgver.tar.gz libtiff-negsize-3.9.patch CVE-2012-3401.patch + CVE-2012-5581.patch " _builddir="$srcdir"/$pkgname-$pkgver @@ -45,4 +46,5 @@ package() { md5sums="6920f3bf628d791d49f268b83612ed23 tiff-3.9.6.tar.gz a0742e7c81551c51438a8d6fa5d68676 libtiff-negsize-3.9.patch -8c862de25b906d3fcefce2fb06c7b604 CVE-2012-3401.patch" +8c862de25b906d3fcefce2fb06c7b604 CVE-2012-3401.patch +f0eff2b15675a00dd4d4a230b88f1f59 CVE-2012-5581.patch" 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; + } -- cgit v1.2.3