CVE-2014-9653.2.d68a455.patch 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. Subject: Use pread (...)
  2. Upstream-Author: Christos Zoulas <christos@zoulas.com>
  3. Date: Mon Feb 18 15:40:59 2013 +0000
  4. Origin: FILE5_12-64-gd68a455
  5. Last-Update: 2015-04-19
  6. - use pread
  7. - add reading of section header names to determine if an ELF file is stripped
  8. (Jan Kaluza)
  9. (prequisite for CVE-2014-9653)
  10. --- a/configure.ac
  11. +++ b/configure.ac
  12. @@ -145,7 +145,7 @@
  13. AC_CHECK_FUNCS(mmap strerror strndup strtoul mbrtowc mkstemp utimes utime wcwidth strtof)
  14. dnl Provide implementation of some required functions if necessary
  15. -AC_REPLACE_FUNCS(getopt_long asprintf vasprintf strlcpy strlcat)
  16. +AC_REPLACE_FUNCS(getopt_long asprintf vasprintf strlcpy strlcat pread)
  17. dnl Checks for libraries
  18. AC_CHECK_LIB(z,gzopen)
  19. --- a/src/cdf.c
  20. +++ b/src/cdf.c
  21. @@ -298,10 +298,9 @@
  22. if (info->i_fd == -1)
  23. return -1;
  24. - if (lseek(info->i_fd, off, SEEK_SET) == (off_t)-1)
  25. return -1;
  26. - if (read(info->i_fd, buf, len) != (ssize_t)len)
  27. + if (pread(info->i_fd, buf, len, off) != (ssize_t)len)
  28. return -1;
  29. return (ssize_t)len;
  30. --- a/src/elfclass.h
  31. +++ b/src/elfclass.h
  32. @@ -66,7 +66,8 @@
  33. if (doshn(ms, clazz, swap, fd,
  34. (off_t)elf_getu(swap, elfhdr.e_shoff), shnum,
  35. (size_t)elf_getu16(swap, elfhdr.e_shentsize),
  36. - fsize, &flags, elf_getu16(swap, elfhdr.e_machine)) == -1)
  37. + fsize, &flags, elf_getu16(swap, elfhdr.e_machine),
  38. + (int)elf_getu16(swap, elfhdr.e_shstrndx)) == -1)
  39. return -1;
  40. break;
  41. --- a/src/file.h
  42. +++ b/src/file.h
  43. @@ -448,6 +448,9 @@
  44. #define strtoul(a, b, c) strtol(a, b, c)
  45. #endif
  46. +#ifndef HAVE_PREAD
  47. +ssize_t pread(int, void *, size_t, off_t);
  48. +#endif
  49. #ifndef HAVE_VASPRINTF
  50. int vasprintf(char **, const char *, va_list);
  51. #endif
  52. --- /dev/null
  53. +++ b/src/pread.c
  54. @@ -0,0 +1,14 @@
  55. +#include "file.h"
  56. +#ifndef lint
  57. +FILE_RCSID("@(#)$File: ctime_r.c,v 1.1 2012/05/15 17:14:36 christos Exp $")
  58. +#endif /* lint */
  59. +#include <fcntl.h>
  60. +#include <unistd.h>
  61. +
  62. +ssize_t
  63. +pread(int fd, void *buf, ssize_t len, off_t off) {
  64. + if (lseek(fd, off, SEEK_SET) == (off_t)-1)
  65. + return -1;
  66. +
  67. + return read(fd, buf, len);
  68. +}
  69. --- a/src/readelf.c
  70. +++ b/src/readelf.c
  71. @@ -48,7 +48,7 @@
  72. private int dophn_exec(struct magic_set *, int, int, int, off_t, int, size_t,
  73. off_t, int *, int);
  74. private int doshn(struct magic_set *, int, int, int, off_t, int, size_t,
  75. - off_t, int *, int);
  76. + off_t, int *, int, int);
  77. private size_t donote(struct magic_set *, void *, size_t, size_t, int,
  78. int, size_t, int *);
  79. @@ -141,19 +141,21 @@
  80. #define elf_getu32(swap, value) getu32(swap, value)
  81. #ifdef USE_ARRAY_FOR_64BIT_TYPES
  82. # define elf_getu64(swap, array) \
  83. - ((swap ? ((uint64_t)elf_getu32(swap, array[0])) << 32 : elf_getu32(swap, array[0])) + \
  84. - (swap ? elf_getu32(swap, array[1]) : ((uint64_t)elf_getu32(swap, array[1]) << 32)))
  85. + ((swap ? ((uint64_t)elf_getu32(swap, array[0])) << 32 \
  86. + : elf_getu32(swap, array[0])) + \
  87. + (swap ? elf_getu32(swap, array[1]) : \
  88. + ((uint64_t)elf_getu32(swap, array[1]) << 32)))
  89. #else
  90. # define elf_getu64(swap, value) getu64(swap, value)
  91. #endif
  92. #define xsh_addr (clazz == ELFCLASS32 \
  93. - ? (void *) &sh32 \
  94. - : (void *) &sh64)
  95. + ? (void *)&sh32 \
  96. + : (void *)&sh64)
  97. #define xsh_sizeof (clazz == ELFCLASS32 \
  98. - ? sizeof sh32 \
  99. - : sizeof sh64)
  100. -#define xsh_size (clazz == ELFCLASS32 \
  101. + ? sizeof(sh32) \
  102. + : sizeof(sh64))
  103. +#define xsh_size (size_t)(clazz == ELFCLASS32 \
  104. ? elf_getu32(swap, sh32.sh_size) \
  105. : elf_getu64(swap, sh64.sh_size))
  106. #define xsh_offset (off_t)(clazz == ELFCLASS32 \
  107. @@ -162,12 +164,15 @@
  108. #define xsh_type (clazz == ELFCLASS32 \
  109. ? elf_getu32(swap, sh32.sh_type) \
  110. : elf_getu32(swap, sh64.sh_type))
  111. +#define xsh_name (clazz == ELFCLASS32 \
  112. + ? elf_getu32(swap, sh32.sh_name) \
  113. + : elf_getu32(swap, sh64.sh_name))
  114. #define xph_addr (clazz == ELFCLASS32 \
  115. ? (void *) &ph32 \
  116. : (void *) &ph64)
  117. #define xph_sizeof (clazz == ELFCLASS32 \
  118. - ? sizeof ph32 \
  119. - : sizeof ph64)
  120. + ? sizeof(ph32) \
  121. + : sizeof(ph64))
  122. #define xph_type (clazz == ELFCLASS32 \
  123. ? elf_getu32(swap, ph32.p_type) \
  124. : elf_getu32(swap, ph64.p_type))
  125. @@ -183,8 +188,8 @@
  126. ? elf_getu32(swap, ph32.p_filesz) \
  127. : elf_getu64(swap, ph64.p_filesz)))
  128. #define xnh_addr (clazz == ELFCLASS32 \
  129. - ? (void *) &nh32 \
  130. - : (void *) &nh64)
  131. + ? (void *)&nh32 \
  132. + : (void *)&nh64)
  133. #define xph_memsz (size_t)((clazz == ELFCLASS32 \
  134. ? elf_getu32(swap, ph32.p_memsz) \
  135. : elf_getu64(swap, ph64.p_memsz)))
  136. @@ -204,8 +209,8 @@
  137. ? prpsoffsets32[i] \
  138. : prpsoffsets64[i])
  139. #define xcap_addr (clazz == ELFCLASS32 \
  140. - ? (void *) &cap32 \
  141. - : (void *) &cap64)
  142. + ? (void *)&cap32 \
  143. + : (void *)&cap64)
  144. #define xcap_sizeof (clazz == ELFCLASS32 \
  145. ? sizeof cap32 \
  146. : sizeof cap64)
  147. @@ -305,7 +310,7 @@
  148. {
  149. Elf32_Phdr ph32;
  150. Elf64_Phdr ph64;
  151. - size_t offset;
  152. + size_t offset, len;
  153. unsigned char nbuf[BUFSIZ];
  154. ssize_t bufsize;
  155. @@ -319,11 +324,7 @@
  156. * Loop through all the program headers.
  157. */
  158. for ( ; num; num--) {
  159. - if (lseek(fd, off, SEEK_SET) == (off_t)-1) {
  160. - file_badseek(ms);
  161. - return -1;
  162. - }
  163. - if (read(fd, xph_addr, xph_sizeof) == -1) {
  164. + if (pread(fd, xph_addr, xph_sizeof, off) == -1) {
  165. file_badread(ms);
  166. return -1;
  167. }
  168. @@ -341,13 +342,8 @@
  169. * This is a PT_NOTE section; loop through all the notes
  170. * in the section.
  171. */
  172. - if (lseek(fd, xph_offset, SEEK_SET) == (off_t)-1) {
  173. - file_badseek(ms);
  174. - return -1;
  175. - }
  176. - bufsize = read(fd, nbuf,
  177. - ((xph_filesz < sizeof(nbuf)) ? xph_filesz : sizeof(nbuf)));
  178. - if (bufsize == -1) {
  179. + len = xph_filesz < sizeof(nbuf) ? xph_filesz : sizeof(nbuf);
  180. + if ((bufsize = pread(fd, nbuf, len, xph_offset)) == -1) {
  181. file_badread(ms);
  182. return -1;
  183. }
  184. @@ -845,16 +841,17 @@
  185. private int
  186. doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
  187. - size_t size, off_t fsize, int *flags, int mach)
  188. + size_t size, off_t fsize, int *flags, int mach, int strtab)
  189. {
  190. Elf32_Shdr sh32;
  191. Elf64_Shdr sh64;
  192. int stripped = 1;
  193. size_t nbadcap = 0;
  194. void *nbuf;
  195. - off_t noff;
  196. + off_t noff, name_off;
  197. uint64_t cap_hw1 = 0; /* SunOS 5.x hardware capabilites */
  198. uint64_t cap_sf1 = 0; /* SunOS 5.x software capabilites */
  199. + char name[50];
  200. if (size != xsh_sizeof) {
  201. if (file_printf(ms, ", corrupted section header size") == -1)
  202. @@ -862,12 +859,19 @@
  203. return 0;
  204. }
  205. + /* Save offset of name section to be able to read section names later */
  206. + name_off = off * size * strtab;
  207. + /* Read the name of this section. */
  208. + if (pread(fd, name, sizeof(name), name_off + xsh_name) == -1) {
  209. + file_badread(ms);
  210. + return -1;
  211. + }
  212. + name[sizeof(name) - 1] = '\0';
  213. + if (strcmp(name, ".debug_info") == 0)
  214. + stripped = 0;
  215. +
  216. for ( ; num; num--) {
  217. - if (lseek(fd, off, SEEK_SET) == (off_t)-1) {
  218. - file_badseek(ms);
  219. - return -1;
  220. - }
  221. - if (read(fd, xsh_addr, xsh_sizeof) == -1) {
  222. + if (pread(fd, xsh_addr, xsh_sizeof, off) == -1) {
  223. file_badread(ms);
  224. return -1;
  225. }
  226. @@ -886,31 +890,23 @@
  227. stripped = 0;
  228. break;
  229. case SHT_NOTE:
  230. - if ((nbuf = malloc((size_t)xsh_size)) == NULL) {
  231. + if ((nbuf = malloc(xsh_size)) == NULL) {
  232. file_error(ms, errno, "Cannot allocate memory"
  233. " for note");
  234. return -1;
  235. }
  236. - if ((noff = lseek(fd, (off_t)xsh_offset, SEEK_SET)) ==
  237. - (off_t)-1) {
  238. + if (pread(fd, nbuf, xsh_size, xsh_offset) == -1) {
  239. file_badread(ms);
  240. free(nbuf);
  241. return -1;
  242. }
  243. - if (read(fd, nbuf, (size_t)xsh_size) !=
  244. - (ssize_t)xsh_size) {
  245. - free(nbuf);
  246. - file_badread(ms);
  247. - return -1;
  248. - }
  249. noff = 0;
  250. for (;;) {
  251. if (noff >= (off_t)xsh_size)
  252. break;
  253. noff = donote(ms, nbuf, (size_t)noff,
  254. - (size_t)xsh_size, clazz, swap, 4,
  255. - flags);
  256. + xsh_size, clazz, swap, 4, flags);
  257. if (noff == 0)
  258. break;
  259. }
  260. @@ -926,8 +922,8 @@
  261. }
  262. if (nbadcap > 5)
  263. break;
  264. - if (lseek(fd, (off_t)xsh_offset, SEEK_SET) ==
  265. - (off_t)-1) {
  266. +
  267. + if (lseek(fd, xsh_offset, SEEK_SET) == (off_t)-1) {
  268. file_badseek(ms);
  269. return -1;
  270. }
  271. @@ -1046,7 +1042,7 @@
  272. const char *shared_libraries = "";
  273. unsigned char nbuf[BUFSIZ];
  274. ssize_t bufsize;
  275. - size_t offset, align;
  276. + size_t offset, align, len;
  277. if (size != xph_sizeof) {
  278. if (file_printf(ms, ", corrupted program header size") == -1)
  279. @@ -1055,13 +1051,8 @@
  280. }
  281. for ( ; num; num--) {
  282. - if (lseek(fd, off, SEEK_SET) == (off_t)-1) {
  283. - file_badseek(ms);
  284. - return -1;
  285. - }
  286. -
  287. - if (read(fd, xph_addr, xph_sizeof) == -1) {
  288. - file_badread(ms);
  289. + if (pread(fd, xph_addr, xph_sizeof, off) == -1) {
  290. + file_badread(ms);
  291. return -1;
  292. }
  293. @@ -1092,12 +1083,9 @@
  294. * This is a PT_NOTE section; loop through all the notes
  295. * in the section.
  296. */
  297. - if (lseek(fd, xph_offset, SEEK_SET) == (off_t)-1) {
  298. - file_badseek(ms);
  299. - return -1;
  300. - }
  301. - bufsize = read(fd, nbuf, ((xph_filesz < sizeof(nbuf)) ?
  302. - xph_filesz : sizeof(nbuf)));
  303. + len = xph_filesz < sizeof(nbuf) ? xph_filesz
  304. + : sizeof(nbuf);
  305. + bufsize = pread(fd, nbuf, len, xph_offset);
  306. if (bufsize == -1) {
  307. file_badread(ms);
  308. return -1;