patch-process_c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. $OpenBSD: patch-process_c,v 1.3 2017/03/23 17:26:17 bluhm Exp $
  2. Fix: handle the PKWare verification bit of internal attributes
  3. https://bugs.debian.org/630078
  4. Fix: extraction of symlinks
  5. Fix CVE-2014-8141: out-of-bounds read issues in getZip64Data()
  6. Fix: do not ignore extra fields containing Unix Timestamps
  7. https://bugs.debian.org/842993
  8. Fix: restore uid and gid information when requested
  9. https://bugs.debian.org/689212
  10. --- process.c.orig Fri Mar 6 02:25:10 2009
  11. +++ process.c Tue Mar 21 16:10:27 2017
  12. @@ -1,5 +1,5 @@
  13. /*
  14. - Copyright (c) 1990-2009 Info-ZIP. All rights reserved.
  15. + Copyright (c) 1990-2014 Info-ZIP. All rights reserved.
  16. See the accompanying file LICENSE, version 2009-Jan-02 or later
  17. (the contents of which are also included in unzip.h) for terms of use.
  18. @@ -1729,6 +1729,13 @@ int process_cdir_file_hdr(__G) /* return PK-type er
  19. else if (uO.L_flag > 1) /* let -LL force lower case for all names */
  20. G.pInfo->lcflag = 1;
  21. + /* Handle the PKWare verification bit, bit 2 (0x0004) of internal
  22. + attributes. If this is set, then a verification checksum is in the
  23. + first 3 bytes of the external attributes. In this case all we can use
  24. + for setting file attributes is the last external attributes byte. */
  25. + if (G.crec.internal_file_attributes & 0x0004)
  26. + G.crec.external_file_attributes &= (ulg)0xff;
  27. +
  28. /* do Amigas (AMIGA_) also have volume labels? */
  29. if (IS_VOLID(G.crec.external_file_attributes) &&
  30. (G.pInfo->hostnum == FS_FAT_ || G.pInfo->hostnum == FS_HPFS_ ||
  31. @@ -1751,6 +1758,12 @@ int process_cdir_file_hdr(__G) /* return PK-type er
  32. = (G.crec.general_purpose_bit_flag & (1 << 11)) == (1 << 11);
  33. #endif
  34. +#ifdef SYMLINKS
  35. + /* Initialize the symlink flag, may be set by the platform-specific
  36. + mapattr function. */
  37. + G.pInfo->symlink = 0;
  38. +#endif
  39. +
  40. return PK_COOL;
  41. } /* end function process_cdir_file_hdr() */
  42. @@ -1888,48 +1901,82 @@ int getZip64Data(__G__ ef_buf, ef_len)
  43. and a 4-byte version of disk start number.
  44. Sets both local header and central header fields. Not terribly clever,
  45. but it means that this procedure is only called in one place.
  46. +
  47. + 2014-12-05 SMS.
  48. + Added checks to ensure that enough data are available before calling
  49. + makeint64() or makelong(). Replaced various sizeof() values with
  50. + simple ("4" or "8") constants. (The Zip64 structures do not depend
  51. + on our variable sizes.) Error handling is crude, but we should now
  52. + stay within the buffer.
  53. ---------------------------------------------------------------------------*/
  54. +#define Z64FLGS 0xffff
  55. +#define Z64FLGL 0xffffffff
  56. +
  57. if (ef_len == 0 || ef_buf == NULL)
  58. return PK_COOL;
  59. Trace((stderr,"\ngetZip64Data: scanning extra field of length %u\n",
  60. ef_len));
  61. - while (ef_len >= EB_HEADSIZE) {
  62. + while (ef_len >= EB_HEADSIZE)
  63. + {
  64. eb_id = makeword(EB_ID + ef_buf);
  65. eb_len = makeword(EB_LEN + ef_buf);
  66. - if (eb_len > (ef_len - EB_HEADSIZE)) {
  67. - /* discovered some extra field inconsistency! */
  68. + if (eb_len > (ef_len - EB_HEADSIZE))
  69. + {
  70. + /* Extra block length exceeds remaining extra field length. */
  71. Trace((stderr,
  72. "getZip64Data: block length %u > rest ef_size %u\n", eb_len,
  73. ef_len - EB_HEADSIZE));
  74. break;
  75. }
  76. - if (eb_id == EF_PKSZ64) {
  77. -
  78. + if (eb_id == EF_PKSZ64)
  79. + {
  80. int offset = EB_HEADSIZE;
  81. - if (G.crec.ucsize == 0xffffffff || G.lrec.ucsize == 0xffffffff){
  82. - G.lrec.ucsize = G.crec.ucsize = makeint64(offset + ef_buf);
  83. - offset += sizeof(G.crec.ucsize);
  84. + if ((G.crec.ucsize == Z64FLGL) || (G.lrec.ucsize == Z64FLGL))
  85. + {
  86. + if (offset+ 8 > ef_len)
  87. + return PK_ERR;
  88. +
  89. + G.crec.ucsize = G.lrec.ucsize = makeint64(offset + ef_buf);
  90. + offset += 8;
  91. }
  92. - if (G.crec.csize == 0xffffffff || G.lrec.csize == 0xffffffff){
  93. - G.csize = G.lrec.csize = G.crec.csize = makeint64(offset + ef_buf);
  94. - offset += sizeof(G.crec.csize);
  95. +
  96. + if ((G.crec.csize == Z64FLGL) || (G.lrec.csize == Z64FLGL))
  97. + {
  98. + if (offset+ 8 > ef_len)
  99. + return PK_ERR;
  100. +
  101. + G.csize = G.crec.csize = G.lrec.csize = makeint64(offset + ef_buf);
  102. + offset += 8;
  103. }
  104. - if (G.crec.relative_offset_local_header == 0xffffffff){
  105. +
  106. + if (G.crec.relative_offset_local_header == Z64FLGL)
  107. + {
  108. + if (offset+ 8 > ef_len)
  109. + return PK_ERR;
  110. +
  111. G.crec.relative_offset_local_header = makeint64(offset + ef_buf);
  112. - offset += sizeof(G.crec.relative_offset_local_header);
  113. + offset += 8;
  114. }
  115. - if (G.crec.disk_number_start == 0xffff){
  116. +
  117. + if (G.crec.disk_number_start == Z64FLGS)
  118. + {
  119. + if (offset+ 4 > ef_len)
  120. + return PK_ERR;
  121. +
  122. G.crec.disk_number_start = (zuvl_t)makelong(offset + ef_buf);
  123. - offset += sizeof(G.crec.disk_number_start);
  124. + offset += 4;
  125. }
  126. +#if 0
  127. + break; /* Expect only one EF_PKSZ64 block. */
  128. +#endif /* 0 */
  129. }
  130. - /* Skip this extra field block */
  131. + /* Skip this extra field block. */
  132. ef_buf += (eb_len + EB_HEADSIZE);
  133. ef_len -= (eb_len + EB_HEADSIZE);
  134. }
  135. @@ -2867,10 +2914,13 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos
  136. break;
  137. case EF_IZUNIX2:
  138. - if (have_new_type_eb == 0) {
  139. - flags &= ~0x0ff; /* ignore any previous IZUNIX field */
  140. + if (have_new_type_eb == 0) { /* (< 1) */
  141. have_new_type_eb = 1;
  142. }
  143. + if (have_new_type_eb <= 1) {
  144. + /* Ignore any prior (EF_IZUNIX/EF_PKUNIX) UID/GID. */
  145. + flags &= 0x0ff;
  146. + }
  147. #ifdef IZ_HAVE_UXUIDGID
  148. if (have_new_type_eb > 1)
  149. break; /* IZUNIX3 overrides IZUNIX2 e.f. block ! */
  150. @@ -2886,6 +2936,8 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos
  151. /* new 3rd generation Unix ef */
  152. have_new_type_eb = 2;
  153. + /* Ignore any prior EF_IZUNIX/EF_PKUNIX/EF_IZUNIX2 UID/GID. */
  154. + flags &= 0x0ff;
  155. /*
  156. Version 1 byte version of this extra field, currently 1
  157. UIDSize 1 byte Size of UID field
  158. @@ -2897,7 +2949,7 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos
  159. #ifdef IZ_HAVE_UXUIDGID
  160. if (eb_len >= EB_UX3_MINLEN
  161. && z_uidgid != NULL
  162. - && (*((EB_HEADSIZE + 0) + ef_buf) == 1)
  163. + && (*((EB_HEADSIZE + 0) + ef_buf) == 1))
  164. /* only know about version 1 */
  165. {
  166. uch uid_size;
  167. @@ -2906,13 +2958,11 @@ unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c, dos
  168. uid_size = *((EB_HEADSIZE + 1) + ef_buf);
  169. gid_size = *((EB_HEADSIZE + uid_size + 2) + ef_buf);
  170. - flags &= ~0x0ff; /* ignore any previous UNIX field */
  171. -
  172. if ( read_ux3_value((EB_HEADSIZE + 2) + ef_buf,
  173. - uid_size, z_uidgid[0])
  174. + uid_size, &z_uidgid[0])
  175. &&
  176. read_ux3_value((EB_HEADSIZE + uid_size + 3) + ef_buf,
  177. - gid_size, z_uidgid[1]) )
  178. + gid_size, &z_uidgid[1]) )
  179. {
  180. flags |= EB_UX2_VALID; /* signal success */
  181. }