CVE-2014-8117.3.6f737dd.patch 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. Subject: Reduce recursion level from 20 to 10 and make a symbolic constant for it. (...)
  2. ID: CVE-2014-8117
  3. Upstream-Author: Christos Zoulas <christos@zoulas.com>
  4. Date: Sun Nov 23 13:54:27 2014 +0000
  5. Origin: FILE5_20-29-g6f737dd
  6. Last-Update: 2015-01-05
  7. - reduce recursion level from 20 to 10 and make a symbolic constant for it.
  8. - pull out the guts of saving and restoring the output buffer into functions
  9. and take care not to overwrite the error message if an error happened.
  10. diff --git a/src/file.h b/src/file.h
  11. index de262b2..6f61643 100644
  12. --- a/src/file.h
  13. +++ b/src/file.h
  14. @@ -444,6 +444,14 @@ protected int file_os2_apptype(struct magic_set *, const char *, const void *,
  15. #endif /* __EMX__ */
  16. +typedef struct {
  17. + char *buf;
  18. + uint32_t offset;
  19. +} file_pushbuf_t;
  20. +
  21. +protected file_pushbuf_t *file_push_buffer(struct magic_set *);
  22. +protected char *file_pop_buffer(struct magic_set *, file_pushbuf_t *);
  23. +
  24. #ifndef COMPILE_ONLY
  25. extern const char *file_names[];
  26. extern const size_t file_nnames;
  27. diff --git a/src/funcs.c b/src/funcs.c
  28. index 0d645eb..04bab02 100644
  29. --- a/src/funcs.c
  30. +++ b/src/funcs.c
  31. @@ -459,3 +459,43 @@ file_replace(struct magic_set *ms, const char *pat, const char *rep)
  32. return nm;
  33. }
  34. }
  35. +
  36. +protected file_pushbuf_t *
  37. +file_push_buffer(struct magic_set *ms)
  38. +{
  39. + file_pushbuf_t *pb;
  40. +
  41. + if (ms->event_flags & EVENT_HAD_ERR)
  42. + return NULL;
  43. +
  44. + if ((pb = (CAST(file_pushbuf_t *, malloc(sizeof(*pb))))) == NULL)
  45. + return NULL;
  46. +
  47. + pb->buf = ms->o.buf;
  48. + pb->offset = ms->offset;
  49. +
  50. + ms->o.buf = NULL;
  51. + ms->offset = 0;
  52. +
  53. + return pb;
  54. +}
  55. +
  56. +protected char *
  57. +file_pop_buffer(struct magic_set *ms, file_pushbuf_t *pb)
  58. +{
  59. + char *rbuf;
  60. +
  61. + if (ms->event_flags & EVENT_HAD_ERR) {
  62. + free(pb->buf);
  63. + free(pb);
  64. + return NULL;
  65. + }
  66. +
  67. + rbuf = ms->o.buf;
  68. +
  69. + ms->o.buf = pb->buf;
  70. + ms->offset = pb->offset;
  71. +
  72. + free(pb);
  73. + return rbuf;
  74. +}
  75. diff --git a/src/softmagic.c b/src/softmagic.c
  76. index 72eae4b..0ace99f 100644
  77. --- a/src/softmagic.c
  78. +++ b/src/softmagic.c
  79. @@ -61,6 +61,9 @@ private void cvt_32(union VALUETYPE *, const struct magic *);
  80. private void cvt_64(union VALUETYPE *, const struct magic *);
  81. #define OFFSET_OOB(n, o, i) ((n) < (o) || (i) > ((n) - (o)))
  82. +
  83. +#define MAX_RECURSION_LEVEL 10
  84. +
  85. /*
  86. * softmagic - lookup one file in parsed, in-memory copy of database
  87. * Passed the name and FILE * of one file to be typed.
  88. @@ -1044,11 +1047,12 @@ mget(struct magic_set *ms, const unsigned char *s,
  89. int recursion_level)
  90. {
  91. uint32_t offset = ms->offset;
  92. + file_pushbuf_t *pb;
  93. int rv;
  94. - char *sbuf, *rbuf;
  95. + char *rbuf;
  96. union VALUETYPE *p = &ms->ms_value;
  97. - if (recursion_level >= 20) {
  98. + if (recursion_level >= MAX_RECURSION_LEVEL) {
  99. file_error(ms, 0, "recursion nesting exceeded");
  100. return -1;
  101. }
  102. @@ -1611,15 +1615,21 @@ mget(struct magic_set *ms, const unsigned char *s,
  103. return 0;
  104. if (nbytes < offset)
  105. return 0;
  106. - sbuf = ms->o.buf;
  107. - ms->o.buf = NULL;
  108. +
  109. + if ((pb = file_push_buffer(ms)) == NULL)
  110. + return -1;
  111. +
  112. rv = file_softmagic(ms, s + offset, nbytes - offset,
  113. recursion_level, BINTEST, text);
  114. +
  115. if ((ms->flags & MAGIC_DEBUG) != 0)
  116. fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv);
  117. +
  118. + rbuf = file_pop_buffer(ms, pb);
  119. + if (rbuf == NULL)
  120. + return -1;
  121. +
  122. if (rv == 1) {
  123. - rbuf = ms->o.buf;
  124. - ms->o.buf = sbuf;
  125. if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 &&
  126. file_printf(ms, m->desc, offset) == -1) {
  127. free(rbuf);
  128. @@ -1629,9 +1639,8 @@ mget(struct magic_set *ms, const unsigned char *s,
  129. free(rbuf);
  130. return -1;
  131. }
  132. - free(rbuf);
  133. - } else
  134. - ms->o.buf = sbuf;
  135. + }
  136. + free(rbuf);
  137. return rv;
  138. case FILE_DEFAULT: /* nothing to check */