CVE-2014-3478.patch 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. made apply cleanly based on the following commits:
  2. commit 27a14bc7ba285a0a5ebfdb55e54001aa11932b08
  3. Author: Christos Zoulas <christos@zoulas.com>
  4. Date: Wed Jun 4 17:36:34 2014 +0000
  5. Correctly compute the truncated pascal string size (Francisco Alonso and
  6. Jan Kaluza at RedHat)
  7. commit 2f0eeb07ba633f1d915f78a50b22808123b38ea0
  8. Author: Christos Zoulas <christos@zoulas.com>
  9. Date: Wed Dec 22 18:14:05 2010 +0000
  10. support for various formats of pascal strings.
  11. commit 57e4574e062e538b16b225e822ece6ca0ce539b8
  12. Author: Christos Zoulas <christos@zoulas.com>
  13. Date: Wed Dec 22 19:09:10 2010 +0000
  14. don't undo our initialization
  15. diff --git a/src/softmagic.c b/src/softmagic.c
  16. index 9ba500b..6d69419 100644
  17. --- a/src/softmagic.c
  18. +++ b/src/softmagic.c
  19. @@ -800,10 +800,18 @@ mconvert(struct magic_set *ms, struct magic *m, int flip)
  20. return 1;
  21. }
  22. case FILE_PSTRING: {
  23. - char *ptr1 = p->s, *ptr2 = ptr1 + 1;
  24. - size_t len = *p->s;
  25. + size_t sz = file_pstring_length_size(m);
  26. + char *ptr1 = p->s, *ptr2 = ptr1 + sz;
  27. + size_t len = file_pstring_get_length(m, ptr1);
  28. - if (len >= sizeof(p->s))
  29. - len = sizeof(p->s) - 1;
  30. + if (len >= sizeof(p->s)) {
  31. + /*
  32. + * The size of the pascal string length (sz)
  33. + * is 1, 2, or 4. We need at least 1 byte for NUL
  34. + * termination, but we've already truncated the
  35. + * string by p->s, so we need to deduct sz.
  36. + */
  37. + len = sizeof(p->s) - sz;
  38. + }
  39. while (len--)
  40. *ptr1++ = *ptr2++;
  41. *ptr1 = '\0';
  42. diff --git a/doc/magic.man b/doc/magic.man
  43. index 8486645..299bb8d 100644
  44. --- a/doc/magic.man
  45. +++ b/doc/magic.man
  46. @@ -71,8 +71,22 @@ characters in the magic match both lower and upper case characters in the
  47. target, whereas upper case characters in the magic only match uppercase
  48. characters in the target.
  49. .It Dv pstring
  50. -A Pascal-style string where the first byte is interpreted as the an
  51. +A Pascal-style string where the first byte/short/int is interpreted as the an
  52. unsigned length.
  53. +The length defaults to byte and can be specified as a modifier.
  54. +The following modifiers are supported:
  55. +.Bl -tag -compact -width B
  56. +.It B
  57. +A byte length (default).
  58. +.It H
  59. +A 2 byte big endian length.
  60. +.It h
  61. +A 2 byte big little length.
  62. +.It L
  63. +A 4 byte big endian length.
  64. +.It l
  65. +A 4 byte big little length.
  66. +.El
  67. The string is not NUL terminated.
  68. .It Dv date
  69. A four-byte value interpreted as a UNIX date.
  70. diff --git a/src/apprentice.c b/src/apprentice.c
  71. index 40d547b..1120a69 100644
  72. --- a/src/apprentice.c
  73. +++ b/src/apprentice.c
  74. @@ -932,6 +932,11 @@ string_modifier_check(struct magic_set *ms, struct magic *m)
  75. if ((ms->flags & MAGIC_CHECK) == 0)
  76. return 0;
  77. + if (m->type != FILE_PSTRING && (m->str_flags & PSTRING_LEN) != 0) {
  78. + file_magwarn(ms,
  79. + "'/BHhLl' modifiers are only allowed for pascal strings\n");
  80. + return -1;
  81. + }
  82. switch (m->type) {
  83. case FILE_BESTRING16:
  84. case FILE_LESTRING16:
  85. @@ -1308,7 +1308,7 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
  86. ++l;
  87. }
  88. m->str_range = 0;
  89. - m->str_flags = 0;
  90. + m->str_flags = m->type == FILE_PSTRING ? PSTRING_1_LE : 0;
  91. m->num_mask = 0;
  92. if ((op = get_op(*l)) != -1) {
  93. if (!IS_STRING(m->type)) {
  94. @@ -1362,6 +1362,32 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
  95. case CHAR_TEXTTEST:
  96. m->str_flags |= STRING_TEXTTEST;
  97. break;
  98. + case CHAR_PSTRING_1_LE:
  99. + if (m->type != FILE_PSTRING)
  100. + goto bad;
  101. + m->str_flags |= PSTRING_1_LE;
  102. + break;
  103. + case CHAR_PSTRING_2_BE:
  104. + if (m->type != FILE_PSTRING)
  105. + goto bad;
  106. + m->str_flags |= PSTRING_2_BE;
  107. + break;
  108. + case CHAR_PSTRING_2_LE:
  109. + if (m->type != FILE_PSTRING)
  110. + goto bad;
  111. + m->str_flags |= PSTRING_2_LE;
  112. + break;
  113. + case CHAR_PSTRING_4_BE:
  114. + if (m->type != FILE_PSTRING)
  115. + goto bad;
  116. + m->str_flags |= PSTRING_4_BE;
  117. + break;
  118. + case CHAR_PSTRING_4_LE:
  119. + if (m->type != FILE_PSTRING)
  120. + goto bad;
  121. + m->str_flags |= PSTRING_4_LE;
  122. + break;
  123. + bad:
  124. default:
  125. if (ms->flags & MAGIC_CHECK)
  126. file_magwarn(ms,
  127. @@ -1990,7 +1990,7 @@ out:
  128. *p = '\0';
  129. m->vallen = CAST(unsigned char, (p - origp));
  130. if (m->type == FILE_PSTRING)
  131. - m->vallen++;
  132. + m->vallen += file_pstring_length_size(m);
  133. return s;
  134. }
  135. @@ -2379,3 +2379,40 @@ bs1(struct magic *m)
  136. m->num_mask = swap8(m->num_mask);
  137. }
  138. }
  139. +
  140. +protected size_t
  141. +file_pstring_length_size(const struct magic *m)
  142. +{
  143. + switch (m->str_flags & PSTRING_LEN) {
  144. + case PSTRING_1_LE:
  145. + return 1;
  146. + case PSTRING_2_LE:
  147. + case PSTRING_2_BE:
  148. + return 2;
  149. + case PSTRING_4_LE:
  150. + case PSTRING_4_BE:
  151. + return 4;
  152. + default:
  153. + abort(); /* Impossible */
  154. + return 1;
  155. + }
  156. +}
  157. +protected size_t
  158. +file_pstring_get_length(const struct magic *m, const char *s)
  159. +{
  160. + switch (m->str_flags & PSTRING_LEN) {
  161. + case PSTRING_1_LE:
  162. + return *s;
  163. + case PSTRING_2_LE:
  164. + return (s[1] << 8) | s[0];
  165. + case PSTRING_2_BE:
  166. + return (s[0] << 8) | s[1];
  167. + case PSTRING_4_LE:
  168. + return (s[3] << 24) | (s[2] << 16) | (s[1] << 8) | s[0];
  169. + case PSTRING_4_BE:
  170. + return (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
  171. + default:
  172. + abort(); /* Impossible */
  173. + return 1;
  174. + }
  175. +}
  176. diff --git a/src/file.h b/src/file.h
  177. index 25cd3a5..c84749f 100644
  178. --- a/src/file.h
  179. +++ b/src/file.h
  180. @@ -285,6 +285,14 @@ struct magic {
  181. #define REGEX_OFFSET_START BIT(4)
  182. #define STRING_TEXTTEST BIT(5)
  183. #define STRING_BINTEST BIT(6)
  184. +#define PSTRING_1_BE BIT(7)
  185. +#define PSTRING_1_LE BIT(7)
  186. +#define PSTRING_2_BE BIT(8)
  187. +#define PSTRING_2_LE BIT(9)
  188. +#define PSTRING_4_BE BIT(10)
  189. +#define PSTRING_4_LE BIT(11)
  190. +#define PSTRING_LEN \
  191. + (PSTRING_1_BE|PSTRING_2_LE|PSTRING_2_BE|PSTRING_4_LE|PSTRING_4_BE)
  192. #define CHAR_COMPACT_WHITESPACE 'W'
  193. #define CHAR_COMPACT_OPTIONAL_WHITESPACE 'w'
  194. #define CHAR_IGNORE_LOWERCASE 'c'
  195. @@ -292,6 +292,12 @@ struct magic {
  196. #define CHAR_REGEX_OFFSET_START 's'
  197. #define CHAR_TEXTTEST 't'
  198. #define CHAR_BINTEST 'b'
  199. +#define CHAR_PSTRING_1_BE 'B'
  200. +#define CHAR_PSTRING_1_LE 'B'
  201. +#define CHAR_PSTRING_2_BE 'H'
  202. +#define CHAR_PSTRING_2_LE 'h'
  203. +#define CHAR_PSTRING_4_BE 'L'
  204. +#define CHAR_PSTRING_4_LE 'l'
  205. #define STRING_IGNORE_CASE (STRING_IGNORE_LOWERCASE|STRING_IGNORE_UPPERCASE)
  206. #define STRING_DEFAULT_RANGE 100
  207. @@ -400,6 +400,8 @@ protected ssize_t sread(int, void *, size_t, int);
  208. protected int file_check_mem(struct magic_set *, unsigned int);
  209. protected int file_looks_utf8(const unsigned char *, size_t, unichar *,
  210. size_t *);
  211. +protected size_t file_pstring_length_size(const struct magic *);
  212. +protected size_t file_pstring_get_length(const struct magic *, const char *);
  213. #ifdef __EMX__
  214. protected int file_os2_apptype(struct magic_set *, const char *, const void *,
  215. size_t);
  216. diff --git a/src/softmagic.c b/src/softmagic.c
  217. index a565989..0f15227 100644
  218. --- a/src/softmagic.c
  219. +++ b/src/softmagic.c
  220. @@ -169,6 +169,8 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
  221. continue;
  222. }
  223. + if ((e = handle_annotation(ms, m)) != 0)
  224. + return e;
  225. /*
  226. * If we are going to print something, we'll need to print
  227. * a blank before we print something else.
  228. @@ -176,8 +176,6 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
  229. if (*m->desc) {
  230. need_separator = 1;
  231. printed_something = 1;
  232. - if ((e = handle_annotation(ms, m)) != 0)
  233. - return e;
  234. if (print_sep(ms, firstline) == -1)
  235. return -1;
  236. }
  237. @@ -252,13 +252,13 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
  238. ms->c.li[cont_level].got_match = 0;
  239. break;
  240. }
  241. + if ((e = handle_annotation(ms, m)) != 0)
  242. + return e;
  243. /*
  244. * If we are going to print something,
  245. * make sure that we have a separator first.
  246. */
  247. if (*m->desc) {
  248. - if ((e = handle_annotation(ms, m)) != 0)
  249. - return e;
  250. if (!printed_something) {
  251. printed_something = 1;
  252. if (print_sep(ms, firstline)
  253. @@ -450,7 +450,7 @@ mprint(struct magic_set *ms, struct magic *m)
  254. return -1;
  255. t = ms->offset + strlen(p->s);
  256. if (m->type == FILE_PSTRING)
  257. - t++;
  258. + t += file_pstring_length_size(m);
  259. }
  260. break;
  261. @@ -615,7 +615,7 @@ moffset(struct magic_set *ms, struct magic *m)
  262. p->s[strcspn(p->s, "\n")] = '\0';
  263. t = CAST(uint32_t, (ms->offset + strlen(p->s)));
  264. if (m->type == FILE_PSTRING)
  265. - t++;
  266. + t += file_pstring_length_size(m);
  267. return t;
  268. }
  269. diff --git a/src/apprentice.c b/src/apprentice.c
  270. index 1120a69..c77f679 100644
  271. --- a/src/apprentice.c
  272. +++ b/src/apprentice.c
  273. @@ -1314,7 +1314,6 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
  274. }
  275. m->str_range = 0;
  276. m->str_flags = m->type == FILE_PSTRING ? PSTRING_1_LE : 0;
  277. - m->num_mask = 0;
  278. if ((op = get_op(*l)) != -1) {
  279. if (!IS_STRING(m->type)) {
  280. uint64_t val;
  281. @@ -2402,6 +2402,8 @@ bs1(struct magic *m)
  282. m->in_offset = swap4((uint32_t)m->in_offset);
  283. m->lineno = swap4((uint32_t)m->lineno);
  284. if (IS_STRING(m->type)) {
  285. + if (m->type == FILE_PSTRING)
  286. + printf("flags! %d\n", m->str_flags);
  287. m->str_range = swap4(m->str_range);
  288. m->str_flags = swap4(m->str_flags);
  289. }