]> granicus.if.org Git - file/commitdiff
Add lzma and bzip built-in decompression support (Christoph Biedl)
authorChristos Zoulas <christos@zoulas.com>
Thu, 18 Jul 2019 20:32:06 +0000 (20:32 +0000)
committerChristos Zoulas <christos@zoulas.com>
Thu, 18 Jul 2019 20:32:06 +0000 (20:32 +0000)
configure.ac
src/compress.c
src/seccomp.c

index 0f1077d1d81067ee6faefd6ebdb6c50ae127cd48..96992ec71010b18f0ce4c96f4d3e7d7c096c41d0 100644 (file)
@@ -39,6 +39,16 @@ AC_ARG_ENABLE([zlib],
 [AS_HELP_STRING([--disable-zlib], [disable zlib compression support @<:@default=auto@:>@])])
 AC_MSG_RESULT($enable_zlib)
 
+AC_MSG_CHECKING(for bzlib support)
+AC_ARG_ENABLE([bzlib],
+[AS_HELP_STRING([--disable-bzlib], [disable bz2lib compression support @<:@default=auto@:>@])])
+AC_MSG_RESULT($enable_bzlib)
+
+AC_MSG_CHECKING(for xzlib support)
+AC_ARG_ENABLE([xzlib],
+[AS_HELP_STRING([--disable-xzlib], [disable liblzma/xz compression support @<:@default=auto@:>@])])
+AC_MSG_RESULT($enable_xzlib)
+
 AC_MSG_CHECKING(for libseccomp support)
 AC_ARG_ENABLE([libseccomp],
 [AS_HELP_STRING([--disable-libseccomp], [disable libseccomp sandboxing @<:@default=auto@:>@])])
