cherry-pick.FILE5_37-55-gb259a07e.add-lzma-and-bzip-built-in-decompression-support.patch 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. Subject: Add lzma and bzip built-in decompression support
  2. Origin: FILE5_37-55-gb259a07e <https://github.com/file/file/commit/FILE5_37-55-gb259a07e>
  3. Upstream-Author: Christos Zoulas <christos@zoulas.com>
  4. Date: Thu Jul 18 20:32:06 2019 +0000
  5. --- a/configure.ac
  6. +++ b/configure.ac
  7. @@ -39,6 +39,16 @@
  8. [AS_HELP_STRING([--disable-zlib], [disable zlib compression support @<:@default=auto@:>@])])
  9. AC_MSG_RESULT($enable_zlib)
  10. +AC_MSG_CHECKING(for bzlib support)
  11. +AC_ARG_ENABLE([bzlib],
  12. +[AS_HELP_STRING([--disable-bzlib], [disable bz2lib compression support @<:@default=auto@:>@])])
  13. +AC_MSG_RESULT($enable_bzlib)
  14. +
  15. +AC_MSG_CHECKING(for xzlib support)
  16. +AC_ARG_ENABLE([xzlib],
  17. +[AS_HELP_STRING([--disable-xzlib], [disable liblzma/xz compression support @<:@default=auto@:>@])])
  18. +AC_MSG_RESULT($enable_xzlib)
  19. +
  20. AC_MSG_CHECKING(for libseccomp support)
  21. AC_ARG_ENABLE([libseccomp],
  22. [AS_HELP_STRING([--disable-libseccomp], [disable libseccomp sandboxing @<:@default=auto@:>@])])
  23. @@ -97,6 +107,12 @@
  24. if test "$enable_zlib" != "no"; then
  25. AC_CHECK_HEADERS(zlib.h)
  26. fi
  27. +if test "$enable_bzlib" != "no"; then
  28. + AC_CHECK_HEADERS(bzlib.h)
  29. +fi
  30. +if test "$enable_xzlib" != "no"; then
  31. + AC_CHECK_HEADERS(lzma.h)
  32. +fi
  33. AC_CHECK_TYPE([sig_t],[AC_DEFINE([HAVE_SIG_T],1,[Have sig_t type])],,[#include <signal.h>])
  34. dnl Checks for typedefs, structures, and compiler characteristics.
  35. @@ -160,6 +176,12 @@
  36. if test "$enable_zlib" != "no"; then
  37. AC_CHECK_LIB(z, gzopen)
  38. fi
  39. +if test "$enable_bzlib" != "no"; then
  40. + AC_CHECK_LIB(bz2, BZ2_bzCompressInit)
  41. +fi
  42. +if test "$enable_xzlib" != "no"; then
  43. + AC_CHECK_LIB(lzma, lzma_stream_decoder)
  44. +fi
  45. if test "$enable_libseccomp" != "no"; then
  46. AC_CHECK_LIB(seccomp, seccomp_init)
  47. fi
  48. @@ -179,6 +201,22 @@
  49. if test "$ac_cv_header_zlib_h$ac_cv_lib_z_gzopen" = "yesyes"; then
  50. AC_DEFINE([ZLIBSUPPORT], 1, [Enable zlib compression support])
  51. fi
  52. +if test "$enable_bzlib" = "yes"; then
  53. + if test "$ac_cv_header_bzlib_h$ac_cv_lib_bz2_BZ2_bzCompressInit" != "yesyes"; then
  54. + AC_MSG_ERROR([bzlib support requested but not found])
  55. + fi
  56. +fi
  57. +if test "$ac_cv_header_bzlib_h$ac_cv_lib_bz2_BZ2_bzCompressInit" = "yesyes"; then
  58. + AC_DEFINE([BZLIBSUPPORT], 1, [Enable bzlib compression support])
  59. +fi
  60. +if test "$enable_xzlib" = "yes"; then
  61. + if test "$ac_cv_header_lzma_h$ac_cv_lib_lzma_lzma_stream_decoder" != "yesyes"; then
  62. + AC_MSG_ERROR([xzlib support requested but not found])
  63. + fi
  64. +fi
  65. +if test "$ac_cv_header_lzma_h$ac_cv_lib_lzma_lzma_stream_decoder" = "yesyes"; then
  66. + AC_DEFINE([XZLIBSUPPORT], 1, [Enable xzlib compression support])
  67. +fi
  68. AC_CONFIG_FILES([Makefile src/Makefile magic/Makefile tests/Makefile doc/Makefile python/Makefile])
  69. AC_OUTPUT
  70. --- a/src/compress.c
  71. +++ b/src/compress.c
  72. @@ -66,11 +66,16 @@
  73. #include <zlib.h>
  74. #endif
  75. -#if defined(HAVE_BZLIB_H)
  76. +#if defined(HAVE_BZLIB_H) || defined(BZLIBSUPPORT)
  77. #define BUILTIN_BZLIB
  78. #include <bzlib.h>
  79. #endif
  80. +#if defined(HAVE_XZLIB_H) || defined(XZLIBSUPPORT)
  81. +#define BUILTIN_XZLIB
  82. +#include <lzma.h>
  83. +#endif
  84. +
  85. #ifdef DEBUG
  86. int tty = -1;
  87. #define DPRINTF(...) do { \
  88. @@ -201,7 +206,11 @@
  89. #endif
  90. #ifdef BUILTIN_BZLIB
  91. private int uncompressbzlib(const unsigned char *, unsigned char **, size_t,
  92. - size_t *, int);
  93. + size_t *);
  94. +#endif
  95. +#ifdef BUILTIN_XZLIB
  96. +private int uncompressxzlib(const unsigned char *, unsigned char **, size_t,
  97. + size_t *);
  98. #endif
  99. static int makeerror(unsigned char **, size_t *, const char *, ...)
  100. @@ -581,6 +590,90 @@
  101. }
  102. #endif
  103. +#ifdef BUILTIN_BZLIB
  104. +private int
  105. +uncompressbzlib(const unsigned char *old, unsigned char **newch,
  106. + size_t bytes_max, size_t *n)
  107. +{
  108. + int rc;
  109. + bz_stream bz;
  110. +
  111. + memset(&bz, 0, sizeof(bz));
  112. + rc = BZ2_bzDecompressInit(&bz, 0, 0);
  113. + if (rc != BZ_OK)
  114. + goto err;
  115. +
  116. + if ((*newch = CAST(unsigned char *, malloc(bytes_max + 1))) == NULL)
  117. + return makeerror(newch, n, "No buffer, %s", strerror(errno));
  118. +
  119. + bz.next_in = CCAST(char *, RCAST(const char *, old));
  120. + bz.avail_in = CAST(uint32_t, *n);
  121. + bz.next_out = RCAST(char *, *newch);
  122. + bz.avail_out = CAST(unsigned int, bytes_max);
  123. +
  124. + rc = BZ2_bzDecompress(&bz);
  125. + if (rc != BZ_OK && rc != BZ_STREAM_END)
  126. + goto err;
  127. +
  128. + /* Assume byte_max is within 32bit */
  129. + /* assert(bz.total_out_hi32 == 0); */
  130. + *n = CAST(size_t, bz.total_out_lo32);
  131. + rc = BZ2_bzDecompressEnd(&bz);
  132. + if (rc != BZ_OK)
  133. + goto err;
  134. +
  135. + /* let's keep the nul-terminate tradition */
  136. + (*newch)[*n] = '\0';
  137. +
  138. + return OKDATA;
  139. +err:
  140. + snprintf(RCAST(char *, *newch), bytes_max, "bunzip error %d", rc);
  141. + *n = strlen(RCAST(char *, *newch));
  142. + return ERRDATA;
  143. +}
  144. +#endif
  145. +
  146. +#ifdef BUILTIN_XZLIB
  147. +private int
  148. +uncompressxzlib(const unsigned char *old, unsigned char **newch,
  149. + size_t bytes_max, size_t *n)
  150. +{
  151. + int rc;
  152. + lzma_stream xz;
  153. +
  154. + memset(&xz, 0, sizeof(xz));
  155. + rc = lzma_auto_decoder(&xz, UINT64_MAX, 0);
  156. + if (rc != LZMA_OK)
  157. + goto err;
  158. +
  159. + if ((*newch = CAST(unsigned char *, malloc(bytes_max + 1))) == NULL)
  160. + return makeerror(newch, n, "No buffer, %s", strerror(errno));
  161. +
  162. + xz.next_in = CCAST(const uint8_t *, old);
  163. + xz.avail_in = CAST(uint32_t, *n);
  164. + xz.next_out = RCAST(uint8_t *, *newch);
  165. + xz.avail_out = CAST(unsigned int, bytes_max);
  166. +
  167. + rc = lzma_code(&xz, LZMA_RUN);
  168. + if (rc != LZMA_OK && rc != LZMA_STREAM_END)
  169. + goto err;
  170. +
  171. + *n = CAST(size_t, xz.total_out);
  172. +
  173. + lzma_end(&xz);
  174. +
  175. + /* let's keep the nul-terminate tradition */
  176. + (*newch)[*n] = '\0';
  177. +
  178. + return OKDATA;
  179. +err:
  180. + snprintf(RCAST(char *, *newch), bytes_max, "unxz error %d", rc);
  181. + *n = strlen(RCAST(char *, *newch));
  182. + return ERRDATA;
  183. +}
  184. +#endif
  185. +
  186. +
  187. static int
  188. makeerror(unsigned char **buf, size_t *len, const char *fmt, ...)
  189. {
  190. @@ -713,6 +806,15 @@
  191. if (compr[method].maglen == 0)
  192. return uncompresszlib(old, newch, bytes_max, n, 1);
  193. #endif
  194. +#ifdef BUILTIN_BZLIB
  195. + if (method == 7)
  196. + return uncompressbzlib(old, newch, bytes_max, n);
  197. +#endif
  198. +#ifdef BUILTIN_XZLIB
  199. + if (method == 9 || method == 13)
  200. + return uncompressxzlib(old, newch, bytes_max, n);
  201. +#endif
  202. +
  203. (void)fflush(stdout);
  204. (void)fflush(stderr);
  205. --- a/src/seccomp.c
  206. +++ b/src/seccomp.c
  207. @@ -174,6 +174,9 @@
  208. ALLOW_RULE(fcntl64);
  209. ALLOW_RULE(fstat);
  210. ALLOW_RULE(fstat64);
  211. +#ifdef XZLIBSUPPORT
  212. + ALLOW_RULE(futex);
  213. +#endif
  214. ALLOW_RULE(getdents);
  215. #ifdef __NR_getdents64
  216. ALLOW_RULE(getdents64);