Package: release.debian.org User: release.debian....@packages.debian.org Usertags: pu Tags: stretch Severity: normal
This is my proposed update libclamunrar in Stretch. I updated from old version + patches to the latest clamav release and was able to drop all patches. The changelog for 0.100.1 stated: Buffer over-read in unRAR code due to missing max value checks in table initialization. Reported by Rui Reis. I don't know if this "just" an over read and nothing bad happens or if a segfault is possible. The 0.100.0 changelog did not state any unrar related changes but they made a few changes with no explanation. I feel more comfortable to sychnronize with latest version as released by clamav. Please find a debdiff attached which has the autoconf and m4 changes removed. Sebastian
diff --git a/configure.ac b/configure.ac index 85aa6a7604e1..4994c10e66f1 100644 --- a/configure.ac +++ b/configure.ac @@ -20,7 +20,7 @@ dnl MA 02110-1301, USA. AC_PREREQ([2.59]) dnl For a release change [devel] to the real version [0.xy] dnl also change VERSION below -AC_INIT([ClamAV], [0.99], [http://bugs.clamav.net/], [clamav], [http://www.clamav.net/]) +AC_INIT([ClamAV], [0.100.1], [https://bugzilla.clamav.net/], [clamav], [https://www.clamav.net/]) AH_BOTTOM([#include "platform.h"]) dnl put configure auxiliary into config @@ -74,6 +74,7 @@ m4_include([m4/reorganization/code_checks/coverage.m4]) dnl libclamav dependencies m4_include([m4/reorganization/libs/xml.m4]) +m4_include([m4/reorganization/libs/openssl.m4]) m4_include([m4/reorganization/libs/json.m4]) m4_include([m4/reorganization/libs/pcre.m4]) @@ -81,6 +82,7 @@ AM_MAINTAINER_MODE m4_include([m4/reorganization/libs/libz.m4]) m4_include([m4/reorganization/libs/bzip.m4]) m4_include([m4/reorganization/libs/unrar.m4]) +m4_include([m4/reorganization/libs/systemd.m4]) m4_include([m4/reorganization/code_checks/ipv6.m4]) m4_include([m4/reorganization/code_checks/dns.m4]) m4_include([m4/reorganization/code_checks/fanotify.m4]) @@ -115,18 +117,26 @@ m4_include([m4/reorganization/code_checks/shift.m4]) m4_include([m4/reorganization/code_checks/features.m4]) m4_include([m4/reorganization/clamdtop.m4]) m4_include([m4/reorganization/distcheck.m4]) -m4_include([m4/reorganization/llvm.m4]) m4_include([m4/reorganization/sha_collect.m4]) m4_include([m4/reorganization/yara.m4]) - +m4_include([m4/reorganization/code_checks/fts.m4]) +m4_include([m4/reorganization/libfreshclam.m4]) +m4_include([m4/reorganization/prelude.m4]) m4_include([m4/reorganization/bsd.m4]) dnl Freshclam dependencies m4_include([m4/reorganization/libs/curl.m4]) - m4_include([m4/reorganization/substitutions.m4]) +m4_include([m4/reorganization/strni.m4]) + +if test "x$use_internal_mspack" = "xyes"; then + mspack_msg="Internal" + AC_CONFIG_SUBDIRS([libclamav/libmspack-0.5alpha]) + AC_SYS_LARGEFILE +else + mspack_msg="External, $LIBMSPACK_CFLAGS $LIBMSPACK_LIBS" +fi -AM_CONDITIONAL([ENABLE_CLAMSUBMIT], [test "$have_curl" = "yes"]) AC_CONFIG_FILES([ libclamunrar_iface/Makefile @@ -148,6 +158,8 @@ AM_CONDITIONAL([ENABLE_LLVM], [test "$subdirfailed" != "yes" && test "$enable_llvm" != "no"]) AM_CONDITIONAL([ENABLE_YARA], [test "$enable_yara" != "no"]) +AM_CONDITIONAL([ENABLE_CLAMSUBMIT], + [test "X$have_curl" = "Xyes" && test "X$have_json" = "Xyes"]) no_recursion="yes"; @@ -166,7 +178,7 @@ else check_libs="$CHECK_LIBS" fi CL_MSG_STATUS([check ],[$check_libs],[$enable_check_ut]) -CL_MSG_STATUS([fanotify ],[$want_fanotify],[$want_fanotify]) +CL_MSG_STATUS([fanotify ],[$have_fanotify],[$have_fanotify]) if test "x$ac_cv_have_control_in_msghdr" = "xyes"; then CL_MSG_STATUS([fdpassing ],[$have_fdpass],[$want_fdpassing]) else @@ -177,7 +189,19 @@ CL_MSG_STATUS([IPv6 ],[$have_cv_ipv6],[$want_ipv6]) AC_MSG_NOTICE([Summary of optional tools]) CL_MSG_STATUS([clamdtop ],[$CURSES_LIBS],[$enable_clamdtop]) CL_MSG_STATUS([milter ],[yes],[$have_milter]) -CL_MSG_STATUS([clamsubmit ],[$have_curl],[$curl_msg]) +if test "X$have_curl" = "Xyes" && test "X$have_json" = "Xyes"; then + CL_MSG_STATUS([clamsubmit ], [yes (libjson-c-dev found at $LIBJSON_HOME), libcurl-devel found at $LIBCURL_HOME)], [yes]) +else + if test "X$have_curl" != "Xyes" && test "X$have_json" != "Xyes"; then + CL_MSG_STATUS([clamsubmit ], [no (missing libjson-c-dev AND libcurl-devel. Use the website to submit FPs/FNs.)], [no]) + else + if test "X$have_curl" = "Xyes"; then + CL_MSG_STATUS([clamsubmit ], [no (missing libjson-c-dev. Use the website to submit FPs/FNs.)], [no]) + else + CL_MSG_STATUS([clamsubmit ], [no (missing libcurl-devel. Use the website to submit FPs/FNs.)], [no]) + fi + fi +fi AC_MSG_NOTICE([Summary of engine performance features]) if test "x$enable_debug" = "xyes"; then @@ -189,10 +213,12 @@ have_jit="no" if test "$subdirfailed" = "no"; then have_jit="yes" fi -if test "x$llvm_linking" = "x"; then - CL_MSG_STATUS([llvm ],[$have_jit, from $system_llvm],[$enable_llvm]) +if test "$enable_llvm" = "no"; then + CL_MSG_STATUS([llvm ],[$have_jit],[$enable_llvm]) +elif test "x$llvmconfig" = "x"; then + CL_MSG_STATUS([llvm ],[$have_jit ($llvmver), from internal],[$enable_llvm]) else - CL_MSG_STATUS([llvm ],[$have_jit, from $system_llvm ($llvm_linking)],[$enable_llvm]) + CL_MSG_STATUS([llvm ],[$have_jit ($llvmver), from $llvmconfig ($llvm_linking)],[$enable_llvm]) fi CL_MSG_STATUS([mempool ],[$have_mempool],[$enable_mempool]) @@ -200,20 +226,25 @@ AC_MSG_NOTICE([Summary of engine detection features]) CL_MSG_STATUS([bzip2 ],[$bzip_check],[$want_bzip2]) CL_MSG_STATUS([zlib ],[$ZLIB_HOME],[yes]) CL_MSG_STATUS([unrar ],[$want_unrar],[$want_unrar]) -if test "x$LIBJSON_HOME" != "x"; then - CL_MSG_STATUS([libjson ],[$LIBJSON_HOME],[$have_json]) +if test "X$have_json" = "Xyes"; then + CL_MSG_STATUS([preclass ],[yes (libjson-c-dev found at $LIBJSON_HOME)],[yes]) +else + CL_MSG_STATUS([preclass ],[no (missing libjson-c-dev)],[no]) fi if test "x$PCRE_HOME" = "x"; then CL_MSG_STATUS([pcre ],[no],[$have_pcre]) else CL_MSG_STATUS([pcre ],[$PCRE_HOME],[$have_pcre]) fi +CL_MSG_STATUS([libmspack ],[yes],[$mspack_msg]) if test "x$XML_LIBS" = "x"; then CL_MSG_STATUS([libxml2 ],[no],[]) else CL_MSG_STATUS([libxml2 ],[yes, from $XML_HOME],[]) fi CL_MSG_STATUS([yara ],[$enable_yara],[$enable_yara]) +CL_MSG_STATUS([fts ],[yes],[$lfs_fts_msg]) + # Yep, downgrading the compiler avoids the bug too: # 4.0.x, and 4.1.0 are the known buggy versions diff --git a/debian/changelog b/debian/changelog index 41eebea1f85b..31692b60a46f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,17 @@ +libclamunrar (0.100.1-0+deb9u1) stretch; urgency=medium + + [ Sebastian Andrzej Siewior ] + * New upstream version + - Buffer over-read in unRAR code due to missing max value checks in table + initialization. Reported by Rui Reis. + - drop all patches (were picked from upstream, the openssl patch is + obsolete). + + [ Scott Kitterman ] + * Delete symlinks to files no longer shipped in libclamav7 (Closes: #903792) + + -- Sebastian Andrzej Siewior <sebast...@breakpoint.cc> Sat, 21 Jul 2018 18:25:22 +0200 + libclamunrar (0.99-3+deb9u1) stretch; urgency=medium * Team upload. diff --git a/debian/libclamunrar7.links b/debian/libclamunrar7.links index 876ecb03db8e..300ea38600bb 100644 --- a/debian/libclamunrar7.links +++ b/debian/libclamunrar7.links @@ -1,7 +1,2 @@ -/usr/share/doc/libclamav7/AUTHORS /usr/share/doc/libclamunrar7/AUTHORS -/usr/share/doc/libclamav7/BUGS /usr/share/doc/libclamunrar7/BUGS -/usr/share/doc/libclamav7/FAQ /usr/share/doc/libclamunrar7/FAQ -/usr/share/doc/libclamav7/README.gz /usr/share/doc/libclamunrar7/README.gz /usr/share/doc/libclamav7/README.Debian.gz /usr/share/doc/libclamunrar7/README.Debian.gz /usr/share/doc/libclamav7/NEWS.Debian.gz /usr/share/doc/libclamunrar7/NEWS.Debian.gz -/usr/share/doc/libclamav7/changelog.gz /usr/share/doc/libclamunrar7/changelog.gz diff --git a/debian/patches/bb11600.patch b/debian/patches/bb11600.patch deleted file mode 100644 index cbb384fff6fb..000000000000 --- a/debian/patches/bb11600.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 155190a0a5000ffb0b516c04a1a9091a5c4dc2b3 Mon Sep 17 00:00:00 2001 -From: Steven Morgan <smor...@sourcefire.com> -Date: Tue, 12 Jul 2016 12:36:29 -0400 -Subject: bb11600 - fix out of bounds stack read. - -Patch-Name: bb11600.patch ---- - libclamunrar/unrar20.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/libclamunrar/unrar20.c b/libclamunrar/unrar20.c -index ecfe40cf32f3..d938c472e1d8 100644 ---- a/libclamunrar/unrar20.c -+++ b/libclamunrar/unrar20.c -@@ -117,7 +117,8 @@ static int read_tables20(int fd, unpack_data_t *unpack_data) - n = (rar_getbits(unpack_data) >> 14) + 3; - rar_addbits(unpack_data, 2); - while ((n-- > 0) && (i < table_size)) { -- table[i] = table[i-1]; -+ if (i>0) -+ table[i] = table[i-1]; - i++; - } - } else { diff --git a/debian/patches/bb11600_pt2.patch b/debian/patches/bb11600_pt2.patch deleted file mode 100644 index 2cf8f8156d8b..000000000000 --- a/debian/patches/bb11600_pt2.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 4ba0a93c2887e5cea285ab0dbd8254b4d1fd33e7 Mon Sep 17 00:00:00 2001 -From: Steven Morgan <smor...@sourcefire.com> -Date: Tue, 12 Jul 2016 14:31:38 -0400 -Subject: fix possible out of bounds stack read. - -Patch-Name: bb11600_pt2.patch ---- - libclamunrar/unrar.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/libclamunrar/unrar.c b/libclamunrar/unrar.c -index 456da4d6fef9..40a3d63cbd3e 100644 ---- a/libclamunrar/unrar.c -+++ b/libclamunrar/unrar.c -@@ -469,7 +469,8 @@ static int read_tables(int fd, unpack_data_t *unpack_data) - rar_addbits(unpack_data, 7); - } - while (n-- > 0 && i < table_size) { -- table[i] = table[i-1]; -+ if (i>0) -+ table[i] = table[i-1]; - i++; - } - } else { diff --git a/debian/patches/bb11601.patch b/debian/patches/bb11601.patch deleted file mode 100644 index ddb14a3530cb..000000000000 --- a/debian/patches/bb11601.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 337277a57bf9c568861b31fcb06f7aeff5e66a8a Mon Sep 17 00:00:00 2001 -From: Steven Morgan <smor...@sourcefire.com> -Date: Wed, 13 Jul 2016 14:27:10 -0400 -Subject: bb11601 - check array boundaries in unrarvm rarvm_getbits(). - -Patch-Name: bb11601.patch ---- - libclamunrar/unrarvm.c | 13 ++++++++----- - 1 file changed, 8 insertions(+), 5 deletions(-) - -diff --git a/libclamunrar/unrarvm.c b/libclamunrar/unrarvm.c -index 29944cbea82a..1cf5bb629952 100644 ---- a/libclamunrar/unrarvm.c -+++ b/libclamunrar/unrarvm.c -@@ -215,12 +215,15 @@ unsigned int rarvm_getbits(rarvm_input_t *rarvm_input) - { - unsigned int bit_field; - -- bit_field = (unsigned int) rarvm_input->in_buf[rarvm_input->in_addr] << 16; -- bit_field |= (unsigned int) rarvm_input->in_buf[rarvm_input->in_addr+1] << 8; -- bit_field |= (unsigned int) rarvm_input->in_buf[rarvm_input->in_addr+2]; -- bit_field >>= (8-rarvm_input->in_bit); -+ if (rarvm_input->in_addr+2 < rarvm_input->buf_size) { -+ bit_field = (unsigned int) rarvm_input->in_buf[rarvm_input->in_addr] << 16; -+ bit_field |= (unsigned int) rarvm_input->in_buf[rarvm_input->in_addr+1] << 8; -+ bit_field |= (unsigned int) rarvm_input->in_buf[rarvm_input->in_addr+2]; -+ bit_field >>= (8-rarvm_input->in_bit); - -- return (bit_field & 0xffff); -+ return (bit_field & 0xffff); -+ } -+ return 0; - } - - unsigned int rarvm_read_data(rarvm_input_t *rarvm_input) diff --git a/debian/patches/bb11601_pt2.patch b/debian/patches/bb11601_pt2.patch deleted file mode 100644 index 3db672c3d0a3..000000000000 --- a/debian/patches/bb11601_pt2.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0b977ab3aaecd1e2e434474f30288eea3c029fe0 Mon Sep 17 00:00:00 2001 -From: Steven Morgan <stevm...@cisco.com> -Date: Wed, 14 Dec 2016 13:29:00 -0500 -Subject: bb11601 - revise buffer limit check due. - -Patch-Name: bb11601_pt2.patch ---- - libclamunrar/unrarvm.c | 19 +++++++++++-------- - 1 file changed, 11 insertions(+), 8 deletions(-) - -diff --git a/libclamunrar/unrarvm.c b/libclamunrar/unrarvm.c -index 1cf5bb629952..102fe2ebf044 100644 ---- a/libclamunrar/unrarvm.c -+++ b/libclamunrar/unrarvm.c -@@ -213,17 +213,20 @@ void rarvm_addbits(rarvm_input_t *rarvm_input, int bits) - - unsigned int rarvm_getbits(rarvm_input_t *rarvm_input) - { -- unsigned int bit_field; -+ unsigned int bit_field = 0; - -- if (rarvm_input->in_addr+2 < rarvm_input->buf_size) { -+ if (rarvm_input->in_addr < rarvm_input->buf_size) { - bit_field = (unsigned int) rarvm_input->in_buf[rarvm_input->in_addr] << 16; -- bit_field |= (unsigned int) rarvm_input->in_buf[rarvm_input->in_addr+1] << 8; -- bit_field |= (unsigned int) rarvm_input->in_buf[rarvm_input->in_addr+2]; -- bit_field >>= (8-rarvm_input->in_bit); -- -- return (bit_field & 0xffff); -+ if (rarvm_input->in_addr+1 < rarvm_input->buf_size) { -+ bit_field |= (unsigned int) rarvm_input->in_buf[rarvm_input->in_addr+1] << 8; -+ if (rarvm_input->in_addr+2 < rarvm_input->buf_size) { -+ bit_field |= (unsigned int) rarvm_input->in_buf[rarvm_input->in_addr+2]; -+ } -+ } - } -- return 0; -+ bit_field >>= (8-rarvm_input->in_bit); -+ -+ return (bit_field & 0xffff); - } - - unsigned int rarvm_read_data(rarvm_input_t *rarvm_input) diff --git a/debian/patches/drop_openssl_check.patch b/debian/patches/drop_openssl_check.patch deleted file mode 100644 index 7c31b9fcdd15..000000000000 --- a/debian/patches/drop_openssl_check.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 184363c715fee85c3f80f10a34d8f57605e462c0 Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior <sebast...@breakpoint.cc> -Date: Thu, 3 Nov 2016 21:38:20 +0100 -Subject: drop openssl check - -We don't really need openssl in libclamunrar. It is only there -because clamav needs it and the configure script is copied while -the package is split. This patch can be dropped once we move to -0.99.3 which detects openssl 1.1.0 properly. - -Patch-Name: drop_openssl_check.patch - -Signed-off-by: Sebastian Andrzej Siewior <sebast...@breakpoint.cc> ---- - configure.ac | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/configure.ac b/configure.ac -index 0f1cdbaef3b2..85aa6a7604e1 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -74,7 +74,6 @@ m4_include([m4/reorganization/code_checks/coverage.m4]) - - dnl libclamav dependencies - m4_include([m4/reorganization/libs/xml.m4]) --m4_include([m4/reorganization/libs/openssl.m4]) - m4_include([m4/reorganization/libs/json.m4]) - m4_include([m4/reorganization/libs/pcre.m4]) - diff --git a/debian/patches/series b/debian/patches/series deleted file mode 100644 index 482d6fb84608..000000000000 --- a/debian/patches/series +++ /dev/null @@ -1,6 +0,0 @@ -bb11600.patch -bb11600_pt2.patch -bb11601.patch -drop_openssl_check.patch -bb11601_pt2.patch -unrar-adding-proposed-changes-to-fix-RAR-VMSF_DELTA-.patch diff --git a/debian/patches/unrar-adding-proposed-changes-to-fix-RAR-VMSF_DELTA-.patch b/debian/patches/unrar-adding-proposed-changes-to-fix-RAR-VMSF_DELTA-.patch deleted file mode 100644 index 17d19c99afca..000000000000 --- a/debian/patches/unrar-adding-proposed-changes-to-fix-RAR-VMSF_DELTA-.patch +++ /dev/null @@ -1,173 +0,0 @@ -From 890a88f7d593eb6f3a13200103c6e49313eca3f1 Mon Sep 17 00:00:00 2001 -From: Mickey Sola <ms...@sourcefire.com> -Date: Thu, 29 Jun 2017 14:02:03 -0400 -Subject: unrar - adding proposed changes to fix RAR VMSF_DELTA Filter - Signedness error - -CVE: CVE-2012-6706: arbitrary memory write -BTS: #867223 -Patch-Name: unrar-adding-proposed-changes-to-fix-RAR-VMSF_DELTA-.patch ---- - libclamunrar/unrarvm.c | 55 ++++++++++++++++++++++++++------------------------ - 1 file changed, 29 insertions(+), 26 deletions(-) - -diff --git a/libclamunrar/unrarvm.c b/libclamunrar/unrarvm.c -index 102fe2ebf044..b21e242fa72b 100644 ---- a/libclamunrar/unrarvm.c -+++ b/libclamunrar/unrarvm.c -@@ -213,9 +213,9 @@ void rarvm_addbits(rarvm_input_t *rarvm_input, int bits) - - unsigned int rarvm_getbits(rarvm_input_t *rarvm_input) - { -- unsigned int bit_field = 0; -+ unsigned int bit_field = 0; - -- if (rarvm_input->in_addr < rarvm_input->buf_size) { -+ if (rarvm_input->in_addr < rarvm_input->buf_size) { - bit_field = (unsigned int) rarvm_input->in_buf[rarvm_input->in_addr] << 16; - if (rarvm_input->in_addr+1 < rarvm_input->buf_size) { - bit_field |= (unsigned int) rarvm_input->in_buf[rarvm_input->in_addr+1] << 8; -@@ -314,10 +314,10 @@ static unsigned int *rarvm_get_operand(rarvm_data_t *rarvm_data, - } - } - --static unsigned int filter_itanium_getbits(unsigned char *data, int bit_pos, int bit_count) -+static unsigned int filter_itanium_getbits(unsigned char *data, unsigned int bit_pos, unsigned int bit_count) - { -- int in_addr=bit_pos/8; -- int in_bit=bit_pos&7; -+ unsigned int in_addr=bit_pos/8; -+ unsigned int in_bit=bit_pos&7; - unsigned int bit_field=(unsigned int)data[in_addr++]; - bit_field|=(unsigned int)data[in_addr++] << 8; - bit_field|=(unsigned int)data[in_addr++] << 16; -@@ -326,10 +326,10 @@ static unsigned int filter_itanium_getbits(unsigned char *data, int bit_pos, int - return(bit_field & (0xffffffff>>(32-bit_count))); - } - --static void filter_itanium_setbits(unsigned char *data, unsigned int bit_field, int bit_pos, int bit_count) -+static void filter_itanium_setbits(unsigned char *data, unsigned int bit_field, unsigned int bit_pos, unsigned int bit_count) - { -- int i, in_addr=bit_pos/8; -- int in_bit=bit_pos&7; -+ unsigned int i, in_addr=bit_pos/8; -+ unsigned int in_bit=bit_pos&7; - unsigned int and_mask=0xffffffff>>(32-bit_count); - and_mask=~(and_mask<<in_bit); - -@@ -346,11 +346,12 @@ static void filter_itanium_setbits(unsigned char *data, unsigned int bit_field, - static void execute_standard_filter(rarvm_data_t *rarvm_data, rarvm_standard_filters_t filter_type) - { - unsigned char *data, cmp_byte2, cur_byte, *src_data, *dest_data; -- int i, j, data_size, channels, src_pos, dest_pos, border, width, PosR; -- int op_type, cur_channel, byte_count, start_pos, pa, pb, pc; -+ unsigned int i, j, data_size, channels, src_pos, dest_pos, border, width, PosR; -+ unsigned int op_type, cur_channel, byte_count, start_pos; -+ int pa, pb, pc; - unsigned int file_offset, cur_pos, predicted; -- int32_t offset, addr; -- const int file_size=0x1000000; -+ uint32_t offset, addr; -+ const unsigned int file_size=0x1000000; - - switch(filter_type) { - case VMSF_E8: -@@ -359,7 +360,7 @@ static void execute_standard_filter(rarvm_data_t *rarvm_data, rarvm_standard_fil - data_size = rarvm_data->R[4]; - file_offset = rarvm_data->R[6]; - -- if (((unsigned int)data_size >= VM_GLOBALMEMADDR) || (data_size < 4)) { -+ if ((data_size > VM_GLOBALMEMADDR) || (data_size < 4)) { - break; - } - -@@ -370,12 +371,14 @@ static void execute_standard_filter(rarvm_data_t *rarvm_data, rarvm_standard_fil - if (cur_byte==0xe8 || cur_byte==cmp_byte2) { - offset = cur_pos+file_offset; - addr = GET_VALUE(FALSE, data); -- if (addr < 0) { -- if (addr+offset >=0 ) { -+ // We check 0x80000000 bit instead of '< 0' comparison -+ // not assuming int32 presence or uint size and endianness. -+ if ((addr & 0x80000000)!=0) { // addr<0 -+ if (((addr+offset) & 0x80000000)==0) { // addr+offset>=0 - SET_VALUE(FALSE, data, addr+file_size); - } - } else { -- if (addr<file_size) { -+ if (((addr-file_size) & 0x80000000)!=0) { // addr<file_size - SET_VALUE(FALSE, data, addr-offset); - } - } -@@ -389,7 +392,7 @@ static void execute_standard_filter(rarvm_data_t *rarvm_data, rarvm_standard_fil - data_size = rarvm_data->R[4]; - file_offset = rarvm_data->R[6]; - -- if (((unsigned int)data_size >= VM_GLOBALMEMADDR) || (data_size < 21)) { -+ if ((data_size > VM_GLOBALMEMADDR) || (data_size < 21)) { - break; - } - -@@ -432,7 +435,7 @@ static void execute_standard_filter(rarvm_data_t *rarvm_data, rarvm_standard_fil - border = data_size*2; - - SET_VALUE(FALSE, &rarvm_data->mem[VM_GLOBALMEMADDR+0x20], data_size); -- if ((unsigned int)data_size >= VM_GLOBALMEMADDR/2) { -+ if (data_size > VM_GLOBALMEMADDR/2 || channels > 1024 || channels == 0) { - break; - } - for (cur_channel=0 ; cur_channel < channels ; cur_channel++) { -@@ -443,7 +446,7 @@ static void execute_standard_filter(rarvm_data_t *rarvm_data, rarvm_standard_fil - } - break; - case VMSF_RGB: { -- const int channels=3; -+ const unsigned int channels=3; - data_size = rarvm_data->R[4]; - width = rarvm_data->R[0] - 3; - PosR = rarvm_data->R[1]; -@@ -451,15 +454,14 @@ static void execute_standard_filter(rarvm_data_t *rarvm_data, rarvm_standard_fil - dest_data = src_data + data_size; - - SET_VALUE(FALSE, &rarvm_data->mem[VM_GLOBALMEMADDR+0x20], data_size); -- if ((unsigned int)data_size >= VM_GLOBALMEMADDR/2) { -+ if (data_size > VM_GLOBALMEMADDR/2 || data_size < 3 || width > data_size || PosR > 2) { - break; - } - for (cur_channel=0 ; cur_channel < channels; cur_channel++) { - unsigned int prev_byte = 0; - for (i=cur_channel ; i<data_size ; i+=channels) { -- int upper_pos=i-width; -- if (upper_pos >= 3) { -- unsigned char *upper_data = dest_data+upper_pos; -+ if (i >= width+3) { -+ unsigned char *upper_data = dest_data+i-width; - unsigned int upper_byte = *upper_data; - unsigned int upper_left_byte = *(upper_data-3); - predicted = prev_byte+upper_byte-upper_left_byte; -@@ -489,13 +491,14 @@ static void execute_standard_filter(rarvm_data_t *rarvm_data, rarvm_standard_fil - break; - } - case VMSF_AUDIO: { -- int channels=rarvm_data->R[0]; -+ unsigned int channels=rarvm_data->R[0]; - data_size = rarvm_data->R[4]; - src_data = rarvm_data->mem; - dest_data = src_data + data_size; - - SET_VALUE(FALSE, &rarvm_data->mem[VM_GLOBALMEMADDR+0x20], data_size); -- if ((unsigned int)data_size >= VM_GLOBALMEMADDR/2) { -+ // In fact, audio channels never exceed 4. -+ if (data_size > VM_GLOBALMEMADDR/2 || channels > 128 || channels == 0) { - break; - } - for (cur_channel=0 ; cur_channel < channels ; cur_channel++) { -@@ -556,7 +559,7 @@ static void execute_standard_filter(rarvm_data_t *rarvm_data, rarvm_standard_fil - data_size = rarvm_data->R[4]; - src_pos = 0; - dest_pos = data_size; -- if ((unsigned int)data_size >= VM_GLOBALMEMADDR/2) { -+ if (data_size > VM_GLOBALMEMADDR/2) { - break; - } - while (src_pos < data_size) { diff --git a/libclamunrar/unrar.c b/libclamunrar/unrar.c index 40a3d63cbd3e..70de634a9a09 100644 --- a/libclamunrar/unrar.c +++ b/libclamunrar/unrar.c @@ -43,7 +43,7 @@ #ifdef RAR_HIGH_DEBUG #define rar_dbgmsg printf #else -static void rar_dbgmsg(const char* fmt,...){} +static void rar_dbgmsg(const char* fmt,...){(void)fmt;} #endif static void insert_old_dist(unpack_data_t *unpack_data, unsigned int distance) @@ -117,13 +117,14 @@ int rar_unp_read_buf(int fd, unpack_data_t *unpack_data) memmove(unpack_data->in_buf, unpack_data->in_buf+unpack_data->in_addr, data_size); } + unpack_data->in_addr = 0; unpack_data->read_top = data_size; } else { data_size = unpack_data->read_top; } /* RAR2 depends on us only reading upto the end of the current compressed file */ - if (unpack_data->pack_size < ((MAX_BUF_SIZE-data_size)&~0xf)) { + if (unpack_data->pack_size < (uint32_t)((MAX_BUF_SIZE-data_size)&~0xf)) { read_size = unpack_data->pack_size; } else { read_size = (MAX_BUF_SIZE-data_size)&~0xf; @@ -218,7 +219,7 @@ static void unp_write_buf(unpack_data_t *unpack_data) struct UnpackFilter *flt, *next_filter; struct rarvm_prepared_program *prg, *next_prg; uint8_t *filtered_data; - int i, j; + size_t i, j; rar_dbgmsg("in unp_write_buf\n"); written_border = unpack_data->wr_ptr; @@ -395,8 +396,9 @@ static int read_tables(int fd, unpack_data_t *unpack_data) uint8_t bit_length[BC]; unsigned char table[HUFF_TABLE_SIZE]; unsigned int bit_field; - int i, length, zero_count, number, n; - const int table_size=HUFF_TABLE_SIZE; + int length, zero_count, number, n; + size_t i; + const size_t table_size=HUFF_TABLE_SIZE; rar_dbgmsg("in read_tables Offset=%ld in_addr=%d read_top=%d\n", lseek(fd, 0, SEEK_CUR), unpack_data->in_addr, unpack_data->read_top); @@ -540,9 +542,11 @@ static int add_vm_code(unpack_data_t *unpack_data, unsigned int first_byte, unsigned char *vmcode, int code_size) { rarvm_input_t rarvm_input; - unsigned int filter_pos, new_filter, block_start, init_mask, cur_size; + unsigned int filter_pos, new_filter, block_start, init_mask, cur_size, data_size; struct UnpackFilter *filter, *stack_filter; - int i, empty_count, stack_pos, vm_codesize, static_size, data_size; + size_t i, empty_count, stack_pos; + unsigned int vm_codesize; + long static_size; unsigned char *vm_code, *global_data; rar_dbgmsg("in add_vm_code first_byte=0x%x code_size=%d\n", first_byte, code_size); @@ -562,7 +566,7 @@ static int add_vm_code(unpack_data_t *unpack_data, unsigned int first_byte, filter_pos = unpack_data->last_filter; } rar_dbgmsg("filter_pos = %u\n", filter_pos); - if (filter_pos > unpack_data->Filters.num_items || + if ((size_t) filter_pos > unpack_data->Filters.num_items || filter_pos > unpack_data->old_filter_lengths_size) { rar_dbgmsg("filter_pos check failed\n"); return FALSE; @@ -652,7 +656,7 @@ static int add_vm_code(unpack_data_t *unpack_data, unsigned int first_byte, } if (new_filter) { vm_codesize = rarvm_read_data(&rarvm_input); - if (vm_codesize >= 0x1000 || vm_codesize == 0 || (vm_codesize > rarvm_input.buf_size) || vm_codesize < 0) { + if (vm_codesize >= 0x1000 || vm_codesize == 0 || vm_codesize > (unsigned int)rarvm_input.buf_size) { rar_dbgmsg("ERROR: vm_codesize=0x%x buf_size=0x%x\n", vm_codesize, rarvm_input.buf_size); return FALSE; } @@ -661,11 +665,11 @@ static int add_vm_code(unpack_data_t *unpack_data, unsigned int first_byte, rar_dbgmsg("unrar: add_vm_code: rar_malloc failed for vm_code\n"); return FALSE; } - for (i=0 ; i < vm_codesize ; i++) { + for (i=0 ; i < (size_t) vm_codesize ; i++) { vm_code[i] = rarvm_getbits(&rarvm_input) >> 8; rarvm_addbits(&rarvm_input, 8); } - if(!rarvm_prepare(&unpack_data->rarvm_data, &rarvm_input, &vm_code[0], vm_codesize, &filter->prg)) { + if(!rarvm_prepare(&unpack_data->rarvm_data, &rarvm_input, &vm_code[0], (int) vm_codesize, &filter->prg)) { rar_dbgmsg("unrar: add_vm_code: rarvm_prepare failed\n"); free(vm_code); return FALSE; @@ -713,10 +717,10 @@ static int add_vm_code(unpack_data_t *unpack_data, unsigned int first_byte, if (data_size >= 0x10000) { return FALSE; } - cur_size = stack_filter->prg.global_size; - if (cur_size < data_size+VM_FIXEDGLOBALSIZE) { - stack_filter->prg.global_size += data_size+VM_FIXEDGLOBALSIZE-cur_size; - stack_filter->prg.global_data = rar_realloc2(stack_filter->prg.global_data, + cur_size = (unsigned int)stack_filter->prg.global_size; + if (cur_size < data_size + VM_FIXEDGLOBALSIZE) { + stack_filter->prg.global_size += (long)data_size + VM_FIXEDGLOBALSIZE - cur_size; + stack_filter->prg.global_data = (unsigned char*)rar_realloc2(stack_filter->prg.global_data, stack_filter->prg.global_size); if(!stack_filter->prg.global_data) { rar_dbgmsg("unrar: add_vm_code: rar_realloc2 failed for stack_filter->prg.global_data\n"); @@ -724,8 +728,8 @@ static int add_vm_code(unpack_data_t *unpack_data, unsigned int first_byte, } } global_data = &stack_filter->prg.global_data[VM_FIXEDGLOBALSIZE]; - for (i=0 ; i< data_size ; i++) { - if ((rarvm_input.in_addr+2) > rarvm_input.buf_size) { + for (i=0 ; i < (size_t)data_size ; i++) { + if (rarvm_input.in_addr + 2 > rarvm_input.buf_size) { rar_dbgmsg("Buffer truncated\n"); return FALSE; } @@ -825,9 +829,9 @@ void rar_unpack_init_data(int solid, unpack_data_t *unpack_data) memset(unpack_data->old_dist, 0, sizeof(unpack_data->old_dist)); unpack_data->old_dist_ptr= 0; memset(unpack_data->unp_old_table, 0, sizeof(unpack_data->unp_old_table)); + memset(&unpack_data->LDD, 0, sizeof(unpack_data->LDD)); memset(&unpack_data->LD, 0, sizeof(unpack_data->LD)); memset(&unpack_data->DD, 0, sizeof(unpack_data->DD)); - memset(&unpack_data->LDD, 0, sizeof(unpack_data->LDD)); memset(&unpack_data->RD, 0, sizeof(unpack_data->RD)); memset(&unpack_data->BD, 0, sizeof(unpack_data->BD)); unpack_data->last_dist= 0; diff --git a/libclamunrar/unrar.h b/libclamunrar/unrar.h index a2cc7461ff43..0c8cd8d63ff9 100644 --- a/libclamunrar/unrar.h +++ b/libclamunrar/unrar.h @@ -209,7 +209,7 @@ typedef struct unpack_data_tag rar_filter_array_t Filters; rar_filter_array_t PrgStack; int *old_filter_lengths; - int last_filter, old_filter_lengths_size; + unsigned int last_filter, old_filter_lengths_size; int64_t written_size; int64_t true_size; int64_t max_size; diff --git a/libclamunrar/unrar15.c b/libclamunrar/unrar15.c index d19337f37e0e..20591b7b11d4 100644 --- a/libclamunrar/unrar15.c +++ b/libclamunrar/unrar15.c @@ -119,16 +119,18 @@ static void copy_string15(unpack_data_t *unpack_data, unsigned int distance, } } -static unsigned int decode_num(unpack_data_t *unpack_data, int num, unsigned int start_pos, +static unsigned int decode_num(unpack_data_t *unpack_data, unsigned int num, unsigned int start_pos, unsigned int *dec_tab, unsigned int *pos_tab) { int i; - for (num&=0xfff0, i=0 ; dec_tab[i] <= num ; i++) { + for (num &= 0xfff0, i=0; dec_tab[i] <= num; i++) { start_pos++; } + rar_addbits(unpack_data, start_pos); - return (((num-(i ? dec_tab[i-1]:0)) >> (16-start_pos)) + pos_tab[start_pos]); + + return ( ((int)num - (i ? dec_tab[i-1] : 0)) >> (16 - start_pos) ) + pos_tab[start_pos]; } static void huff_decode(unpack_data_t *unpack_data) diff --git a/libclamunrar/unrar20.c b/libclamunrar/unrar20.c index d938c472e1d8..ad50c4e21275 100644 --- a/libclamunrar/unrar20.c +++ b/libclamunrar/unrar20.c @@ -25,7 +25,7 @@ #ifdef RAR_HIGH_DEBUG #define rar_dbgmsg printf #else -static void rar_dbgmsg(const char* fmt,...){} +static void rar_dbgmsg(const char* fmt,...){(void)fmt;} #endif void unpack_init_data20(int solid, unpack_data_t *unpack_data) @@ -338,13 +338,26 @@ int rar_unpack20(int fd, int solid, unpack_data_t *unpack_data) continue; } if (number > 269) { - length = ldecode[number-=270]+3; + /* If number is higher or equal to 298 in this instance something has likely + * gone horribly wrong and/or this is a RAR 5 file that Clam does not yet + * support parsing. Either way, this is a total failure case. */ + if (number < 298) { + length = ldecode[number-=270]+3; + } else { + retval = FALSE; + break; + } + if ((bits = lbits[number]) > 0) { length += rar_getbits(unpack_data) >> (16-bits); rar_addbits(unpack_data, bits); } dist_number = rar_decode_number(unpack_data, (struct Decode *)&unpack_data->DD); + if (dist_number > 47 || dist_number < 0) { + retval = FALSE; + break; + } distance = ddecode[dist_number] + 1; if ((bits = dbits[dist_number]) > 0) { distance += rar_getbits(unpack_data)>>(16-bits); diff --git a/libclamunrar/unrarfilter.c b/libclamunrar/unrarfilter.c index 1039d1e0e85d..9237027055ab 100644 --- a/libclamunrar/unrarfilter.c +++ b/libclamunrar/unrarfilter.c @@ -33,7 +33,7 @@ void rar_filter_array_init(rar_filter_array_t *filter_a) void rar_filter_array_reset(rar_filter_array_t *filter_a) { - int i; + size_t i; if (!filter_a) { return; diff --git a/libclamunrar/unrarhlp.c b/libclamunrar/unrarhlp.c index 62746bf43493..17166db58e5a 100644 --- a/libclamunrar/unrarhlp.c +++ b/libclamunrar/unrarhlp.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + * Copyright (C) 2015, 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. * Copyright (C) 2007 Sourcefire, Inc. * * The unRAR sources may be used in any software to handle RAR @@ -19,7 +19,7 @@ #ifdef RAR_HIGH_DEBUG #define rar_dbgmsg printf #else -static void rar_dbgmsg(const char* fmt,...){} +static void rar_dbgmsg(const char* fmt,...){(void)fmt;} #endif #define RAR_MAX_ALLOCATION 184549376 @@ -30,14 +30,14 @@ void *rar_malloc(size_t size) if(!size || size > RAR_MAX_ALLOCATION) { - rar_dbgmsg("UNRAR: rar_malloc(): Attempt to allocate %lu bytes. Please report to http://bugs.clamav.net\n", size); + rar_dbgmsg("UNRAR: rar_malloc(): Attempt to allocate %lu bytes. Please report to https://bugzilla.clamav.net\n", size); return NULL; } alloc = malloc(size); if(!alloc) { - fprintf(stderr, "UNRAR: rar_malloc(): Can't allocate memory (%lu bytes).\n", size); + fprintf(stderr, "UNRAR: rar_malloc(): Can't allocate memory (%llu bytes).\n", (long long unsigned)size); return NULL; } else return alloc; } @@ -48,14 +48,14 @@ void *rar_realloc2(void *ptr, size_t size) if(!size || size > RAR_MAX_ALLOCATION) { - rar_dbgmsg("UNRAR: rar_realloc2(): Attempt to allocate %lu bytes. Please report to http://bugs.clamav.net\n", size); + rar_dbgmsg("UNRAR: rar_realloc2(): Attempt to allocate %lu bytes. Please report to https://bugzilla.clamav.net\n", size); return NULL; } alloc = realloc(ptr, size); if(!alloc) { - fprintf(stderr, "UNRAR: rar_realloc2(): Can't allocate memory (%lu bytes).\n", size); + fprintf(stderr, "UNRAR: rar_realloc2(): Can't allocate memory (%llu bytes).\n", (long long unsigned)size); if(ptr) free(ptr); return NULL; diff --git a/libclamunrar/unrarppm.c b/libclamunrar/unrarppm.c index a58b47cedaa2..439318157e7d 100644 --- a/libclamunrar/unrarppm.c +++ b/libclamunrar/unrarppm.c @@ -940,14 +940,14 @@ void ppm_cleanup(ppm_data_t *ppm_data) int ppm_decode_init(ppm_data_t *ppm_data, int fd, unpack_data_t *unpack_data, int *EscChar) { - int max_order, Reset, MaxMB; + int max_order = 0, Reset = 0, MaxMB = 0; - max_order = rar_get_char(fd, unpack_data); + max_order = (int) rar_get_char(fd, unpack_data); rar_dbgmsg("ppm_decode_init max_order=%d\n", max_order); Reset = (max_order & 0x20) ? 1 : 0; rar_dbgmsg("ppm_decode_init Reset=%d\n", Reset); if (Reset) { - MaxMB = rar_get_char(fd, unpack_data); + MaxMB = (int) rar_get_char(fd, unpack_data); rar_dbgmsg("ppm_decode_init MaxMB=%d\n", MaxMB); } else { if (sub_allocator_get_allocated_memory(&ppm_data->sub_alloc) == 0) { diff --git a/libclamunrar/unrarvm.c b/libclamunrar/unrarvm.c index b21e242fa72b..813ec0867d43 100644 --- a/libclamunrar/unrarvm.c +++ b/libclamunrar/unrarvm.c @@ -29,7 +29,7 @@ #ifdef RAR_HIGH_DEBUG #define rar_dbgmsg printf #else -static void rar_dbgmsg(const char* fmt,...){} +static void rar_dbgmsg(const char* fmt,...){(void)fmt;} #endif #define VMCF_OP0 0 @@ -42,6 +42,28 @@ static void rar_dbgmsg(const char* fmt,...){} #define VMCF_USEFLAGS 32 #define VMCF_CHFLAGS 64 +#define UINT32(x) (sizeof(uint32_t)==4 ? (uint32_t)(x):((x)&0xffffffff)) + +#if WORDS_BIGENDIAN == 0 +#define GET_VALUE(byte_mode,addr) ((byte_mode) ? (*(unsigned char *)(addr)) : UINT32((*(unsigned int *)(addr)))) +#else +#define GET_VALUE(byte_mode,addr) ((byte_mode) ? (*(unsigned char *)(addr)) : (((unsigned char *)addr)[0] | ((unsigned char *)addr)[1]<<8 | ((unsigned char *)addr)[2]<<16 | ((unsigned char *)addr)[3]<<24)) +#endif + +#if WORDS_BIGENDIAN == 0 +#define SET_VALUE(byte_mode,addr,value) (void)(((byte_mode) ? (*(unsigned char *)(addr)=(value)):(*(uint32_t *)(addr)=((uint32_t)(value))))) +#else +#define SET_VALUE(byte_mode,addr,value) rarvm_set_value(byte_mode, (unsigned int *)addr, value); +#endif + +#define SET_IP(IP) \ + if ((IP)>=(unsigned int)code_size) \ + return TRUE; \ + if (--max_ops<=0) \ + return FALSE; \ + cmd=prepared_code+(IP); + + static uint8_t vm_cmdflags[]= { /* VM_MOV */ VMCF_OP2 | VMCF_BYTEMODE , @@ -86,37 +108,6 @@ static uint8_t vm_cmdflags[]= /* VM_PRINT */ VMCF_OP0 }; -#define UINT32(x) (sizeof(uint32_t)==4 ? (uint32_t)(x):((x)&0xffffffff)) - -#if WORDS_BIGENDIAN == 0 -#define GET_VALUE(byte_mode,addr) ((byte_mode) ? (*(unsigned char *)(addr)) : UINT32((*(unsigned int *)(addr)))) -#else -#define GET_VALUE(byte_mode,addr) ((byte_mode) ? (*(unsigned char *)(addr)) : (((unsigned char *)addr)[0] | ((unsigned char *)addr)[1]<<8 | ((unsigned char *)addr)[2]<<16 | ((unsigned char *)addr)[3]<<24)) -#endif - -void rarvm_set_value(int byte_mode, unsigned int *addr, unsigned int value) -{ - if (byte_mode) { - *(unsigned char *)addr=value; - } else { -#if WORDS_BIGENDIAN == 0 - *(uint32_t *)addr = value; -#else - ((unsigned char *)addr)[0]=(unsigned char)value; - ((unsigned char *)addr)[1]=(unsigned char)(value>>8); - ((unsigned char *)addr)[2]=(unsigned char)(value>>16); - ((unsigned char *)addr)[3]=(unsigned char)(value>>24); -#endif - } -} - - -#if WORDS_BIGENDIAN == 0 -#define SET_VALUE(byte_mode,addr,value) (void)(((byte_mode) ? (*(unsigned char *)(addr)=(value)):(*(uint32_t *)(addr)=((uint32_t)(value))))) -#else -#define SET_VALUE(byte_mode,addr,value) rarvm_set_value(byte_mode, (unsigned int *)addr, value); -#endif - const uint32_t crc_tab[256]={ 0x0, 0x77073096, 0xee0e612c, 0x990951ba, 0x76dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0xedb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x9b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, @@ -152,14 +143,30 @@ const uint32_t crc_tab[256]={ 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }; +void rarvm_set_value(int byte_mode, unsigned int *addr, unsigned int value) +{ + if (byte_mode) { + *(unsigned char *)addr=value; + } else { +#if WORDS_BIGENDIAN == 0 + *(uint32_t *)addr = value; +#else + ((unsigned char *)addr)[0]=(unsigned char)value; + ((unsigned char *)addr)[1]=(unsigned char)(value>>8); + ((unsigned char *)addr)[2]=(unsigned char)(value>>16); + ((unsigned char *)addr)[3]=(unsigned char)(value>>24); +#endif + } +} + uint32_t rar_crc(uint32_t start_crc, void *addr, uint32_t size) { unsigned char *data; - int i; + uint32_t i; data = addr; #if WORDS_BIGENDIAN == 0 - while (size > 0 && ((long)data & 7)) + while (size > 0 && ((size_t)data & 7)) { start_crc = crc_tab[(unsigned char)(start_crc^data[0])]^(start_crc>>8); size--; @@ -270,7 +277,7 @@ unsigned int rarvm_read_data(rarvm_input_t *rarvm_input) static rarvm_standard_filters_t is_standard_filter(unsigned char *code, int code_size) { uint32_t code_crc; - int i; + size_t i; struct standard_filter_signature { @@ -576,13 +583,6 @@ static void execute_standard_filter(rarvm_data_t *rarvm_data, rarvm_standard_fil break; } } - -#define SET_IP(IP) \ - if ((IP)>=code_size) \ - return TRUE; \ - if (--max_ops<=0) \ - return FALSE; \ - cmd=prepared_code+(IP); static int rarvm_execute_code(rarvm_data_t *rarvm_data, struct rarvm_prepared_command *prepared_code, int code_size) diff --git a/libclamunrar_iface/unrar_iface.c b/libclamunrar_iface/unrar_iface.c index 638008e1bc0a..a3ae10576c8c 100644 --- a/libclamunrar_iface/unrar_iface.c +++ b/libclamunrar_iface/unrar_iface.c @@ -1,6 +1,6 @@ /* * Interface to libclamunrar - * Copyright (C) 2015 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + * Copyright (C) 2015, 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. * Copyright (C) 2007-2013 Sourcefire, Inc. * Authors: Trog, Torok Edvin, Tomasz Kojm * @@ -53,7 +53,7 @@ static uint32_t unrar_endian_convert_32(uint32_t v) #ifdef RAR_DEBUG_MODE #define unrar_dbgmsg printf #else -static void unrar_dbgmsg(const char* fmt,...){} +static void unrar_dbgmsg(const char* fmt,...){(void)fmt;} #endif static void *read_header(int fd, header_type hdr_type) @@ -254,8 +254,9 @@ int unrar_open(int fd, const char *dirname, unrar_state_t *state) int ofd, retval; char filename[1024]; unpack_data_t *unpack_data; - unrar_main_header_t *main_hdr; + unrar_main_header_t *main_hdr = NULL; off_t offset; + int ret = 0; if(!state) @@ -274,34 +275,29 @@ int unrar_open(int fd, const char *dirname, unrar_state_t *state) unrar_dbgmsg("UNRAR: Head Size: %.4x\n", main_hdr->head_size); if(main_hdr->flags & MHD_PASSWORD) { - free(main_hdr); - return UNRAR_PASSWD; + ret = UNRAR_PASSWD; + goto err_mhdr; } snprintf(filename,1024,"%s"PATHSEP"comments", dirname); if(mkdir(filename,0700)) { unrar_dbgmsg("UNRAR: Unable to create comment temporary directory\n"); - free(main_hdr); - return UNRAR_ERR; + goto err_mhdr; } state->comment_dir = strdup(filename); if(!state->comment_dir) { - free(main_hdr); - return UNRAR_EMEM; + ret = UNRAR_EMEM; + goto err_mhdr; } - if(main_hdr->head_size < SIZEOF_NEWMHD) { - free(main_hdr); - free(state->comment_dir); - return UNRAR_ERR; - } + if(main_hdr->head_size < SIZEOF_NEWMHD) + goto err_cmt_dir; unpack_data = (unpack_data_t *) calloc(1, sizeof(unpack_data_t)); if(!unpack_data) { - free(main_hdr); - free(state->comment_dir); unrar_dbgmsg("UNRAR: malloc failed for unpack_data\n"); - return UNRAR_EMEM; + ret = UNRAR_EMEM; + goto err_cmt_dir; } unpack_data->rarvm_data.mem = NULL; unpack_data->old_filter_lengths = NULL; @@ -318,10 +314,7 @@ int unrar_open(int fd, const char *dirname, unrar_state_t *state) offset = lseek(fd, 0, SEEK_CUR); if (offset == -1) { unrar_dbgmsg("UNRAR: seek: lseek() call failed in unrar_open\n"); - free(main_hdr); - free(state->comment_dir); - free(unpack_data); - return UNRAR_ERR; + goto err_unpack_data; } unrar_dbgmsg("UNRAR: Offset: %x\n", offset); comment_header = read_header(fd, COMM_HEAD); @@ -336,13 +329,7 @@ int unrar_open(int fd, const char *dirname, unrar_state_t *state) if(ofd < 0) { unrar_dbgmsg("UNRAR: ERROR: Failed to open output file\n"); free(comment_header); - free(main_hdr); - ppm_destructor(&unpack_data->ppm_data); - rar_init_filters(unpack_data); - unpack_free_data(unpack_data); - free(unpack_data); - free(state->comment_dir); - return UNRAR_ERR; + goto err_unpack_data; } else { if(comment_header->method == 0x30) { unrar_dbgmsg("UNRAR: Copying stored comment (not packed)\n"); @@ -352,6 +339,8 @@ int unrar_open(int fd, const char *dirname, unrar_state_t *state) unpack_data->dest_unp_size = comment_header->unpack_size; unpack_data->pack_size = comment_header->head_size - SIZEOF_COMMHEAD; retval = rar_unpack(fd, comment_header->unpack_ver, FALSE, unpack_data); + if (!retval) + unrar_dbgmsg("UNRAR: failed to unpack comment\n"); unpack_free_data(unpack_data); } close(ofd); @@ -360,26 +349,13 @@ int unrar_open(int fd, const char *dirname, unrar_state_t *state) } if (lseek(fd, offset, SEEK_SET) == -1) { unrar_dbgmsg("UNRAR: seek: call to lseek() failed in unrar_open: %ld\n", offset); - free(main_hdr); - ppm_destructor(&unpack_data->ppm_data); - rar_init_filters(unpack_data); - unpack_free_data(unpack_data); - free(unpack_data); - free(state->comment_dir); - return UNRAR_ERR; + goto err_unpack_data; } } if(main_hdr->head_size > SIZEOF_NEWMHD) { - if(!lseek(fd, main_hdr->head_size - SIZEOF_NEWMHD, SEEK_CUR)) { - free(main_hdr); - ppm_destructor(&unpack_data->ppm_data); - rar_init_filters(unpack_data); - unpack_free_data(unpack_data); - free(unpack_data); - free(state->comment_dir); - return UNRAR_ERR; - } + if (!lseek(fd, main_hdr->head_size - SIZEOF_NEWMHD, SEEK_CUR)) + goto err_unpack_data; } state->unpack_data = unpack_data; @@ -389,6 +365,19 @@ int unrar_open(int fd, const char *dirname, unrar_state_t *state) state->fd = fd; return UNRAR_OK; + +err_unpack_data: + ppm_destructor(&unpack_data->ppm_data); + rar_init_filters(unpack_data); + unpack_free_data(unpack_data); + free(unpack_data); +err_cmt_dir: + free(state->comment_dir); +err_mhdr: + free(main_hdr); + if (!ret) + return UNRAR_ERR; + return ret; } int unrar_extract_next_prepare(unrar_state_t *state, const char *dirname) @@ -397,6 +386,7 @@ int unrar_extract_next_prepare(unrar_state_t *state, const char *dirname) int ofd; unrar_metadata_t *new_metadata; + (void)dirname; state->file_header = read_block(state->fd, FILE_HEAD); if(!state->file_header) @@ -510,7 +500,7 @@ int unrar_extract_next(unrar_state_t *state, const char *dirname) unrar_dbgmsg("UNRAR: Computed File CRC: 0x%x\n", unpack_data->unp_crc^0xffffffff); if(unpack_data->unp_crc != 0xffffffff) { if(state->file_header->file_crc != (unpack_data->unp_crc^0xffffffff)) { - unrar_dbgmsg("UNRAR: RAR CRC error. If the file is not corrupted, please report at http://bugs.clamav.net/\n"); + unrar_dbgmsg("UNRAR: RAR CRC error. If the file is not corrupted, please report at https://bugzilla.clamav.net/\n"); } } if(!retval) {