CVE-2014-8116.1.b4c0114.patch 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  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-05
  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. diff --git a/src/elfclass.h b/src/elfclass.h
  11. index 010958a..0826ce3 100644
  12. --- a/src/elfclass.h
  13. +++ b/src/elfclass.h
  14. @@ -35,10 +35,12 @@
  15. switch (type) {
  16. #ifdef ELFCORE
  17. case ET_CORE:
  18. + phnum = elf_getu16(swap, elfhdr.e_phnum);
  19. + if (phnum > MAX_PHNUM)
  20. + return toomany(ms, "program", phnum);
  21. flags |= FLAGS_IS_CORE;
  22. if (dophn_core(ms, clazz, swap, fd,
  23. - (off_t)elf_getu(swap, elfhdr.e_phoff),
  24. - elf_getu16(swap, elfhdr.e_phnum),
  25. + (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
  26. (size_t)elf_getu16(swap, elfhdr.e_phentsize),
  27. fsize, &flags) == -1)
  28. return -1;
  29. @@ -46,18 +48,24 @@
  30. #endif
  31. case ET_EXEC:
  32. case ET_DYN:
  33. + phnum = elf_getu16(swap, elfhdr.e_phnum);
  34. + if (phnum > MAX_PHNUM)
  35. + return toomany(ms, "program", phnum);
  36. + shnum = elf_getu16(swap, elfhdr.e_shnum);
  37. + if (shnum > MAX_SHNUM)
  38. + return toomany(ms, "section", shnum);
  39. if (dophn_exec(ms, clazz, swap, fd,
  40. - (off_t)elf_getu(swap, elfhdr.e_phoff),
  41. - elf_getu16(swap, elfhdr.e_phnum),
  42. + (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
  43. (size_t)elf_getu16(swap, elfhdr.e_phentsize),
  44. - fsize, &flags, elf_getu16(swap, elfhdr.e_shnum))
  45. - == -1)
  46. + fsize, &flags, shnum) == -1)
  47. return -1;
  48. /*FALLTHROUGH*/
  49. case ET_REL:
  50. + shnum = elf_getu16(swap, elfhdr.e_shnum);
  51. + if (shnum > MAX_SHNUM)
  52. + return toomany(ms, "section", shnum);
  53. if (doshn(ms, clazz, swap, fd,
  54. - (off_t)elf_getu(swap, elfhdr.e_shoff),
  55. - elf_getu16(swap, elfhdr.e_shnum),
  56. + (off_t)elf_getu(swap, elfhdr.e_shoff), shnum,
  57. (size_t)elf_getu16(swap, elfhdr.e_shentsize),
  58. fsize, &flags, elf_getu16(swap, elfhdr.e_machine),
  59. (int)elf_getu16(swap, elfhdr.e_shstrndx)) == -1)
  60. diff --git a/src/readelf.c b/src/readelf.c
  61. index 18dacdd..5a6dd41 100644
  62. --- a/src/readelf.c
  63. +++ b/src/readelf.c
  64. @@ -60,6 +60,18 @@ private uint16_t getu16(int, uint16_t);
  65. private uint32_t getu32(int, uint32_t);
  66. private uint64_t getu64(int, uint64_t);
  67. +#define MAX_PHNUM 256
  68. +#define MAX_SHNUM 1024
  69. +
  70. +private int
  71. +toomany(struct magic_set *ms, const char *name, uint16_t num)
  72. +{
  73. + if (file_printf(ms, ", too many %s header sections (%u)", name, num
  74. + ) == -1)
  75. + return -1;
  76. + return 0;
  77. +}
  78. +
  79. private uint16_t
  80. getu16(int swap, uint16_t value)
  81. {
  82. @@ -507,13 +519,13 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
  83. if (namesz & 0x80000000) {
  84. (void)file_printf(ms, ", bad note name size 0x%lx",
  85. (unsigned long)namesz);
  86. - return offset;
  87. + return 0;
  88. }
  89. if (descsz & 0x80000000) {
  90. (void)file_printf(ms, ", bad note description size 0x%lx",
  91. (unsigned long)descsz);
  92. - return offset;
  93. + return 0;
  94. }
  95. @@ -1198,7 +1210,7 @@ file_tryelf(struct magic_set *ms, int fd, const unsigned char *buf,
  96. int flags = 0;
  97. Elf32_Ehdr elf32hdr;
  98. Elf64_Ehdr elf64hdr;
  99. - uint16_t type;
  100. + uint16_t type, phnum, shnum;
  101. if (ms->flags & (MAGIC_MIME|MAGIC_APPLE))
  102. return 0;