@@ -97,6 +107,12 @@ AC_CHECK_HEADERS(sys/mman.h sys/stat.h sys/types.h sys/utime.h sys/time.h sys/sy
 if test "$enable_zlib" != "no"; then
   AC_CHECK_HEADERS(zlib.h)
 fi
+if test "$enable_bzlib" != "no"; then
+  AC_CHECK_HEADERS(bzlib.h)
+fi
+if test "$enable_xzlib" != "no"; then
+  AC_CHECK_HEADERS(lzma.h)
+fi
 AC_CHECK_TYPE([sig_t],[AC_DEFINE([HAVE_SIG_T],1,[Have sig_t type])],,[#include <signal.h>])
 
 dnl Checks for typedefs, structures, and compiler characteristics.
@@ -159,6 +175,12 @@ dnl Checks for libraries
 if test "$enable_zlib" != "no"; then
   AC_CHECK_LIB(z, gzopen)
 fi
+if test "$enable_bzlib" != "no"; then
+  AC_CHECK_LIB(bz2, BZ2_bzCompressInit)
+fi
+if test "$enable_xzlib" != "no"; then
+  AC_CHECK_LIB(lzma, lzma_stream_decoder)
+fi
 if test "$enable_libseccomp" != "no"; then
     AC_CHECK_LIB(seccomp, seccomp_init)
 fi
@@ -178,6 +200,22 @@ fi
 if  test "$ac_cv_header_zlib_h$ac_cv_lib_z_gzopen" = "yesyes"; then
   AC_DEFINE([ZLIBSUPPORT], 1, [Enable zlib compression support])
 fi
+if test "$enable_bzlib" = "yes"; then
+  if test "$ac_cv_header_bzlib_h$ac_cv_lib_bz2_BZ2_bzCompressInit" != "yesyes"; then
+    AC_MSG_ERROR([bzlib support requested but not found])
+  fi
+fi
+if  test "$ac_cv_header_bzlib_h$ac_cv_lib_bz2_BZ2_bzCompressInit" = "yesyes"; then
+  AC_DEFINE([BZLIBSUPPORT], 1, [Enable bzlib compression support])
+fi
+if test "$enable_xzlib" = "yes"; then
+  if test "$ac_cv_header_lzma_h$ac_cv_lib_lzma_lzma_stream_decoder" != "yesyes"; then
+    AC_MSG_ERROR([xzlib support requested but not found])
+  fi
+fi
+if  test "$ac_cv_header_lzma_h$ac_cv_lib_lzma_lzma_stream_decoder" = "yesyes"; then
+  AC_DEFINE([XZLIBSUPPORT], 1, [Enable xzlib compression support])
+fi
 
 AC_CONFIG_FILES([Makefile src/Makefile magic/Makefile tests/Makefile doc/Makefile python/Makefile])
 AC_OUTPUT
index 316a165a8718e573d6b1d78330269e929d9eeb9d..db070905ec27f1754f2d07d263de88bede5d9361 100644 (file)
@@ -35,7 +35,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: compress.c,v 1.122 2019/07/18 15:43:54 christos Exp $")
+FILE_RCSID("@(#)$File: compress.c,v 1.123 2019/07/18 20:32:06 christos Exp $")
 #endif
 
 #include "magic.h"
@@ -66,11 +66,16 @@ typedef void (*sig_t)(int);
 #include <zlib.h>
 #endif
 
-#if defined(HAVE_BZLIB_H)
+#if defined(HAVE_BZLIB_H) || defined(BZLIBSUPPORT)
 #define BUILTIN_BZLIB
 #include <bzlib.h>
 #endif
 
+#if defined(HAVE_XZLIB_H) || defined(XZLIBSUPPORT)
+#define BUILTIN_XZLIB
+#include <lzma.h>
+#endif
+
 #ifdef DEBUG
 int tty = -1;
 #define DPRINTF(...)   do { \
@@ -201,7 +206,11 @@ private int uncompressgzipped(const unsigned char *, unsigned char **, size_t,
 #endif
 #ifdef BUILTIN_BZLIB
 private int uncompressbzlib(const unsigned char *, unsigned char **, size_t,
-    size_t *, int);
+    size_t *);
+#endif
+#ifdef BUILTIN_XZLIB
+private int uncompressxzlib(const unsigned char *, unsigned char **, size_t,
+    size_t *);
 #endif
 
 static int makeerror(unsigned char **, size_t *, const char *, ...)
@@ -581,6 +590,90 @@ err:
 }
 #endif
 
+#ifdef BUILTIN_BZLIB
+private int
+uncompressbzlib(const unsigned char *old, unsigned char **newch,
+    size_t bytes_max, size_t *n)
+{
+       int rc;
+       bz_stream bz;
+
+       memset(&bz, 0, sizeof(bz));
+       rc = BZ2_bzDecompressInit(&bz, 0, 0);
+       if (rc != BZ_OK)
+               goto err;
+
+       if ((*newch = CAST(unsigned char *, malloc(bytes_max + 1))) == NULL)
+               return makeerror(newch, n, "No buffer, %s", strerror(errno));
+
+       bz.next_in = CCAST(char *, RCAST(const char *, old));
+       bz.avail_in = CAST(uint32_t, *n);
+       bz.next_out = RCAST(char *, *newch);
+       bz.avail_out = CAST(unsigned int, bytes_max);
+
+       rc = BZ2_bzDecompress(&bz);
+       if (rc != BZ_OK && rc != BZ_STREAM_END)
+               goto err;
+
+       /* Assume byte_max is within 32bit */
+       /* assert(bz.total_out_hi32 == 0); */
+       *n = CAST(size_t, bz.total_out_lo32);
+       rc = BZ2_bzDecompressEnd(&bz);
+       if (rc != BZ_OK)
+               goto err;
+
+       /* let's keep the nul-terminate tradition */
+       (*newch)[*n] = '\0';
+
+       return OKDATA;
+err:
+       snprintf(RCAST(char *, *newch), bytes_max, "bunzip error %d", rc);
+       *n = strlen(RCAST(char *, *newch));
+       return ERRDATA;
+}
+#endif
+
+#ifdef BUILTIN_XZLIB
+private int
+uncompressxzlib(const unsigned char *old, unsigned char **newch,
+    size_t bytes_max, size_t *n)
+{
+       int rc;
+       lzma_stream xz;
+
+       memset(&xz, 0, sizeof(xz));
+       rc = lzma_auto_decoder(&xz, UINT64_MAX, 0);
+       if (rc != LZMA_OK)
+               goto err;
+
+       if ((*newch = CAST(unsigned char *, malloc(bytes_max + 1))) == NULL)
+               return makeerror(newch, n, "No buffer, %s", strerror(errno));
+
+       xz.next_in = CCAST(const uint8_t *, old);
+       xz.avail_in = CAST(uint32_t, *n);
+       xz.next_out = RCAST(uint8_t *, *newch);
+       xz.avail_out = CAST(unsigned int, bytes_max);
+
+       rc = lzma_code(&xz, LZMA_RUN);
+       if (rc != LZMA_OK && rc != LZMA_STREAM_END)
+               goto err;
+
+       *n = CAST(size_t, xz.total_out);
+
+       lzma_end(&xz);
+
+       /* let's keep the nul-terminate tradition */
+       (*newch)[*n] = '\0';
+
+       return OKDATA;
+err:
+       snprintf(RCAST(char *, *newch), bytes_max, "unxz error %d", rc);
+       *n = strlen(RCAST(char *, *newch));
+       return ERRDATA;
+}
+#endif
+
+
 static int
 makeerror(unsigned char **buf, size_t *len, const char *fmt, ...)
 {
@@ -713,6 +806,15 @@ uncompressbuf(int fd, size_t bytes_max, size_t method, const unsigned char *old,
        if (compr[method].maglen == 0)
                return uncompresszlib(old, newch, bytes_max, n, 1);
 #endif
+#ifdef BUILTIN_BZLIB
+       if (method == 7)
+               return uncompressbzlib(old, newch, bytes_max, n);
+#endif
+#ifdef BUILTIN_XZLIB
+       if (method == 9 || method == 13)
+               return uncompressxzlib(old, newch, bytes_max, n);
+#endif
+
        (void)fflush(stdout);
        (void)fflush(stderr);
 
index 54f9be46485197502dd89a776dc70f22c80a1223..902a3eba78621c412bdf0d9adbb653c0e19f66cb 100644 (file)
@@ -27,7 +27,7 @@
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: seccomp.c,v 1.10 2019/07/03 15:33:20 christos Exp $")
+FILE_RCSID("@(#)$File: seccomp.c,v 1.11 2019/07/18 20:32:06 christos Exp $")
 #endif /* lint */
 
 #if HAVE_LIBSECCOMP
@@ -174,6 +174,9 @@ enable_sandbox_full(void)
        ALLOW_RULE(fcntl64);
        ALLOW_RULE(fstat);
        ALLOW_RULE(fstat64);
+#ifdef XZLIBSUPPORT
+       ALLOW_RULE(futex);
+#endif
        ALLOW_RULE(getdents);
 #ifdef __NR_getdents64
        ALLOW_RULE(getdents64);