CVE-2014-3538.patch 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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. Last-Update: 2014-09-07
  11. * Enforce limit of 8K on regex searches that have no limits
  12. * Allow the l modifier for regex to mean line count. Default
  13. to byte count. If line count is specified, assume a max
  14. of 80 characters per line to limit the byte count.
  15. * Don't allow conversions to be used for dates, allowing
  16. the mask field to be used as an offset.
  17. * Bump the version of the magic format so that regex changes
  18. are visible.
  19. --- a/src/softmagic.c
  20. +++ b/src/softmagic.c
  21. @@ -51,7 +51,7 @@
  22. private int32_t moffset(struct magic_set *, struct magic *);
  23. private void mdebug(uint32_t, const char *, size_t);
  24. private int mcopy(struct magic_set *, union VALUETYPE *, int, int,
  25. - const unsigned char *, uint32_t, size_t, size_t);
  26. + const unsigned char *, uint32_t, size_t, struct magic *);
  27. private int mconvert(struct magic_set *, struct magic *);
  28. private int print_sep(struct magic_set *, int);
  29. private int handle_annotation(struct magic_set *, struct magic *);
  30. @@ -918,7 +918,7 @@
  31. private int
  32. mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
  33. - const unsigned char *s, uint32_t offset, size_t nbytes, size_t linecnt)
  34. + const unsigned char *s, uint32_t offset, size_t nbytes, struct magic *m)
  35. {
  36. /*
  37. * Note: FILE_SEARCH and FILE_REGEX do not actually copy
  38. @@ -938,15 +938,24 @@
  39. const char *last; /* end of search region */
  40. const char *buf; /* start of search region */
  41. const char *end;
  42. - size_t lines;
  43. + size_t lines, linecnt, bytecnt;
  44. + linecnt = m->str_range;
  45. + bytecnt = linecnt * 80;
  46. +
  47. + if (bytecnt == 0) {
  48. + bytecnt = 8192;
  49. + }
  50. + if (bytecnt > nbytes) {
  51. + bytecnt = nbytes;
  52. + }
  53. if (s == NULL) {
  54. ms->search.s_len = 0;
  55. ms->search.s = NULL;
  56. return 0;
  57. }
  58. buf = RCAST(const char *, s) + offset;
  59. - end = last = RCAST(const char *, s) + nbytes;
  60. + end = last = RCAST(const char *, s) + bytecnt;
  61. /* mget() guarantees buf <= last */
  62. for (lines = linecnt, b = buf; lines && b < end &&
  63. ((b = CAST(const char *,
  64. @@ -959,7 +968,7 @@
  65. b++;
  66. }
  67. if (lines)
  68. - last = RCAST(const char *, s) + nbytes;
  69. + last = RCAST(const char *, s) + bytecnt;
  70. ms->search.s = buf;
  71. ms->search.s_len = last - buf;
  72. @@ -1032,7 +1041,6 @@
  73. int recursion_level)
  74. {
  75. uint32_t offset = ms->offset;
  76. - uint32_t count = m->str_range;
  77. union VALUETYPE *p = &ms->ms_value;
  78. if (recursion_level >= 20) {
  79. @@ -1040,7 +1048,8 @@
  80. return -1;
  81. }
  82. - if (mcopy(ms, p, m->type, m->flag & INDIR, s, offset, nbytes, count) == -1)
  83. + if (mcopy(ms, p, m->type, m->flag & INDIR, s, offset,
  84. + (uint32_t)nbytes, m) == -1)
  85. return -1;
  86. if ((ms->flags & MAGIC_DEBUG) != 0) {
  87. @@ -1527,7 +1536,7 @@
  88. if (m->flag & INDIROFFADD) {
  89. offset += ms->c.li[cont_level-1].off;
  90. }
  91. - if (mcopy(ms, p, m->type, 0, s, offset, nbytes, count) == -1)
  92. + if (mcopy(ms, p, m->type, 0, s, offset, nbytes, m) == -1)
  93. return -1;
  94. ms->offset = offset;