CVE-2014-3538.patch 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. Subject: file does not properly restrict the amount of data read during a regex search
  2. ID: CVE-2014-3538
  3. Author: Christos Zoulas <christos@zoulas.com>
  4. Date: Tue Jun 3 19:01:34 2014 +0000
  5. Origin:
  6. commit 4a284c89d6ef11aca34da65da7d673050a5ea320
  7. Debian-Author: Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
  8. Comment:
  9. Taken from the fix in php5 (5.4.4-14+deb7u13), with minor corrections
  10. and adjustments.
  11. Last-Update: 2014-09-07
  12. * Enforce limit of 8K on regex searches that have no limits
  13. * Allow the l modifier for regex to mean line count. Default
  14. to byte count. If line count is specified, assume a max
  15. of 80 characters per line to limit the byte count.
  16. * Don't allow conversions to be used for dates, allowing
  17. the mask field to be used as an offset.
  18. * Bump the version of the magic format so that regex changes
  19. are visible.
  20. --- a/src/softmagic.c
  21. +++ b/src/softmagic.c
  22. @@ -51,7 +51,7 @@
  23. private int32_t moffset(struct magic_set *, struct magic *);
  24. private void mdebug(uint32_t, const char *, size_t);
  25. private int mcopy(struct magic_set *, union VALUETYPE *, int, int,
  26. - const unsigned char *, uint32_t, size_t, size_t);
  27. + const unsigned char *, uint32_t, size_t, struct magic *);
  28. private int mconvert(struct magic_set *, struct magic *);
  29. private int print_sep(struct magic_set *, int);
  30. private int handle_annotation(struct magic_set *, struct magic *);
  31. @@ -924,7 +924,7 @@
  32. private int
  33. mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
  34. - const unsigned char *s, uint32_t offset, size_t nbytes, size_t linecnt)
  35. + const unsigned char *s, uint32_t offset, size_t nbytes, struct magic *m)
  36. {
  37. /*
  38. * Note: FILE_SEARCH and FILE_REGEX do not actually copy
  39. @@ -944,15 +944,24 @@
  40. const char *last; /* end of search region */
  41. const char *buf; /* start of search region */
  42. const char *end;
  43. - size_t lines;
  44. + size_t lines, linecnt, bytecnt;
  45. + linecnt = m->str_range;
  46. + bytecnt = linecnt * 80;
  47. +
  48. + if (bytecnt == 0) {
  49. + bytecnt = 8192;
  50. + }
  51. + if (bytecnt > nbytes) {
  52. + bytecnt = nbytes;
  53. + }
  54. if (s == NULL) {
  55. ms->search.s_len = 0;
  56. ms->search.s = NULL;
  57. return 0;
  58. }
  59. buf = (const char *)s + offset;
  60. - end = last = (const char *)s + nbytes;
  61. + end = last = (const char *)s + bytecnt;
  62. /* mget() guarantees buf <= last */
  63. for (lines = linecnt, b = buf; lines && b < end &&
  64. ((b = CAST(const char *,
  65. @@ -965,7 +974,7 @@
  66. b++;
  67. }
  68. if (lines)
  69. - last = (const char *)s + nbytes;
  70. + last = (const char *)s + bytecnt;
  71. ms->search.s = buf;
  72. ms->search.s_len = last - buf;
  73. @@ -1037,7 +1046,6 @@
  74. struct magic *m, size_t nbytes, unsigned int cont_level, int recursion_level)
  75. {
  76. uint32_t offset = ms->offset;
  77. - uint32_t count = m->str_range;
  78. union VALUETYPE *p = &ms->ms_value;
  79. if (recursion_level >= 20) {
  80. @@ -1045,7 +1053,8 @@
  81. return -1;
  82. }
  83. - if (mcopy(ms, p, m->type, m->flag & INDIR, s, offset, nbytes, count) == -1)
  84. + if (mcopy(ms, p, m->type, m->flag & INDIR, s, offset,
  85. + (uint32_t)nbytes, m) == -1)
  86. return -1;
  87. if ((ms->flags & MAGIC_DEBUG) != 0) {
  88. @@ -1532,7 +1541,7 @@
  89. if (m->flag & INDIROFFADD) {
  90. offset += ms->c.li[cont_level-1].off;
  91. }
  92. - if (mcopy(ms, p, m->type, 0, s, offset, nbytes, count) == -1)
  93. + if (mcopy(ms, p, m->type, 0, s, offset, nbytes, m) == -1)
  94. return -1;
  95. ms->offset = offset;