CVE-2014-8116.1.b4c0114.patch 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. Subject: Limit the number of program and section header number of sections to be (...)
  2. ID: CVE-2014-8116
  3. Upstream-Author: Christos Zoulas <christos@zoulas.com>
  4. Date: Sat Nov 22 16:04:29 2014 +0000
  5. Origin: FILE5_20-27-gb4c0114
  6. Last-Update: 2015-01-09
  7. - limit the number of program and section header number of sections to be
  8. processed to avoid excessive processing time.
  9. - if a bad note is found, return 0 to stop processing immediately.
  10. --- a/src/elfclass.h
  11. +++ b/src/elfclass.h
  12. @@ -35,9 +35,11 @@
  13. switch (type) {
  14. #ifdef ELFCORE
  15. case ET_CORE:
  16. + phnum = elf_getu16(swap, elfhdr.e_phnum);
  17. + if (phnum > MAX_PHNUM)
  18. + return toomany(ms, "program", phnum);
  19. if (dophn_core(ms, clazz, swap, fd,
  20. - (off_t)elf_getu(swap, elfhdr.e_phoff),
  21. - elf_getu16(swap, elfhdr.e_phnum),
  22. + (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
  23. (size_t)elf_getu16(swap, elfhdr.e_phentsize),
  24. fsize, &flags) == -1)
  25. return -1;
  26. @@ -45,18 +47,24 @@
  27. #endif
  28. case ET_EXEC:
  29. case ET_DYN:
  30. + phnum = elf_getu16(swap, elfhdr.e_phnum);
  31. + if (phnum > MAX_PHNUM)
  32. + return toomany(ms, "program", phnum);
  33. + shnum = elf_getu16(swap, elfhdr.e_shnum);
  34. + if (shnum > MAX_SHNUM)
  35. + return toomany(ms, "section", shnum);
  36. if (dophn_exec(ms, clazz, swap, fd,
  37. - (off_t)elf_getu(swap, elfhdr.e_phoff),
  38. - elf_getu16(swap, elfhdr.e_phnum),
  39. + (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
  40. (size_t)elf_getu16(swap, elfhdr.e_phentsize),
  41. - fsize, &flags, elf_getu16(swap, elfhdr.e_shnum))
  42. - == -1)
  43. + fsize, &flags, shnum) == -1)
  44. return -1;
  45. /*FALLTHROUGH*/
  46. case ET_REL:
  47. + shnum = elf_getu16(swap, elfhdr.e_shnum);
  48. + if (shnum > MAX_SHNUM)
  49. + return toomany(ms, "section", shnum);
  50. if (doshn(ms, clazz, swap, fd,
  51. - (off_t)elf_getu(swap, elfhdr.e_shoff),
  52. - elf_getu16(swap, elfhdr.e_shnum),
  53. + (off_t)elf_getu(swap, elfhdr.e_shoff), shnum,
  54. (size_t)elf_getu16(swap, elfhdr.e_shentsize),
  55. &flags,
  56. elf_getu16(swap, elfhdr.e_machine)) == -1)
  57. --- a/src/readelf.c
  58. +++ b/src/readelf.c
  59. @@ -60,6 +60,18 @@
  60. private uint32_t getu32(int, uint32_t);
  61. private uint64_t getu64(int, uint64_t);
  62. +#define MAX_PHNUM 256
  63. +#define MAX_SHNUM 1024
  64. +
  65. +private int
  66. +toomany(struct magic_set *ms, const char *name, uint16_t num)
  67. +{
  68. + if (file_printf(ms, ", too many %s header sections (%u)", name, num
  69. + ) == -1)
  70. + return -1;
  71. + return 0;
  72. +}
  73. +
  74. private uint16_t
  75. getu16(int swap, uint16_t value)
  76. {
  77. @@ -398,13 +410,13 @@
  78. if (namesz & 0x80000000) {
  79. (void)file_printf(ms, ", bad note name size 0x%lx",
  80. (unsigned long)namesz);
  81. - return offset;
  82. + return 0;
  83. }
  84. if (descsz & 0x80000000) {
  85. (void)file_printf(ms, ", bad note description size 0x%lx",
  86. (unsigned long)descsz);
  87. - return offset;
  88. + return 0;
  89. }
  90. @@ -1165,7 +1177,7 @@
  91. int flags = 0;
  92. Elf32_Ehdr elf32hdr;
  93. Elf64_Ehdr elf64hdr;
  94. - uint16_t type;
  95. + uint16_t type, phnum, shnum;
  96. if (ms->flags & (MAGIC_MIME|MAGIC_APPLE))
  97. return 0;