You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

164 lines
6.8 KiB

  1. From e1cd2d7ab032e7fe80b4c13e07895194c8bac85e Mon Sep 17 00:00:00 2001
  2. From: Brian May <brian@linuxpenguins.xyz>
  3. Date: Thu, 7 Dec 2017 07:46:47 +1100
  4. Subject: [PATCH 1/4] [PATCH] tiff2pdf: Fix CVE-2017-9935
  5. Fix for http://bugzilla.maptools.org/show_bug.cgi?id=2704
  6. This vulnerability - at least for the supplied test case - is because we
  7. assume that a tiff will only have one transfer function that is the same
  8. for all pages. This is not required by the TIFF standards.
  9. We than read the transfer function for every page. Depending on the
  10. transfer function, we allocate either 2 or 4 bytes to the XREF buffer.
  11. We allocate this memory after we read in the transfer function for the
  12. page.
  13. For the first exploit - POC1, this file has 3 pages. For the first page
  14. we allocate 2 extra extra XREF entries. Then for the next page 2 more
  15. entries. Then for the last page the transfer function changes and we
  16. allocate 4 more entries.
  17. When we read the file into memory, we assume we have 4 bytes extra for
  18. each and every page (as per the last transfer function we read). Which
  19. is not correct, we only have 2 bytes extra for the first 2 pages. As a
  20. result, we end up writing past the end of the buffer.
  21. There are also some related issues that this also fixes. For example,
  22. TIFFGetField can return uninitalized pointer values, and the logic to
  23. detect a N=3 vs N=1 transfer function seemed rather strange.
  24. It is also strange that we declare the transfer functions to be of type
  25. float, when the standard says they are unsigned 16 bit values. This is
  26. fixed in another patch.
  27. This patch will check to ensure that the N value for every transfer
  28. function is the same for every page. If this changes, we abort with an
  29. error. In theory, we should perhaps check that the transfer function
  30. itself is identical for every page, however we don't do that due to the
  31. confusion of the type of the data in the transfer function.
  32. ---
  33. libtiff/tif_dir.c | 3 +++
  34. tools/tiff2pdf.c | 69 +++++++++++++++++++++++++++++++----------------
  35. 2 files changed, 49 insertions(+), 23 deletions(-)
  36. diff --git a/libtiff/tif_dir.c b/libtiff/tif_dir.c
  37. index f00f808..c36a5f3 100644
  38. --- a/libtiff/tif_dir.c
  39. +++ b/libtiff/tif_dir.c
  40. @@ -1067,6 +1067,9 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
  41. if (td->td_samplesperpixel - td->td_extrasamples > 1) {
  42. *va_arg(ap, uint16**) = td->td_transferfunction[1];
  43. *va_arg(ap, uint16**) = td->td_transferfunction[2];
  44. + } else {
  45. + *va_arg(ap, uint16**) = NULL;
  46. + *va_arg(ap, uint16**) = NULL;
  47. }
  48. break;
  49. case TIFFTAG_REFERENCEBLACKWHITE:
  50. diff --git a/tools/tiff2pdf.c b/tools/tiff2pdf.c
  51. index bdb9126..bd23c9e 100644
  52. --- a/tools/tiff2pdf.c
  53. +++ b/tools/tiff2pdf.c
  54. @@ -239,7 +239,7 @@ typedef struct {
  55. float tiff_whitechromaticities[2];
  56. float tiff_primarychromaticities[6];
  57. float tiff_referenceblackwhite[2];
  58. - float* tiff_transferfunction[3];
  59. + uint16* tiff_transferfunction[3];
  60. int pdf_image_interpolate; /* 0 (default) : do not interpolate,
  61. 1 : interpolate */
  62. uint16 tiff_transferfunctioncount;
  63. @@ -1049,6 +1049,8 @@ void t2p_read_tiff_init(T2P* t2p, TIFF* input){
  64. uint16 pagen=0;
  65. uint16 paged=0;
  66. uint16 xuint16=0;
  67. + uint16 tiff_transferfunctioncount=0;
  68. + uint16* tiff_transferfunction[3];
  69. directorycount=TIFFNumberOfDirectories(input);
  70. if(directorycount > TIFF_DIR_MAX) {
  71. @@ -1157,26 +1159,48 @@ void t2p_read_tiff_init(T2P* t2p, TIFF* input){
  72. }
  73. #endif
  74. if (TIFFGetField(input, TIFFTAG_TRANSFERFUNCTION,
  75. - &(t2p->tiff_transferfunction[0]),
  76. - &(t2p->tiff_transferfunction[1]),
  77. - &(t2p->tiff_transferfunction[2]))) {
  78. - if((t2p->tiff_transferfunction[1] != (float*) NULL) &&
  79. - (t2p->tiff_transferfunction[2] != (float*) NULL) &&
  80. - (t2p->tiff_transferfunction[1] !=
  81. - t2p->tiff_transferfunction[0])) {
  82. - t2p->tiff_transferfunctioncount = 3;
  83. - t2p->tiff_pages[i].page_extra += 4;
  84. - t2p->pdf_xrefcount += 4;
  85. - } else {
  86. - t2p->tiff_transferfunctioncount = 1;
  87. - t2p->tiff_pages[i].page_extra += 2;
  88. - t2p->pdf_xrefcount += 2;
  89. - }
  90. - if(t2p->pdf_minorversion < 2)
  91. - t2p->pdf_minorversion = 2;
  92. + &(tiff_transferfunction[0]),
  93. + &(tiff_transferfunction[1]),
  94. + &(tiff_transferfunction[2]))) {
  95. +
  96. + if((tiff_transferfunction[1] != (uint16*) NULL) &&
  97. + (tiff_transferfunction[2] != (uint16*) NULL)
  98. + ) {
  99. + tiff_transferfunctioncount=3;
  100. + } else {
  101. + tiff_transferfunctioncount=1;
  102. + }
  103. } else {
  104. - t2p->tiff_transferfunctioncount=0;
  105. + tiff_transferfunctioncount=0;
  106. }
  107. +
  108. + if (i > 0){
  109. + if (tiff_transferfunctioncount != t2p->tiff_transferfunctioncount){
  110. + TIFFError(
  111. + TIFF2PDF_MODULE,
  112. + "Different transfer function on page %d",
  113. + i);
  114. + t2p->t2p_error = T2P_ERR_ERROR;
  115. + return;
  116. + }
  117. + }
  118. +
  119. + t2p->tiff_transferfunctioncount = tiff_transferfunctioncount;
  120. + t2p->tiff_transferfunction[0] = tiff_transferfunction[0];
  121. + t2p->tiff_transferfunction[1] = tiff_transferfunction[1];
  122. + t2p->tiff_transferfunction[2] = tiff_transferfunction[2];
  123. + if(tiff_transferfunctioncount == 3){
  124. + t2p->tiff_pages[i].page_extra += 4;
  125. + t2p->pdf_xrefcount += 4;
  126. + if(t2p->pdf_minorversion < 2)
  127. + t2p->pdf_minorversion = 2;
  128. + } else if (tiff_transferfunctioncount == 1){
  129. + t2p->tiff_pages[i].page_extra += 2;
  130. + t2p->pdf_xrefcount += 2;
  131. + if(t2p->pdf_minorversion < 2)
  132. + t2p->pdf_minorversion = 2;
  133. + }
  134. +
  135. if( TIFFGetField(
  136. input,
  137. TIFFTAG_ICCPROFILE,
  138. @@ -1837,10 +1861,9 @@ void t2p_read_tiff_data(T2P* t2p, TIFF* input){
  139. &(t2p->tiff_transferfunction[0]),
  140. &(t2p->tiff_transferfunction[1]),
  141. &(t2p->tiff_transferfunction[2]))) {
  142. - if((t2p->tiff_transferfunction[1] != (float*) NULL) &&
  143. - (t2p->tiff_transferfunction[2] != (float*) NULL) &&
  144. - (t2p->tiff_transferfunction[1] !=
  145. - t2p->tiff_transferfunction[0])) {
  146. + if((t2p->tiff_transferfunction[1] != (uint16*) NULL) &&
  147. + (t2p->tiff_transferfunction[2] != (uint16*) NULL)
  148. + ) {
  149. t2p->tiff_transferfunctioncount=3;
  150. } else {
  151. t2p->tiff_transferfunctioncount=1;
  152. --
  153. 2.17.0