161e87d12167b1e36193385485c1f6ce92f74f02.patch 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. From: Alan Modra <amodra@gmail.com>
  2. Date: Wed, 15 Dec 2021 01:18:42 +0000 (+1030)
  3. Subject: PR28694, Out-of-bounds write in stab_xcoff_builtin_type
  4. CVE: CVE-2021-45078
  5. Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff_plain;h=161e87d12167b1e36193385485c1f6ce92f74f02]
  6. PR28694, Out-of-bounds write in stab_xcoff_builtin_type
  7. PR 28694
  8. * stabs.c (stab_xcoff_builtin_type): Make typenum unsigned.
  9. Negate typenum earlier, simplifying bounds checking. Correct
  10. off-by-one indexing. Adjust switch cases.
  11. ---
  12. diff --git a/binutils/stabs.c b/binutils/stabs.c
  13. index 274bfb0e7fa..83ee3ea5fa4 100644
  14. --- a/binutils/stabs.c
  15. +++ b/binutils/stabs.c
  16. @@ -202,7 +202,7 @@ static debug_type stab_find_type (void *, struct stab_handle *, const int *);
  17. static bool stab_record_type
  18. (void *, struct stab_handle *, const int *, debug_type);
  19. static debug_type stab_xcoff_builtin_type
  20. - (void *, struct stab_handle *, int);
  21. + (void *, struct stab_handle *, unsigned int);
  22. static debug_type stab_find_tagged_type
  23. (void *, struct stab_handle *, const char *, int, enum debug_type_kind);
  24. static debug_type *stab_demangle_argtypes
  25. @@ -3496,166 +3496,167 @@ stab_record_type (void *dhandle ATTRIBUTE_UNUSED, struct stab_handle *info,
  26. static debug_type
  27. stab_xcoff_builtin_type (void *dhandle, struct stab_handle *info,
  28. - int typenum)
  29. + unsigned int typenum)
  30. {
  31. debug_type rettype;
  32. const char *name;
  33. - if (typenum >= 0 || typenum < -XCOFF_TYPE_COUNT)
  34. + typenum = -typenum - 1;
  35. + if (typenum >= XCOFF_TYPE_COUNT)
  36. {
  37. - fprintf (stderr, _("Unrecognized XCOFF type %d\n"), typenum);
  38. + fprintf (stderr, _("Unrecognized XCOFF type %d\n"), -typenum - 1);
  39. return DEBUG_TYPE_NULL;
  40. }
  41. - if (info->xcoff_types[-typenum] != NULL)
  42. - return info->xcoff_types[-typenum];
  43. + if (info->xcoff_types[typenum] != NULL)
  44. + return info->xcoff_types[typenum];
  45. - switch (-typenum)
  46. + switch (typenum)
  47. {
  48. - case 1:
  49. + case 0:
  50. /* The size of this and all the other types are fixed, defined
  51. by the debugging format. */
  52. name = "int";
  53. rettype = debug_make_int_type (dhandle, 4, false);
  54. break;
  55. - case 2:
  56. + case 1:
  57. name = "char";
  58. rettype = debug_make_int_type (dhandle, 1, false);
  59. break;
  60. - case 3:
  61. + case 2:
  62. name = "short";
  63. rettype = debug_make_int_type (dhandle, 2, false);
  64. break;
  65. - case 4:
  66. + case 3:
  67. name = "long";
  68. rettype = debug_make_int_type (dhandle, 4, false);
  69. break;
  70. - case 5:
  71. + case 4:
  72. name = "unsigned char";
  73. rettype = debug_make_int_type (dhandle, 1, true);
  74. break;
  75. - case 6:
  76. + case 5:
  77. name = "signed char";
  78. rettype = debug_make_int_type (dhandle, 1, false);
  79. break;
  80. - case 7:
  81. + case 6:
  82. name = "unsigned short";
  83. rettype = debug_make_int_type (dhandle, 2, true);
  84. break;
  85. - case 8:
  86. + case 7:
  87. name = "unsigned int";
  88. rettype = debug_make_int_type (dhandle, 4, true);
  89. break;
  90. - case 9:
  91. + case 8:
  92. name = "unsigned";
  93. rettype = debug_make_int_type (dhandle, 4, true);
  94. break;
  95. - case 10:
  96. + case 9:
  97. name = "unsigned long";
  98. rettype = debug_make_int_type (dhandle, 4, true);
  99. break;
  100. - case 11:
  101. + case 10:
  102. name = "void";
  103. rettype = debug_make_void_type (dhandle);
  104. break;
  105. - case 12:
  106. + case 11:
  107. /* IEEE single precision (32 bit). */
  108. name = "float";
  109. rettype = debug_make_float_type (dhandle, 4);
  110. break;
  111. - case 13:
  112. + case 12:
  113. /* IEEE double precision (64 bit). */
  114. name = "double";
  115. rettype = debug_make_float_type (dhandle, 8);
  116. break;
  117. - case 14:
  118. + case 13:
  119. /* This is an IEEE double on the RS/6000, and different machines
  120. with different sizes for "long double" should use different
  121. negative type numbers. See stabs.texinfo. */
  122. name = "long double";
  123. rettype = debug_make_float_type (dhandle, 8);
  124. break;
  125. - case 15:
  126. + case 14:
  127. name = "integer";
  128. rettype = debug_make_int_type (dhandle, 4, false);
  129. break;
  130. - case 16:
  131. + case 15:
  132. name = "boolean";
  133. rettype = debug_make_bool_type (dhandle, 4);
  134. break;
  135. - case 17:
  136. + case 16:
  137. name = "short real";
  138. rettype = debug_make_float_type (dhandle, 4);
  139. break;
  140. - case 18:
  141. + case 17:
  142. name = "real";
  143. rettype = debug_make_float_type (dhandle, 8);
  144. break;
  145. - case 19:
  146. + case 18:
  147. /* FIXME */
  148. name = "stringptr";
  149. rettype = NULL;
  150. break;
  151. - case 20:
  152. + case 19:
  153. /* FIXME */
  154. name = "character";
  155. rettype = debug_make_int_type (dhandle, 1, true);
  156. break;
  157. - case 21:
  158. + case 20:
  159. name = "logical*1";
  160. rettype = debug_make_bool_type (dhandle, 1);
  161. break;
  162. - case 22:
  163. + case 21:
  164. name = "logical*2";
  165. rettype = debug_make_bool_type (dhandle, 2);
  166. break;
  167. - case 23:
  168. + case 22:
  169. name = "logical*4";
  170. rettype = debug_make_bool_type (dhandle, 4);
  171. break;
  172. - case 24:
  173. + case 23:
  174. name = "logical";
  175. rettype = debug_make_bool_type (dhandle, 4);
  176. break;
  177. - case 25:
  178. + case 24:
  179. /* Complex type consisting of two IEEE single precision values. */
  180. name = "complex";
  181. rettype = debug_make_complex_type (dhandle, 8);
  182. break;
  183. - case 26:
  184. + case 25:
  185. /* Complex type consisting of two IEEE double precision values. */
  186. name = "double complex";
  187. rettype = debug_make_complex_type (dhandle, 16);
  188. break;
  189. - case 27:
  190. + case 26:
  191. name = "integer*1";
  192. rettype = debug_make_int_type (dhandle, 1, false);
  193. break;
  194. - case 28:
  195. + case 27:
  196. name = "integer*2";
  197. rettype = debug_make_int_type (dhandle, 2, false);
  198. break;
  199. - case 29:
  200. + case 28:
  201. name = "integer*4";
  202. rettype = debug_make_int_type (dhandle, 4, false);
  203. break;
  204. - case 30:
  205. + case 29:
  206. /* FIXME */
  207. name = "wchar";
  208. rettype = debug_make_int_type (dhandle, 2, false);
  209. break;
  210. - case 31:
  211. + case 30:
  212. name = "long long";
  213. rettype = debug_make_int_type (dhandle, 8, false);
  214. break;
  215. - case 32:
  216. + case 31:
  217. name = "unsigned long long";
  218. rettype = debug_make_int_type (dhandle, 8, true);
  219. break;
  220. - case 33:
  221. + case 32:
  222. name = "logical*8";
  223. rettype = debug_make_bool_type (dhandle, 8);
  224. break;
  225. - case 34:
  226. + case 33:
  227. name = "integer*8";
  228. rettype = debug_make_int_type (dhandle, 8, false);
  229. break;
  230. @@ -3664,9 +3665,7 @@ stab_xcoff_builtin_type (void *dhandle, struct stab_handle *info,
  231. }
  232. rettype = debug_name_type (dhandle, name, rettype);
  233. -
  234. - info->xcoff_types[-typenum] = rettype;
  235. -
  236. + info->xcoff_types[typenum] = rettype;
  237. return rettype;
  238. }