cherry-pick.FILE5_30-28-g393555f2.try-to-clean-this-up-the-vector-code-is-still-fishy.patch 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. Subject: Try to clean this up; the vector code is still fishy
  2. Origin: FILE5_30-28-g393555f2
  3. Upstream-Author: Christos Zoulas <christos@zoulas.com>
  4. Date: Mon Mar 27 20:58:11 2017 +0000
  5. [ Also contains the spello fix FILE5_30-10-ga25f230f -CB ]
  6. --- a/src/cdf.c
  7. +++ b/src/cdf.c
  8. @@ -818,6 +818,66 @@
  9. return 0;
  10. }
  11. +#define CDF_SHLEN_LIMIT (UINT32_MAX / 8)
  12. +#define CDF_PROP_LIMIT (UINT32_MAX / (4 * sizeof(cdf_property_info_t)))
  13. +
  14. +static const void *
  15. +cdf_offset(const void *p, size_t l)
  16. +{
  17. + return CAST(const void *, CAST(const uint8_t *, p) + l);
  18. +}
  19. +
  20. +static const uint8_t *
  21. +cdf_get_property_info_pos(const cdf_stream_t *sst, const cdf_header_t *h,
  22. + const uint8_t *p, const uint8_t *e, size_t i)
  23. +{
  24. + size_t tail = (i << 1) + 1;
  25. + size_t ofs;
  26. + const uint8_t *q;
  27. +
  28. + if (cdf_check_stream_offset(sst, h, p, tail * sizeof(uint32_t),
  29. + __LINE__) == -1)
  30. + return NULL;
  31. + ofs = CDF_GETUINT32(p, tail);
  32. + q = CAST(const uint8_t *, cdf_offset(CAST(const void *, p),
  33. + ofs - 2 * sizeof(uint32_t)));
  34. +
  35. + if (q < p) {
  36. + DPRINTF(("Wrapped around %p < %p\n", q, p));
  37. + return NULL;
  38. + }
  39. +
  40. + if (q >= e) {
  41. + DPRINTF(("Ran off the end %p >= %p\n", q, e));
  42. + return NULL;
  43. + }
  44. + return q;
  45. +}
  46. +
  47. +static cdf_property_info_t *
  48. +cdf_grow_info(cdf_property_info_t **info, size_t *maxcount, size_t incr)
  49. +{
  50. + cdf_property_info_t *inp;
  51. + size_t newcount = *maxcount + incr;
  52. +
  53. + if (newcount > CDF_PROP_LIMIT)
  54. + goto out;
  55. +
  56. + inp = CAST(cdf_property_info_t *,
  57. + realloc(*info, newcount * sizeof(*inp)));
  58. + if (inp == NULL)
  59. + goto out;
  60. +
  61. + *info = inp;
  62. + *maxcount = newcount;
  63. + return inp;
  64. +out:
  65. + free(*info);
  66. + *maxcount = 0;
  67. + *info = NULL;
  68. + return NULL;
  69. +}
  70. +
  71. int
  72. cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h,
  73. uint32_t offs, cdf_property_info_t **info, size_t *count, size_t *maxcount)
  74. @@ -831,70 +891,40 @@
  75. int64_t s64;
  76. uint64_t u64;
  77. cdf_timestamp_t tp;
  78. - size_t i, o, o4, nelements, j;
  79. + size_t i, o4, nelements, j, slen;
  80. cdf_property_info_t *inp;
  81. if (offs > UINT32_MAX / 4) {
  82. errno = EFTYPE;
  83. goto out;
  84. }
  85. - shp = CAST(const cdf_section_header_t *, (const void *)
  86. - ((const char *)sst->sst_tab + offs));
  87. + shp = CAST(const cdf_section_header_t *,
  88. + cdf_offset(sst->sst_tab, offs));
  89. if (cdf_check_stream_offset(sst, h, shp, sizeof(*shp), __LINE__) == -1)
  90. goto out;
  91. sh.sh_len = CDF_TOLE4(shp->sh_len);
  92. -#define CDF_SHLEN_LIMIT (UINT32_MAX / 8)
  93. if (sh.sh_len > CDF_SHLEN_LIMIT) {
  94. errno = EFTYPE;
  95. goto out;
  96. }
  97. sh.sh_properties = CDF_TOLE4(shp->sh_properties);
  98. -#define CDF_PROP_LIMIT (UINT32_MAX / (4 * sizeof(*inp)))
  99. if (sh.sh_properties > CDF_PROP_LIMIT)
  100. goto out;
  101. DPRINTF(("section len: %u properties %u\n", sh.sh_len,
  102. sh.sh_properties));
  103. - if (*maxcount) {
  104. - if (*maxcount > CDF_PROP_LIMIT)
  105. - goto out;
  106. - *maxcount += sh.sh_properties;
  107. - inp = CAST(cdf_property_info_t *,
  108. - realloc(*info, *maxcount * sizeof(*inp)));
  109. - } else {
  110. - *maxcount = sh.sh_properties;
  111. - inp = CAST(cdf_property_info_t *,
  112. - malloc(*maxcount * sizeof(*inp)));
  113. - }
  114. + inp = cdf_grow_info(info, maxcount, sh.sh_properties);
  115. if (inp == NULL)
  116. - goto out1;
  117. - *info = inp;
  118. + goto out;
  119. inp += *count;
  120. *count += sh.sh_properties;
  121. - p = CAST(const uint8_t *, (const void *)
  122. - ((const char *)(const void *)sst->sst_tab +
  123. - offs + sizeof(sh)));
  124. - e = CAST(const uint8_t *, (const void *)
  125. - (((const char *)(const void *)shp) + sh.sh_len));
  126. + p = CAST(const uint8_t *, cdf_offset(sst->sst_tab, offs + sizeof(sh)));
  127. + e = CAST(const uint8_t *, cdf_offset(shp, sh.sh_len));
  128. if (cdf_check_stream_offset(sst, h, e, 0, __LINE__) == -1)
  129. goto out;
  130. +
  131. for (i = 0; i < sh.sh_properties; i++) {
  132. - size_t tail = (i << 1) + 1;
  133. - size_t ofs;
  134. - if (cdf_check_stream_offset(sst, h, p, tail * sizeof(uint32_t),
  135. - __LINE__) == -1)
  136. - goto out;
  137. - ofs = CDF_GETUINT32(p, tail);
  138. - q = (const uint8_t *)(const void *)
  139. - ((const char *)(const void *)p + ofs
  140. - - 2 * sizeof(uint32_t));
  141. - if (q < p) {
  142. - DPRINTF(("Wrapped around %p < %p\n", q, p));
  143. - goto out;
  144. - }
  145. - if (q >= e) {
  146. - DPRINTF(("Ran of the end %p >= %p\n", q, e));
  147. + if ((q = cdf_get_property_info_pos(sst, h, p, e, i)) == NULL)
  148. goto out;
  149. - }
  150. inp[i].pi_id = CDF_GETUINT32(p, i << 1);
  151. inp[i].pi_type = CDF_GETUINT32(q, 0);
  152. DPRINTF(("%" SIZE_T_FORMAT "u) id=%x type=%x offs=0x%tx,0x%x\n",
  153. @@ -905,12 +935,12 @@
  154. DPRINTF(("CDF_VECTOR with nelements == 0\n"));
  155. goto out;
  156. }
  157. - o = 2;
  158. + slen = 2;
  159. } else {
  160. nelements = 1;
  161. - o = 1;
  162. + slen = 1;
  163. }
  164. - o4 = o * sizeof(uint32_t);
  165. + o4 = slen * sizeof(uint32_t);
  166. if (inp[i].pi_type & (CDF_ARRAY|CDF_BYREF|CDF_RESERVED))
  167. goto unknown;
  168. switch (inp[i].pi_type & CDF_TYPEMASK) {
  169. @@ -966,16 +996,10 @@
  170. case CDF_LENGTH32_WSTRING:
  171. if (nelements > 1) {
  172. size_t nelem = inp - *info;
  173. - if (*maxcount > CDF_PROP_LIMIT
  174. - || nelements > CDF_PROP_LIMIT)
  175. - goto out;
  176. - *maxcount += nelements;
  177. - inp = CAST(cdf_property_info_t *,
  178. - realloc(*info, *maxcount * sizeof(*inp)));
  179. + inp = cdf_grow_info(info, maxcount, nelements);
  180. if (inp == NULL)
  181. - goto out1;
  182. - *info = inp;
  183. - inp = *info + nelem;
  184. + goto out;
  185. + inp += nelem;
  186. }
  187. DPRINTF(("nelements = %" SIZE_T_FORMAT "u\n",
  188. nelements));
  189. @@ -984,28 +1008,28 @@
  190. {
  191. uint32_t l;
  192. - if (q + o + sizeof(uint32_t) >= e)
  193. + if (q + slen + sizeof(uint32_t) >= e)
  194. goto out;
  195. - l = CDF_GETUINT32(q, o);
  196. + l = CDF_GETUINT32(q, slen);
  197. o4 += sizeof(uint32_t);
  198. - if (q + o4 + l >= e)
  199. + if (o4 + l > CAST(size_t, e - q))
  200. goto out;
  201. inp[i].pi_str.s_len = l;
  202. inp[i].pi_str.s_buf = CAST(const char *,
  203. CAST(const void *, &q[o4]));
  204. - DPRINTF(("l = %d, r = %" SIZE_T_FORMAT
  205. - "u, s = %s\n", l,
  206. - CDF_ROUND(l, sizeof(l)),
  207. + DPRINTF(("o=%zu l=%d(%" SIZE_T_FORMAT
  208. + "u), t=%td s=%s\n", o4, l,
  209. + CDF_ROUND(l, sizeof(l)), e - q,
  210. inp[i].pi_str.s_buf));
  211. if (l & 1)
  212. l++;
  213. - o += l >> 1;
  214. - o4 = o * sizeof(uint32_t);
  215. + slen += l >> 1;
  216. + o4 = slen * sizeof(uint32_t);
  217. }
  218. i--;
  219. break;
  220. @@ -1029,8 +1053,6 @@
  221. return 0;
  222. out:
  223. errno = EFTYPE;
  224. -out1:
  225. - free(*info);
  226. return -1;
  227. }