CVE-2014-8117.3.6f737dd.patch 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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-09
  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. --- a/src/file.h
  11. +++ b/src/file.h
  12. @@ -422,6 +422,14 @@
  13. #endif /* __EMX__ */
  14. +typedef struct {
  15. + char *buf;
  16. + uint32_t offset;
  17. +} file_pushbuf_t;
  18. +
  19. +protected file_pushbuf_t *file_push_buffer(struct magic_set *);
  20. +protected char *file_pop_buffer(struct magic_set *, file_pushbuf_t *);
  21. +
  22. #ifndef COMPILE_ONLY
  23. extern const char *file_names[];
  24. extern const size_t file_nnames;
  25. --- a/src/funcs.c
  26. +++ b/src/funcs.c
  27. @@ -424,3 +424,43 @@
  28. #endif /* ENABLE_CONDITIONALS */
  29. return 0;
  30. }
  31. +
  32. +protected file_pushbuf_t *
  33. +file_push_buffer(struct magic_set *ms)
  34. +{
  35. + file_pushbuf_t *pb;
  36. +
  37. + if (ms->event_flags & EVENT_HAD_ERR)
  38. + return NULL;
  39. +
  40. + if ((pb = (CAST(file_pushbuf_t *, malloc(sizeof(*pb))))) == NULL)
  41. + return NULL;
  42. +
  43. + pb->buf = ms->o.buf;
  44. + pb->offset = ms->offset;
  45. +
  46. + ms->o.buf = NULL;
  47. + ms->offset = 0;
  48. +
  49. + return pb;
  50. +}
  51. +
  52. +protected char *
  53. +file_pop_buffer(struct magic_set *ms, file_pushbuf_t *pb)
  54. +{
  55. + char *rbuf;
  56. +
  57. + if (ms->event_flags & EVENT_HAD_ERR) {
  58. + free(pb->buf);
  59. + free(pb);
  60. + return NULL;
  61. + }
  62. +
  63. + rbuf = ms->o.buf;
  64. +
  65. + ms->o.buf = pb->buf;
  66. + ms->offset = pb->offset;
  67. +
  68. + free(pb);
  69. + return rbuf;
  70. +}
  71. --- a/src/softmagic.c
  72. +++ b/src/softmagic.c
  73. @@ -61,6 +61,9 @@
  74. private void cvt_64(union VALUETYPE *, const struct magic *);
  75. #define OFFSET_OOB(n, o, i) ((n) < (o) || (i) > ((n) - (o)))
  76. +
  77. +#define MAX_RECURSION_LEVEL 10
  78. +
  79. /*
  80. * softmagic - lookup one file in parsed, in-memory copy of database
  81. * Passed the name and FILE * of one file to be typed.
  82. @@ -1049,11 +1052,12 @@
  83. struct magic *m, size_t nbytes, unsigned int cont_level, int recursion_level)
  84. {
  85. uint32_t offset = ms->offset;
  86. + file_pushbuf_t *pb;
  87. int rv;
  88. - char *sbuf, *rbuf;
  89. + char *rbuf;
  90. union VALUETYPE *p = &ms->ms_value;
  91. - if (recursion_level >= 20) {
  92. + if (recursion_level >= MAX_RECURSION_LEVEL) {
  93. file_error(ms, 0, "recursion nesting exceeded");
  94. return -1;
  95. }
  96. @@ -1614,17 +1618,23 @@
  97. case FILE_INDIRECT:
  98. if (offset == 0)
  99. return 0;
  100. +
  101. if (nbytes < offset)
  102. return 0;
  103. - sbuf = ms->o.buf;
  104. - ms->o.buf = NULL;
  105. +
  106. + if ((pb = file_push_buffer(ms)) == NULL)
  107. + return -1;
  108. +
  109. rv = file_softmagic(ms, s + offset, nbytes - offset,
  110. recursion_level, BINTEST);
  111. if ((ms->flags & MAGIC_DEBUG) != 0)
  112. fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv);
  113. +
  114. + rbuf = file_pop_buffer(ms, pb);
  115. + if (rbuf == NULL)
  116. + return -1;
  117. +
  118. if (rv == 1) {
  119. - rbuf = ms->o.buf;
  120. - ms->o.buf = sbuf;
  121. if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 &&
  122. file_printf(ms, m->desc, offset) == -1) {
  123. free(rbuf);
  124. @@ -1634,9 +1644,8 @@
  125. free(rbuf);
  126. return -1;
  127. }
  128. - free(rbuf);
  129. - } else
  130. - ms->o.buf = sbuf;
  131. + }
  132. + free(rbuf);
  133. return rv;
  134. case FILE_DEFAULT: /* nothing to check */