CVE-2014-9653.1.1231e6e.patch 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. Subject: PR/134: Don't seek all overr the place when reading elf files, homogenize (...)
  2. Upstream-Author: Christos Zoulas <christos@zoulas.com>
  3. Date: Wed Aug 17 11:34:39 2011 +0000
  4. Origin: FILE5_08-7-g1231e6e
  5. Last-Update: 2015-04-19
  6. PR/134: Don't seek all overr the place when reading elf files, homogenize
  7. the seeking to seek to the proper offset for each header structure reading
  8. instead of saving and restoring offsets in random places.
  9. (prequisite for CVE-2014-9653)
  10. --- a/src/elfclass.h
  11. +++ b/src/elfclass.h
  12. @@ -66,8 +66,7 @@
  13. if (doshn(ms, clazz, swap, fd,
  14. (off_t)elf_getu(swap, elfhdr.e_shoff), shnum,
  15. (size_t)elf_getu16(swap, elfhdr.e_shentsize),
  16. - &flags,
  17. - elf_getu16(swap, elfhdr.e_machine)) == -1)
  18. + fsize, &flags, elf_getu16(swap, elfhdr.e_machine)) == -1)
  19. return -1;
  20. break;
  21. --- a/src/readelf.c
  22. +++ b/src/readelf.c
  23. @@ -47,8 +47,8 @@
  24. #endif
  25. private int dophn_exec(struct magic_set *, int, int, int, off_t, int, size_t,
  26. off_t, int *, int);
  27. -private int doshn(struct magic_set *, int, int, int, off_t, int, size_t, int *,
  28. - int);
  29. +private int doshn(struct magic_set *, int, int, int, off_t, int, size_t,
  30. + off_t, int *, int);
  31. private size_t donote(struct magic_set *, void *, size_t, size_t, int,
  32. int, size_t, int *);
  33. @@ -156,7 +156,7 @@
  34. #define xsh_size (clazz == ELFCLASS32 \
  35. ? elf_getu32(swap, sh32.sh_size) \
  36. : elf_getu64(swap, sh64.sh_size))
  37. -#define xsh_offset (clazz == ELFCLASS32 \
  38. +#define xsh_offset (off_t)(clazz == ELFCLASS32 \
  39. ? elf_getu32(swap, sh32.sh_offset) \
  40. : elf_getu64(swap, sh64.sh_offset))
  41. #define xsh_type (clazz == ELFCLASS32 \
  42. @@ -308,13 +308,6 @@
  43. size_t offset;
  44. unsigned char nbuf[BUFSIZ];
  45. ssize_t bufsize;
  46. - off_t savedoffset;
  47. - struct stat st;
  48. -
  49. - if (fstat(fd, &st) < 0) {
  50. - file_badread(ms);
  51. - return -1;
  52. - }
  53. if (size != xph_sizeof) {
  54. if (file_printf(ms, ", corrupted program header size") == -1)
  55. @@ -326,7 +319,7 @@
  56. * Loop through all the program headers.
  57. */
  58. for ( ; num; num--) {
  59. - if ((savedoffset = lseek(fd, off, SEEK_SET)) == (off_t)-1) {
  60. + if (lseek(fd, off, SEEK_SET) == (off_t)-1) {
  61. file_badseek(ms);
  62. return -1;
  63. }
  64. @@ -334,15 +327,13 @@
  65. file_badread(ms);
  66. return -1;
  67. }
  68. + off += size;
  69. +
  70. if (xph_offset > fsize) {
  71. - if (lseek(fd, savedoffset, SEEK_SET) == (off_t)-1) {
  72. - file_badseek(ms);
  73. - return -1;
  74. - }
  75. + /* Perhaps warn here */
  76. continue;
  77. }
  78. - off += size;
  79. if (xph_type != PT_NOTE)
  80. continue;
  81. @@ -854,7 +845,7 @@
  82. private int
  83. doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
  84. - size_t size, int *flags, int mach)
  85. + size_t size, off_t fsize, int *flags, int mach)
  86. {
  87. Elf32_Shdr sh32;
  88. Elf64_Shdr sh64;
  89. @@ -871,16 +862,22 @@
  90. return 0;
  91. }
  92. - if (lseek(fd, off, SEEK_SET) == (off_t)-1) {
  93. - file_badseek(ms);
  94. - return -1;
  95. - }
  96. -
  97. for ( ; num; num--) {
  98. + if (lseek(fd, off, SEEK_SET) == (off_t)-1) {
  99. + file_badseek(ms);
  100. + return -1;
  101. + }
  102. if (read(fd, xsh_addr, xsh_sizeof) == -1) {
  103. file_badread(ms);
  104. return -1;
  105. }
  106. + off += size;
  107. +
  108. + if (xsh_offset > fsize) {
  109. + /* Perhaps warn here */
  110. + continue;
  111. + }
  112. +
  113. switch (xsh_type) {
  114. case SHT_SYMTAB:
  115. #if 0
  116. @@ -889,11 +886,6 @@
  117. stripped = 0;
  118. break;
  119. case SHT_NOTE:
  120. - if ((off = lseek(fd, (off_t)0, SEEK_CUR)) ==
  121. - (off_t)-1) {
  122. - file_badread(ms);
  123. - return -1;
  124. - }
  125. if ((nbuf = malloc((size_t)xsh_size)) == NULL) {
  126. file_error(ms, errno, "Cannot allocate memory"
  127. " for note");
  128. @@ -922,11 +914,6 @@
  129. if (noff == 0)
  130. break;
  131. }
  132. - if ((lseek(fd, off, SEEK_SET)) == (off_t)-1) {
  133. - free(nbuf);
  134. - file_badread(ms);
  135. - return -1;
  136. - }
  137. free(nbuf);
  138. break;
  139. case SHT_SUNW_cap:
  140. @@ -941,7 +928,7 @@
  141. break;
  142. if (lseek(fd, (off_t)xsh_offset, SEEK_SET) ==
  143. (off_t)-1) {
  144. - file_badread(ms);
  145. + file_badseek(ms);
  146. return -1;
  147. }
  148. coff = 0;
  149. @@ -979,10 +966,6 @@
  150. break;
  151. }
  152. }
  153. - if (lseek(fd, off, SEEK_SET) == (off_t)-1) {
  154. - file_badread(ms);
  155. - return -1;
  156. - }
  157. break;
  158. }
  159. }
  160. @@ -1064,13 +1047,6 @@
  161. unsigned char nbuf[BUFSIZ];
  162. ssize_t bufsize;
  163. size_t offset, align;
  164. - off_t savedoffset = (off_t)-1;
  165. - struct stat st;
  166. -
  167. - if (fstat(fd, &st) < 0) {
  168. - file_badread(ms);
  169. - return -1;
  170. - }
  171. if (size != xph_sizeof) {
  172. if (file_printf(ms, ", corrupted program header size") == -1)
  173. @@ -1078,34 +1054,20 @@
  174. return 0;
  175. }
  176. - if (lseek(fd, off, SEEK_SET) == (off_t)-1) {
  177. - file_badseek(ms);
  178. - return -1;
  179. - }
  180. -
  181. for ( ; num; num--) {
  182. - if (read(fd, xph_addr, xph_sizeof) == -1) {
  183. - file_badread(ms);
  184. + if (lseek(fd, off, SEEK_SET) == (off_t)-1) {
  185. + file_badseek(ms);
  186. return -1;
  187. }
  188. - if (xph_offset > st.st_size && savedoffset != (off_t)-1) {
  189. - if (lseek(fd, savedoffset, SEEK_SET) == (off_t)-1) {
  190. - file_badseek(ms);
  191. - return -1;
  192. - }
  193. - continue;
  194. - }
  195. - if ((savedoffset = lseek(fd, (off_t)0, SEEK_CUR)) == (off_t)-1) {
  196. - file_badseek(ms);
  197. + if (read(fd, xph_addr, xph_sizeof) == -1) {
  198. + file_badread(ms);
  199. return -1;
  200. }
  201. + off += size;
  202. if (xph_offset > fsize) {
  203. - if (lseek(fd, savedoffset, SEEK_SET) == (off_t)-1) {
  204. - file_badseek(ms);
  205. - return -1;
  206. - }
  207. + /* Maybe warn here? */
  208. continue;
  209. }
  210. @@ -1130,8 +1092,7 @@
  211. * This is a PT_NOTE section; loop through all the notes
  212. * in the section.
  213. */
  214. - if (lseek(fd, xph_offset, SEEK_SET)
  215. - == (off_t)-1) {
  216. + if (lseek(fd, xph_offset, SEEK_SET) == (off_t)-1) {
  217. file_badseek(ms);
  218. return -1;
  219. }
  220. @@ -1151,10 +1112,6 @@
  221. if (offset == 0)
  222. break;
  223. }
  224. - if (lseek(fd, savedoffset, SEEK_SET) == (off_t)-1) {
  225. - file_badseek(ms);
  226. - return -1;
  227. - }
  228. break;
  229. default:
  230. break;