CVE-2014-8117.4.90018fe.patch 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. Subject: Bump recursion to 15, and allow it to be set from the command line
  2. Upstream-Author: Christos Zoulas <christos@zoulas.com>
  3. Date: Thu Nov 27 15:40:36 2014 +0000
  4. Origin: FILE5_20-34-g90018fe
  5. Last-Update: 2015-01-05
  6. diff --git a/src/file.c b/src/file.c
  7. index 408ec63..2f3cf9d 100644
  8. --- a/src/file.c
  9. +++ b/src/file.c
  10. @@ -101,7 +101,7 @@ private const struct option long_options[] = {
  11. #undef OPT_LONGONLY
  12. {0, 0, NULL, 0}
  13. };
  14. -#define OPTSTRING "bcCde:f:F:hiklLm:nNprsvz0"
  15. +#define OPTSTRING "bcCde:f:F:hiklLm:nNprR:svz0"
  16. private const struct {
  17. const char *name;
  18. @@ -140,6 +140,7 @@ main(int argc, char *argv[])
  19. size_t i;
  20. int action = 0, didsomefiles = 0, errflg = 0;
  21. int flags = 0, e = 0;
  22. + size_t max_recursion = 0;
  23. struct magic_set *magic = NULL;
  24. int longindex;
  25. const char *magicfile = NULL; /* where the magic is */
  26. @@ -243,6 +244,9 @@ main(int argc, char *argv[])
  27. case 'r':
  28. flags |= MAGIC_RAW;
  29. break;
  30. + case 'R':
  31. + max_recursion = atoi(optarg);
  32. + break;
  33. case 's':
  34. flags |= MAGIC_DEVICES;
  35. break;
  36. @@ -290,6 +294,8 @@ main(int argc, char *argv[])
  37. strerror(errno));
  38. return 1;
  39. }
  40. +
  41. +
  42. switch(action) {
  43. case FILE_CHECK:
  44. c = magic_check(magic, magicfile);
  45. @@ -313,6 +319,15 @@ main(int argc, char *argv[])
  46. if (magic == NULL)
  47. if ((magic = load(magicfile, flags)) == NULL)
  48. return 1;
  49. + if (max_recursion) {
  50. + if (magic_setparam(magic, MAGIC_PARAM_MAX_RECURSION,
  51. + &max_recursion) == -1) {
  52. + (void)fprintf(stderr,
  53. + "%s: Can't set recurision %s\n", progname,
  54. + strerror(errno));
  55. + return 1;
  56. + }
  57. + }
  58. break;
  59. }
  60. diff --git a/src/file.h b/src/file.h
  61. index 6f61643..71a3aeb 100644
  62. --- a/src/file.h
  63. +++ b/src/file.h
  64. @@ -380,6 +380,8 @@ struct magic_set {
  65. /* FIXME: Make the string dynamically allocated so that e.g.
  66. strings matched in files can be longer than MAXstring */
  67. union VALUETYPE ms_value; /* either number or string */
  68. + size_t max_recursion;
  69. +#define FILE_MAX_RECURSION 15
  70. };
  71. /* Type for Unicode characters */
  72. diff --git a/src/file_opts.h b/src/file_opts.h
  73. index 8a17672..4245447 100644
  74. --- a/src/file_opts.h
  75. +++ b/src/file_opts.h
  76. @@ -44,6 +44,7 @@ OPT('0', "print0", 0, " terminate filenames with ASCII NUL\n")
  77. OPT('p', "preserve-date", 0, " preserve access times on files\n")
  78. #endif
  79. OPT('r', "raw", 0, " don't translate unprintable chars to \\ooo\n")
  80. +OPT('R', "recursion", 0, " set maximum recursion level\n")
  81. OPT('s', "special-files", 0, " treat special (block/char devices) files as\n"
  82. " ordinary ones\n")
  83. OPT('C', "compile", 0, " compile file specified by -m\n")
  84. diff --git a/src/magic.c b/src/magic.c
  85. index 5403951..2a916c7 100644
  86. --- a/src/magic.c
  87. +++ b/src/magic.c
  88. @@ -233,6 +233,7 @@ magic_open(int flags)
  89. ms->mlist = NULL;
  90. ms->file = "unknown";
  91. ms->line = 0;
  92. + ms->max_recursion = FILE_MAX_RECURSION;
  93. return ms;
  94. free:
  95. free(ms);
  96. @@ -511,3 +512,29 @@ magic_setflags(struct magic_set *ms, int flags)
  97. ms->flags = flags;
  98. return 0;
  99. }
  100. +
  101. +public int
  102. +magic_setparam(struct magic_set *ms, int param, const void *val)
  103. +{
  104. + switch (param) {
  105. + case MAGIC_PARAM_MAX_RECURSION:
  106. + ms->max_recursion = *(const size_t *)val;
  107. + return 0;
  108. + default:
  109. + errno = EINVAL;
  110. + return -1;
  111. + }
  112. +}
  113. +
  114. +public int
  115. +magic_getparam(struct magic_set *ms, int param, void *val)
  116. +{
  117. + switch (param) {
  118. + case MAGIC_PARAM_MAX_RECURSION:
  119. + *(size_t *)val = ms->max_recursion;
  120. + return 0;
  121. + default:
  122. + errno = EINVAL;
  123. + return -1;
  124. + }
  125. +}
  126. diff --git a/src/magic.h b/src/magic.h
  127. index 2bbed76..3d9ee8a 100644
  128. --- a/src/magic.h
  129. +++ b/src/magic.h
  130. @@ -92,11 +92,17 @@ const char *magic_error(magic_t);
  131. int magic_setflags(magic_t, int);
  132. int magic_load(magic_t, const char *);
  133. +int magic_load_buffers(magic_t, void **, size_t *, size_t);
  134. +
  135. int magic_compile(magic_t, const char *);
  136. int magic_check(magic_t, const char *);
  137. int magic_list(magic_t, const char *);
  138. int magic_errno(magic_t);
  139. +#define MAGIC_PARAM_MAX_RECURSION 0
  140. +int magic_setparam(magic_t, int, const void *);
  141. +int magic_getparam(magic_t, int, void *);
  142. +
  143. #ifdef __cplusplus
  144. };
  145. #endif
  146. diff --git a/src/softmagic.c b/src/softmagic.c
  147. index 0ace99f..188e66b 100644
  148. --- a/src/softmagic.c
  149. +++ b/src/softmagic.c
  150. @@ -43,9 +43,9 @@ FILE_RCSID("@(#)$File: softmagic.c,v 1.147 2011/11/05 15:44:22 rrt Exp $")
  151. private int match(struct magic_set *, struct magic *, uint32_t,
  152. - const unsigned char *, size_t, int, int, int);
  153. + const unsigned char *, size_t, int, int, size_t);
  154. private int mget(struct magic_set *, const unsigned char *,
  155. - struct magic *, size_t, unsigned int, int, int);
  156. + struct magic *, size_t, unsigned int, int, size_t);
  157. private int magiccheck(struct magic_set *, struct magic *);
  158. private int32_t mprint(struct magic_set *, struct magic *);
  159. private int32_t moffset(struct magic_set *, struct magic *);
  160. @@ -62,8 +62,6 @@ private void cvt_64(union VALUETYPE *, const struct magic *);
  161. #define OFFSET_OOB(n, o, i) ((n) < (o) || (i) > ((n) - (o)))
  162. -#define MAX_RECURSION_LEVEL 10
  163. -
  164. /*
  165. * softmagic - lookup one file in parsed, in-memory copy of database
  166. * Passed the name and FILE * of one file to be typed.
  167. @@ -113,7 +111,7 @@ file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes,
  168. private int
  169. match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
  170. const unsigned char *s, size_t nbytes, int mode, int text,
  171. - int recursion_level)
  172. + size_t recursion_level)
  173. {
  174. uint32_t magindex = 0;
  175. unsigned int cont_level = 0;
  176. @@ -1044,7 +1042,7 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
  177. private int
  178. mget(struct magic_set *ms, const unsigned char *s,
  179. struct magic *m, size_t nbytes, unsigned int cont_level, int text,
  180. - int recursion_level)
  181. + size_t recursion_level)
  182. {
  183. uint32_t offset = ms->offset;
  184. file_pushbuf_t *pb;
  185. @@ -1052,10 +1050,11 @@ mget(struct magic_set *ms, const unsigned char *s,
  186. char *rbuf;
  187. union VALUETYPE *p = &ms->ms_value;
  188. - if (recursion_level >= MAX_RECURSION_LEVEL) {
  189. - file_error(ms, 0, "recursion nesting exceeded");
  190. - return -1;
  191. - }
  192. + if (recursion_level >= ms->max_recursion) {
  193. + file_error(ms, 0, "recursion nesting (%zu) exceeded",
  194. + recursion_level);
  195. + return -1;
  196. + }
  197. if (mcopy(ms, p, m->type, m->flag & INDIR, s, offset,
  198. (uint32_t)nbytes, m) == -1)