Code Monkey home page Code Monkey logo

libmspack's Introduction

cabextract

cabextract is Free Software for extracting Microsoft cabinet files, also called .CAB files. It is distributed under the GNU GPL license and is based on the portable LGPL libmspack library.

cabextract is released at https://www.cabextract.org.uk/

libmspack

libmspack is a library for some loosely related Microsoft compression formats: CAB, CHM, HLP, LIT, KWAJ and SZDD.

libmspack is released at https://www.cabextract.org.uk/libmspack/

libmspack's People

Contributors

jwilk avatar kyz avatar micahsnyder avatar neonbunny avatar sgtatham avatar wereii avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libmspack's Issues

Regression when extracting cabinets using "-F" option

Hi,

I'm the maintainer for winetricks. I had a bug report recently (Winetricks/winetricks#1120) about something failing to extract. Upon further investigation, seems to be a regression in cabextract:

d3d899be6100c3399fc8c915ca768f3aafe6d9a6 is the first bad commit
commit d3d899be6100c3399fc8c915ca768f3aafe6d9a6
Author: Micah Snyder <[email protected]>
Date:   Sun Sep 16 18:19:11 2018 -0400

    Added CAB decompression parameter MSCABD_PARAM_SALVAGE which makes a best effort to extract as many files as possible from damaged, mangled, malformed or otherwise non-standard CAB archives.

:040000 040000 cd5cb2957dfa85165f28fbe1d6fe462a2906bc7c be39207070d5060291a5b1e3885c0228dbba7ebd M	libmspack

Before this patch:

Executing cabextract -q -d /home/austin/.wine/dosdevices/c:/windows/temp/_mspatcha -L -F i386/mspatcha.dl_ /home/austin/.cache/winetricks/win2ksp4/W2KSP4_EN.EXE
Executing cabextract -q --directory=/home/austin/.wine/dosdevices/c:/windows/system32 /home/austin/.wine/dosdevices/c:/windows/temp/_mspatcha/i386/mspatcha.dl_
Using native,builtin override for following DLLs: mspatcha

After this patch:

Executing cabextract -q -d /home/austin/.wine/dosdevices/c:/windows/temp/_mspatcha -L -F i386/mspatcha.dl_ /home/austin/.cache/winetricks/win2ksp4/W2KSP4_EN.EXE
/home/austin/.cache/winetricks/win2ksp4/W2KSP4_EN.EXE: WARNING; non-maximal data block
/home/austin/.cache/winetricks/win2ksp4/W2KSP4_EN.EXE: WARNING; non-maximal data block
Executing cabextract -q --directory=/home/austin/.wine/dosdevices/c:/windows/system32 /home/austin/.wine/dosdevices/c:/windows/temp/_mspatcha/i386/mspatcha.dl_
/home/austin/.wine/dosdevices/c:/windows/temp/_mspatcha/i386/mspatcha.dl_: no valid cabinets found
------------------------------------------------------
Note: command cabextract -q --directory=/home/austin/.wine/dosdevices/c:/windows/system32 /home/austin/.wine/dosdevices/c:/windows/temp/_mspatcha/i386/mspatcha.dl_ returned status 1. Aborting.

The patch also breaks the tests for me:

make: Entering directory '/home/austin/src/cabextract/cabextract/test'
../cabextract -l case.cab >case.list
../cabextract -L -l case.cab >>case.list
../cabextract -d DIR/PATH -l case.cab >>case.list
../cabextract -d DIR/PATH -L -l case.cab >>case.list
../cabextract -l dirwalk-vulns.cab >dirwalk-vulns.list
../cabextract -e koi8-ru -l encoding-koi8.cab >encoding-koi8.list
../cabextract -e iso-8859-1 -l encoding-latin1.cab >encoding-latin1.list
../cabextract -e sjis -l encoding-sjis.cab >encoding-sjis.list
../cabextract -l search.cab >search.list
../cabextract -l simple.cab >simple.list
../cabextract -l utf8-stresstest.cab >utf8-stresstest.list
../cabextract -p mixed.cab >mixed.test
stdout(mszip.txt): No such file or directory
stdout(lzx.txt): No such file or directory
stdout(qtm.txt): No such file or directory
make: *** [Makefile:27: mixed.test] Error 1
make: Leaving directory '/home/austin/src/cabextract/cabextract/test'

With 5c1b259 (parent commit), winetricks works and cabextract tests pass.

Please let me know if I can provide any further information.

Multiple filters in one command

When using cabextract on large cab files with many bundled files, the ability to extract more than one file based on multiple filters is a huge efficiency gain (minutes vs hours). However, I was not able to find a way to do it without breaking the existing API. So I'm submitting a feature request for your consideration vs. a pull request:

https://github.com/caesarshift/libmspack

Tarball missing for 10 days

On the main website https://www.cabextract.org.uk/libmspack/, this is printed:
"The latest release of libmspack is libmspack 0.7alpha, released on 25 July 2018."
which has a link to "https://www.cabextract.org.uk/libmspack/libmspack-0.7alpha.tar.gz"

which does not exist.

Not Found
The requested URL /libmspack/libmspack-0.7alpha.tar.gz was not found on this server.

Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.

I thought maybe the file had to get re-rolled, but after 10 days, either you guys aren't aware the file is missing or there's a major issue in which an adjustment of the website is necessary, I would think.

If it's just a bad link, can you fix it?

locale-dependent pitfalls

As long as the archive was produced in a way that stored the filenames as utf8 strings, things work fine.

Yet, if it's not the case, cabextract behaves as broken as zip does.
Something like zip's iconv patch is needed - of course, the result would be requiring a libc that implements iconv.
Also, if such archive was created is a DBCS locale, putting such name through tolower will only result in a completely broken return value.

Warnings from compilers/analyzers

What is your politics about compilers or code analyzeres warnings?
I know this is mostly endless fight... But who knows...
While investigating possibility of using your famous libmspack library in our commercial project I found huge ammont of warning from different compilers and static code analyzers.
Most of them is just some sort of common signed/unsigned mismatch. Some are false positive for shure but some other looks for me like really potential bugs. Hard to say exactly bcoz I don't familiar with your library interanals.
Pretty shure I should not put them here in public for common reason but just one example:
define TOLOWER(x) (((x)<0||(x)>256)?(x):mspack_tolower_map[(x)])
off-by-one static const array overrun here for 0x100 utf-8 character.

Not clear on Github how to get libmspack vs cabextract releases

Just have been trying to geterate dist tar ball using distcheck target and build fails:

[tkloczko@domek libmspack]$ ./configure 
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /usr/bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking whether make supports nested variables... (cached) yes
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking whether gcc understands -c and -o together... yes
checking whether make supports the include directive... yes (GNU style)
checking dependency style of gcc... gcc3
checking for ar... ar
checking the archiver (ar) interface... ar
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking how to print strings... printf
checking for a sed that does not truncate output... /usr/bin/sed
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for fgrep... /usr/bin/grep -F
checking for ld used by gcc... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... yes
checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B
checking the name lister (/usr/bin/nm -B) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 1572864
checking how to convert x86_64-pc-linux-gnu file names to x86_64-pc-linux-gnu format... func_convert_file_noop
checking how to convert x86_64-pc-linux-gnu file names to toolchain format... func_convert_file_noop
checking for /usr/bin/ld option to reload object files... -r
checking for objdump... objdump
checking how to recognize dependent libraries... pass_all
checking for dlltool... no
checking how to associate runtime and link libraries... printf %s\n
checking for archiver @FILE support... @
checking for strip... strip
checking for ranlib... ranlib
checking command to parse /usr/bin/nm -B output from gcc object... ok
checking for sysroot... no
checking for a working dd... /usr/bin/dd
checking how to truncate binary pipes... /usr/bin/dd bs=4096 count=1
checking for mt... no
checking if : is a manifest tool... no
checking how to run the C preprocessor... gcc -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking for dlfcn.h... yes
checking for objdir... .libs
checking if gcc supports -fno-rtti -fno-exceptions... no
checking for gcc option to produce PIC... -fPIC -DPIC
checking if gcc PIC flag -fPIC -DPIC works... yes
checking if gcc static flag -static works... no
checking if gcc supports -c -o file.o... yes
checking if gcc supports -c -o file.o... (cached) yes
checking whether the gcc linker (/usr/bin/ld -m elf_x86_64) supports shared libraries... yes
checking whether -lc should be explicitly linked in... no
checking dynamic linker characteristics... GNU/Linux ld.so
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... yes
checking for inttypes.h... (cached) yes
checking for an ANSI C-conforming const... yes
checking for inline... inline
checking whether byte ordering is bigendian... no
checking for mode_t... yes
checking for off_t... yes
checking for size_t... yes
checking size of off_t... 8
checking for mkdir... yes
checking for _mkdir... no
checking whether mkdir takes one argument... no
checking for towlower... yes
checking for special C compiler options needed for large files... no
checking for _FILE_OFFSET_BITS value needed for large files... no
checking for _LARGEFILE_SOURCE value needed for large files... no
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating libmspack.pc
config.status: creating config.h
config.status: executing depfiles commands
config.status: executing libtool commands
[tkloczko@domek libmspack]$ make distcheck
make  dist-gzip am__post_remove_distdir='@:'
make[1]: Entering directory '/home/tkloczko/rpmbuild/BUILD/libmspack-1.9.1/libmspack'
make  distdir-am
make[2]: Entering directory '/home/tkloczko/rpmbuild/BUILD/libmspack-1.9.1/libmspack'
  CC       mspack/system.lo
  CC       mspack/cabd.lo
  CC       mspack/lzxd.lo
  CC       mspack/mszipd.lo
  CC       mspack/qtmd.lo
  CCLD     libmscabd.la
  CC       mspack/cabc.lo
  CC       mspack/chmc.lo
  CC       mspack/chmd.lo
  CC       mspack/hlpc.lo
  CC       mspack/hlpd.lo
  CC       mspack/litc.lo
  CC       mspack/litd.lo
  CC       mspack/kwajc.lo
  CC       mspack/kwajd.lo
  CC       mspack/szddc.lo
  CC       mspack/szddd.lo
  CC       mspack/oabc.lo
  CC       mspack/oabd.lo
mspack/oabd.c:375:12: error: conflicting types for ‘copy_fh’
  375 | static int copy_fh(struct mspack_system *sys, struct mspack_file *infh,
      |            ^~~~~~~
mspack/oabd.c:37:12: note: previous declaration of ‘copy_fh’ was here
   37 | static int copy_fh(struct mspack_system *sys, struct mspack_file *infh,
      |            ^~~~~~~
mspack/oabd.c:37:12: warning: copy_fh’ used but never defined
mspack/oabd.c:375:12: warning: copy_fh’ defined but not used [-Wunused-function]
  375 | static int copy_fh(struct mspack_system *sys, struct mspack_file *infh,
      |            ^~~~~~~
make[2]: *** [Makefile:1071: mspack/oabd.lo] Error 1
make[2]: Leaving directory '/home/tkloczko/rpmbuild/BUILD/libmspack-1.9.1/libmspack'
make[1]: *** [Makefile:1439: distdir] Error 2
make[1]: Leaving directory '/home/tkloczko/rpmbuild/BUILD/libmspack-1.9.1/libmspack'
make: *** [Makefile:1516: dist] Error 2

Compilier warnings with 1.9.1

With gcc 9.3.1 20200506 compiling mspack 1.9.1 prints:

mspack/chmd.c: In function 'chmd_extract':
mspack/chmd.c:1139:10: warning: 'length' may be used uninitialized in this function [-Wmaybe-uninitialized]
 1139 |   length -= self->d->offset;
      |          ^
mspack/chmd.c:1042:9: note: 'length' was declared here
 1042 |   off_t length, offset;
      |         ^
  CC       test/chmd_order.o
  CCLD     test/chmd_order
mspack/chmd.c: In function 'chmd_extract':
mspack/chmd.c:1139:10: warning: 'length' may be used uninitialized in this function [-Wmaybe-uninitialized]
 1139 |   length -= self->d->offset;
      |          ^
mspack/chmd.c:1042:9: note: 'length' was declared here
 1042 |   off_t length, offset;
      |         ^
  CC       test/chminfo.o
test/chminfo.c: In function ‘main’:
test/chminfo.c:255:47: warning: format ‘%llu’ expects argument of type ‘long long unsigned int’, but argument 4 has type ‘off_t’ {aka ‘long int’} 
[-Wformat=]
  255 |               printf("    %-10u -> %-10u [ %llu %u ]\n",
      |                                            ~~~^
      |                                               |
      |                                               long long unsigned int
      |                                            %lu
......
  258 |                      contents + rtdata,
      |                      ~~~~~~~~~~~~~~~~~         
      |                               |
      |                               off_t {aka long int}
  CCLD     test/chminfo
mspack/chmd.c: In function 'chmd_extract':
mspack/chmd.c:1139:10: warning: 'length' may be used uninitialized in this function [-Wmaybe-uninitialized]
 1139 |   length -= self->d->offset;
      |          ^
mspack/chmd.c:1042:9: note: 'length' was declared here
 1042 |   off_t length, offset;
      |         ^
make[1]: Target 'all-am' not remade because of errors.

Heap buffer overflow in chmd_read_headers()

Description:

Function chmd_read_headers() in libmspack has a heap buffer overflow problem( Out of Bound Read).

Affected version:

libmspack 0.9.1 alpha

Details:

In function chmd_read_headers(), line 486,memcmp(&name[33], &content_name[33], 8L) will lead to out of bound read while extracting a crafted chm file.

chmd.c ,line 486~492:

      if (name[0] == ':' && name[1] == ':') {
        /* system file */
        if (memcmp(&name[2], &content_name[2], 31L) == 0) {
          if (memcmp(&name[33], &content_name[33], 8L) == 0) {
            chm->sec1.content = fi;
          }
          else if (memcmp(&name[33], &control_name[33], 11L) == 0) {
            chm->sec1.control = fi;
          }

Details with asan output:

./chmextract chmextract-overflow-chmd-486                      
chmextract-overflow-chmd-486
chmextract-overflow-chmd-486: invalid section number '89'.
chmextract-overflow-chmd-486: invalid section number '89'.
chmextract-overflow-chmd-486: invalid section number '89'.
chmextract-overflow-chmd-486: invalid section number '71'.
chmextract-overflow-chmd-486: invalid section number '266694953'.
chmextract-overflow-chmd-486: invalid section number '114'.
chmextract-overflow-chmd-486: invalid section number '84'.
chmextract-overflow-chmd-486: invalid section number '16259'.
chmextract-overflow-chmd-486: invalid section number '58'.
chmextract-overflow-chmd-486: invalid section number '67'.
chmextract-overflow-chmd-486: invalid section number '47'.
chmextract-overflow-chmd-486: invalid section number '48'.
chmextract-overflow-chmd-486: invalid section number '71'.
chmextract-overflow-chmd-486: invalid section number '266694953'.
chmextract-overflow-chmd-486: invalid section number '114'.
chmextract-overflow-chmd-486: invalid section number '84'.
chmextract-overflow-chmd-486: invalid section number '16259'.
chmextract-overflow-chmd-486: invalid section number '58'.
=================================================================
==9457==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x621000002500 at pc 0x0000004bf5bc bp 0x7ffebbdd6c60 sp 0x7ffebbdd6410
READ of size 31 at 0x621000002500 thread T0
    #0 0x4bf5bb in __interceptor_memcmp.part.78 /src/llvm/projects/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:827
    #1 0x7f1b498ccde1 in chmd_read_headers /src/libmspack/libmspack/mspack/chmd.c:486
    #2 0x7f1b498ccde1 in chmd_real_open /src/libmspack/libmspack/mspack/chmd.c:163
    #3 0x7f1b498ccde1 in chmd_open /src/libmspack/libmspack/mspack/chmd.c:126
    #4 0x529a23 in main /src/libmspack/libmspack/examples/chmextract.c:92:18
    #5 0x7f1b489c882f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #6 0x41a888 in _start (/src/libmspack/libmspack/examples/.libs/chmextract+0x41a888)

0x621000002500 is located 0 bytes to the right of 4096-byte region [0x621000001500,0x621000002500)
allocated by thread T0 here:
    #0 0x4e95bf in __interceptor_malloc /src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:146
    #1 0x7f1b498cbd57 in chmd_read_headers /src/libmspack/libmspack/mspack/chmd.c:418
    #2 0x7f1b498cbd57 in chmd_real_open /src/libmspack/libmspack/mspack/chmd.c:163
    #3 0x7f1b498cbd57 in chmd_open /src/libmspack/libmspack/mspack/chmd.c:126

SUMMARY: AddressSanitizer: heap-buffer-overflow /src/llvm/projects/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:827 in __interceptor_memcmp.part.78
Shadow bytes around the buggy address:
  0x0c427fff8450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c427fff8460: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c427fff8470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c427fff8480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c427fff8490: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c427fff84a0:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fff84b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fff84c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fff84d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fff84e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fff84f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==9457==ABORTING

poc file

https://github.com/JsHuang/pocs/blob/master/libmspack/chmextract-overflow-chmd-486

Credit: ADLab of Venustech

Decompressing files in memory?

Please add support for decompressing files that have already been loaded into memory.

I'm trying to use mszipd_init() and mszipd_decompress(), but it will only work with file handles.

Or if it already does it, then I would like to see a C/C++ coding example of how to decompress a file loaded in a memory buffer. Thanks.

cabextract NULL pointer dereference

When I try to run cabextract against a certain CAB file I get the following output (from cabextract 1.6 installed via the Ubuntu 17.10 apt-get repo):

cabextract /tmp/97f3c838aa94567ca24d15f810a6d1c116d7b971cf2df82188ac4f9ea0a0d9a8 
/tmp/97f3c838aa94567ca24d15f810a6d1c116d7b971cf2df82188ac4f9ea0a0d9a8: CAB: Folder record 0
/tmp/97f3c838aa94567ca24d15f810a6d1c116d7b971cf2df82188ac4f9ea0a0d9a8: CAB: Folder offset: 71
/tmp/97f3c838aa94567ca24d15f810a6d1c116d7b971cf2df82188ac4f9ea0a0d9a8: CAB: Folder compression method: 1
/tmp/97f3c838aa94567ca24d15f810a6d1c116d7b971cf2df82188ac4f9ea0a0d9a8: CAB: Recorded folders: 1
CAB: File record 0
CAB: File name: XXXXXX*exe
CAB: File offset: 0
CAB: File folder index: 4294967295
CAB: File attribs: 0x20
CAB:   * file modified since last backup
CAB: Recorded files: 1

/tmp/97f3c838aa94567ca24d15f810a6d1c116d7b971cf2df82188ac4f9ea0a0d9a8: can't find (null)
Extracting cabinet: /tmp/97f3c838aa94567ca24d15f810a6d1c116d7b971cf2df82188ac4f9ea0a0d9a8
Segmentation fault (core dumped)

I built from source and confirmed that the issue still occurs. Here is the gdb output related to the crash:

(gdb) run
Starting program: /home/zelda/workspace/libmspack/cabextract/cabextract /tmp/97f3c838aa94567ca24d15f810a6d1c116d7b971cf2df82188ac4f9ea0a0d9a8

Program received signal SIGSEGV, Segmentation fault.
__gconv (cd=0x0, inbuf=inbuf@entry=0x0, inbufend=inbufend@entry=0x0, outbuf=outbuf@entry=0x0, 
    outbufend=outbufend@entry=0x0, irreversible=irreversible@entry=0x7fffffffda30) at gconv.c:42
42	gconv.c: No such file or directory.
(gdb) bt
#0  __gconv (cd=0x0, inbuf=inbuf@entry=0x0, inbufend=inbufend@entry=0x0, outbuf=outbuf@entry=0x0, 
    outbufend=outbufend@entry=0x0, irreversible=irreversible@entry=0x7fffffffda30) at gconv.c:42
#1  0x00007ffff7a16b61 in iconv (cd=<optimized out>, inbuf=0x0, inbytesleft=0x0, outbuf=0x0, 
    outbytesleft=0x0) at iconv.c:42
#2  0x0000555555555ddf in convert_filename (name=<optimized out>) at src/cabextract.c:1004
#3  convert_filenames (files=<optimized out>) at src/cabextract.c:1025
#4  process_cabinet (
    basename=0x7fffffffe13a "/tmp/97f3c838aa94567ca24d15f810a6d1c116d7b971cf2df82188ac4f9ea0a0d9a8")
    at src/cabextract.c:483
#5  main (argc=2, argv=0x7fffffffdd58) at src/cabextract.c:412
(gdb) disassemble 
Dump of assembler code for function __gconv:
   0x00007ffff7a170b0 <+0>:	cmp    rdi,0xffffffffffffffff
   0x00007ffff7a170b4 <+4>:	je     0x7ffff7a171e8 <__gconv+312>
   0x00007ffff7a170ba <+10>:	push   r15
   0x00007ffff7a170bc <+12>:	push   r14
   0x00007ffff7a170be <+14>:	mov    r15,rdi
   0x00007ffff7a170c1 <+17>:	push   r13
   0x00007ffff7a170c3 <+19>:	push   r12
   0x00007ffff7a170c5 <+21>:	mov    r14,r9
   0x00007ffff7a170c8 <+24>:	push   rbp
   0x00007ffff7a170c9 <+25>:	push   rbx
   0x00007ffff7a170ca <+26>:	mov    r12,rdx
   0x00007ffff7a170cd <+29>:	mov    rbp,rsi
   0x00007ffff7a170d0 <+32>:	sub    rsp,0x28
=> 0x00007ffff7a170d4 <+36>:	mov    rax,QWORD PTR [rdi]
(gdb) info registers
rax            0x0	0
rbx            0x555555765c30	93824994401328
rcx            0x0	0
rdx            0x0	0
rsi            0x0	0
rdi            0x0	0
rbp            0x0	0x0
rsp            0x7fffffffd9d0	0x7fffffffd9d0
r8             0x0	0
r9             0x7fffffffda30	140737488345648
r10            0xffffffffffffffb0	-80
r11            0x7ffff7dcfc78	140737351842936
r12            0x0	0
r13            0x0	0
r14            0x7fffffffda30	140737488345648
r15            0x0	0
rip            0x7ffff7a170d4	0x7ffff7a170d4 <__gconv+36>

The contained file can be extracted successfully on Windows. I'll email you the offending CAB file.

Fail to properly create path components coming from the archive

Problem description

Path components coming from the archive are not properly created.

Cause

In function ensure_filepath() from cabextract.c line 1229, lstat() is used to get information about that particular file system entry and then, at line 1231, even if the lstat() call failed (for example the entry does not exist at all in the file system), the st_buf is still used for determining if the path is a directory or not.

Examples

Fail - cabextract does not create the path component coming from the archive

[~]> ls *
dest:

src:
W2KSP4_EN.EXE

[~]> cabextract -d dest -F i386/mspatcha.dl_ src/W2KSP4_EN.EXE
Extracting cabinet: src/W2KSP4_EN.EXE
  extracting dest/i386/mspatcha.dl_
dest/i386/mspatcha.dl_: No such file or directory

All done, errors in processing 1 file(s)

Pass - manually create the path component before calling cabextract

[~]> mkdir dest/i386

[~]> cabextract -d dest -F i386/mspatcha.dl_ src/W2KSP4_EN.EXE
Extracting cabinet: src/W2KSP4_EN.EXE
  extracting dest/i386/mspatcha.dl_

All done, no errors.

Info - program version

[~]> cabextract -v
cabextract version 1.10

Proposed solution

The proposed patch fixes the issue and the archive directory components are properly created.

diff --git a/cabextract/src/cabextract.c b/cabextract/src/cabextract.c
index 0a19a9b..a58b0bd 100644
--- a/cabextract/src/cabextract.c
+++ b/cabextract/src/cabextract.c
@@ -1227,8 +1227,10 @@ static int ensure_filepath(char *path, int n) {
       /* in the archive-determined part of the path and not keeping symlinks:
        * use lstat() and delete symlinks if found */
       ok = (lstat(path, &st_buf) == 0);
-      if (ok && (st_buf.st_mode & S_IFMT) == S_IFLNK) unlink(path);
-      ok = S_ISDIR(st_buf.st_mode);
+      if (ok) {
+         if ((st_buf.st_mode & S_IFMT) == S_IFLNK) unlink(path);
+         ok = S_ISDIR(st_buf.st_mode);
+      }
     }
     if (!ok) ok = (mkdir(path, 0777 & ~user_umask) == 0);
     *p = '/';

please push forward expand.c

Hello.

Currently expand.c resides in a "test" directory,
which makes it being skipped by the distributions.
Unfortunately, there seem to be no other extractor
for the mscompress files.
Can expand.c be moved to the more visible location,
where it will be picked up by the distributions?
Maybe it should even became a part of cabextract?

[libmspack Patch] MinGW: "error: too many arguments to function 'mkdir'"

There is an error in the file test/chmx.c of libmspack when building on Win32 with MinGW:

error: too many arguments to function 'mkdir'

On Win32 the mkdir command only uses a single argument. It does not support the permissions flags of Unix systems.

Attached is a patch to fix this. It checks for definitions of "WIN32" or "MINGW32" and changes the mkdir command from mkdir(path, flags) to mkdir(path).

libmspack-0.5-cef3a03_test__chmx.c.patch.txt

chmextract

how can I compile and run chmextract.c file in your examples?

Cannot extract files from a .cab file containing file names encoded in shift_JIS

If I try to extract files from a .cab file containing file names encoded in shift_JIS, it aborts with the following error:

Extracting cabinet: DENKEN CG集(同人).cab
  extracting DENKEN?@CG?W?i???l?j/DENKEN?@CG?W.d88
DENKEN?@CG?W?i???l?j/DENKEN?@CG?W.d88: can't create file path

Using -f to try to workaround it also doesn't work.

The sample .cab file can be downloaded here.

Plenty of other Japanese sample .cab files can be obtained here.

Issue with KWAJ method 2 decompression

Using the contents of this file: MOUSE901.ZIP ...

Use msexpand to decompress MOUSE.IN$. Expected results: A readable text file. Actual results: a garbled file.

The problem exists for all KWAJ#2 files that I've tested. Note that the EXPAND.EXE DOS utility from MOUSE901.ZIP can successfully decompress the file.

What I think is that KWAJ#2 is supposed to use the mode that libmspack calls LZSS_MODE_QBASIC, instead of LZSS_MODE_EXPAND.

Or maybe there is a different kind of KWAJ#2 file out there that libmspack correctly decompresses. If so, I'd like to know about it.

Some other places to find KWAJ#2 files: lifepl02.zip, PRO207/

Buffer overflow in kwajd_read_headers()

Apparently buffer overflow is possible in the kwajd_read_headers function:

$ printf 'KWAJ\210\360\47\3210000\377%07d\0\0%013d' > overflow.kwaj
$ valgrind -q msexpand overflow.kwaj /dev/null
==26911== Invalid write of size 1
==26911==    at 0x4840E2A: kwajd_read_headers (kwajd.c:221)
==26911==    by 0x4840FD6: kwajd_open (kwajd.c:108)
==26911==    by 0x4842264: kwajd_decompress (kwajd.c:334)
==26911==    by 0x1088A7: main (msexpand.c:34)
==26911==  Address 0x4a1b555 is 0 bytes after a block of size 13 alloc'd
==26911==    at 0x482E2BC: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==26911==    by 0x483BF46: msp_alloc (system.c:208)
==26911==    by 0x4840D5C: kwajd_read_headers (kwajd.c:202)
==26911==    by 0x4840FD6: kwajd_open (kwajd.c:108)
==26911==    by 0x4842264: kwajd_decompress (kwajd.c:334)
==26911==    by 0x1088A7: main (msexpand.c:34)
==26911== 
==26911== Invalid write of size 1
==26911==    at 0x4840E67: kwajd_read_headers (kwajd.c:226)
==26911==    by 0x4840FD6: kwajd_open (kwajd.c:108)
==26911==    by 0x4842264: kwajd_decompress (kwajd.c:334)
==26911==    by 0x1088A7: main (msexpand.c:34)
==26911==  Address 0x4a1b556 is 1 bytes after a block of size 13 alloc'd
==26911==    at 0x482E2BC: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==26911==    by 0x483BF46: msp_alloc (system.c:208)
==26911==    by 0x4840D5C: kwajd_read_headers (kwajd.c:202)
==26911==    by 0x4840FD6: kwajd_open (kwajd.c:108)
==26911==    by 0x4842264: kwajd_decompress (kwajd.c:334)
==26911==    by 0x1088A7: main (msexpand.c:34)
==26911== 

Tested against git master (6037317).

Found using American Fuzzy Lop:
http://lcamtuf.coredump.cx/afl/

build fails on macos

when I go to libmspack and so sh rebuild.sh, I'm getting

mspack/oabd.c:375:12: error: conflicting types for 'copy_fh'
static int copy_fh(struct mspack_system *sys, struct mspack_file *infh,
^
mspack/oabd.c:37:12: note: previous declaration is here
static int copy_fh(struct mspack_system *sys, struct mspack_file *infh,
^
1 error generated.

Conflicting definitions for copy_fh

mspack/oadb.c: contains the function copy_fh() with bytes_to_copy being of type size_t on line 38 and unsigned int on line 377. This does not work with gcc 9.2.1 20200206.

cabextract doesn't build from master

Noticed while investigating #22.

Current master (43682d7) doesn't build for me (while 1.7 and v1.8 tags do):

gcc -DHAVE_CONFIG_H -I.     -g -O2 -c -o src/cabextract.o src/cabextract.c
src/cabextract.c: In function 'main':
src/cabextract.c:397:25: error: 'MSCABD_PARAM_SALVAGE' undeclared (first use in this function); did you mean 'MSCABD_PARAM_SEARCHBUF'?
   cabd->set_param(cabd, MSCABD_PARAM_SALVAGE, args.fix);
                         ^~~~~~~~~~~~~~~~~~~~
                         MSCABD_PARAM_SEARCHBUF
src/cabextract.c:397:25: note: each undeclared identifier is reported only once for each function it appears in

Bisect shows it was

commit a8c22c9572d98d3e6832cd76b825bf1dc76d22e7
Author: Stuart Caie <[email protected]>
Date:   Fri Oct 26 19:09:43 2018 +0100

    Use pkg-config PKG_CHECK_MODULES to get external libmspack flags

:040000 040000 3a5f11d99686a26a6fbb52c9a6ff73db6da846a2 7f3c6f79a541cdefee092985d0a74572ed5de394 M	cabextract

This is on Gentoo amd64 (built with ./rebuild.sh from git, not using portage).

gcc version 7.3.0 (Gentoo 7.3.0-r4 p1.6)

Add a ‘make check’ rule

I'd like to routinely test libmspack in our Fedora builds. However the testing situation seems to be a bit of a mess. There are some test programs built, but it's not clear which ones we're meant to run, some run successfully, others do nothing, others fail.

You can add a make check rule very simply by listing the test programs which are meant to pass. It's a one line addition to Makefile.am, for example:

TESTS = test/cabd_test test/chmd_test test/kwajd_test

(or whatever the correct list of tests is supposed to be). That won't quite work unless you make test/ into a subdir and put the Makefile.am in there, or adjust the tests so they can run from the top source directory, but hopefully you get the idea.

Malloc size error in chmd.c:1327:34

System info

Ubuntu x86_64, clang 6.0, chmextract (latest master 7e63519)

Configure

CFLAGS="-g -fsanitize=address" LDFLAGS="-fsanitize=address" ./configure

Command line

./libmspack/examples/chmextract @@

AddressSanitizer output

==19777==WARNING: AddressSanitizer failed to allocate 0xffffffffffffc044 bytes
==19777==AddressSanitizer's allocator is terminating the process instead of returning 0
==19777==If you don't like this behavior set allocator_may_return_null=1
==19777==AddressSanitizer CHECK failed: /home/seviezhou/llvm-6.0.0/projects/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cc:225 "((0)) != (0)" (0x0, 0x0)
    #0 0x4e7a9f in __asan::AsanCheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) /home/seviezhou/llvm-6.0.0/projects/compiler-rt/lib/asan/asan_rtl.cc:69
    #1 0x504a15 in __sanitizer::CheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) /home/seviezhou/llvm-6.0.0/projects/compiler-rt/lib/sanitizer_common/sanitizer_termination.cc:79
    #2 0x4ed8c6 in __sanitizer::ReportAllocatorCannotReturnNull() /home/seviezhou/llvm-6.0.0/projects/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cc:225
    #3 0x4ed903 in __sanitizer::ReturnNullOrDieOnFailure::OnBadRequest() /home/seviezhou/llvm-6.0.0/projects/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cc:241
    #4 0x41e9d6 in __asan::asan_malloc(unsigned long, __sanitizer::BufferedStackTrace*) /home/seviezhou/llvm-6.0.0/projects/compiler-rt/lib/asan/asan_allocator.cc:856
    #5 0x4de584 in __interceptor_malloc /home/seviezhou/llvm-6.0.0/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:89
    #6 0x526156 in read_sys_file /home/seviezhou/libmspack/libmspack/mspack/chmd.c:1327:34
    #7 0x51ab64 in chmd_init_decomp /home/seviezhou/libmspack/libmspack/mspack/chmd.c:1059:16
    #8 0x51ab64 in chmd_extract /home/seviezhou/libmspack/libmspack/mspack/chmd.c:974
    #9 0x517045 in main /home/seviezhou/libmspack/libmspack/examples/chmextract.c:104:17
    #10 0x7f52106ae83f in __libc_start_main /build/glibc-e6zv40/glibc-2.23/csu/../csu/libc-start.c:291
    #11 0x41a398 in _start (/home/seviezhou/libmspack/libmspack/examples/chmextract+0x41a398)

POC

malloc-size-error-read_sys_file-chmd-1327.zip

1.9.1: issue with dist tar ball

Looks like in this repo is maintained not one but two separated projects.
This makes a bit difficult to package (automatically) libmspack.
My suggestion is to separate those two projects into two repos (clone and move up each of the projects up in directory hierarchy and delete second project from the copies) or provide dist tar balls generated by "make distcheck" on the https://www.cabextract.org.uk/libmspack/ (because content of that page is not up to date).

configure / libtool fails with -flto

build with -flto fails

...
libtool: compile:  x86_64-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I. -I/var/tmp/portage/dev-libs/libmspack-0.10.1_alpha/work/libmspack-0.10.1alpha -I/var/tmp/portage/dev-libs/libmspack-0.10.1_alpha/work/libmspack-0.10.1alpha/mspack -I/var/tmp/portage/dev-libs/libmspack-0.10.1_alpha/work/libmspack-0.10.1alpha/test -Wall -Wextra -Wno-unused-parameter -Wno-unused-result -march=native -O2 -flto -fno-stack-protector -pipe -c mspack/crc32.c  -fPIC -DPIC -o mspack/.libs/crc32.o
libtool: link: x86_64-pc-linux-gnu-ar cru .libs/libmschmd.a mspack/.libs/system.o mspack/.libs/chmd.o mspack/.libs/lzxd.o 
libtool: link: x86_64-pc-linux-gnu-ranlib .libs/libmschmd.a
libtool: link: ( cd ".libs" && rm -f "libmschmd.la" && ln -s "../libmschmd.la" "libmschmd.la" )
libtool: link: x86_64-pc-linux-gnu-ar cru .libs/libmscabd.a mspack/.libs/system.o mspack/.libs/cabd.o mspack/.libs/lzxd.o mspack/.libs/mszipd.o mspack/.libs/qtmd.o 
libtool: link: x86_64-pc-linux-gnu-ranlib .libs/libmscabd.a
libtool: link: /usr/bin/x86_64-pc-linux-gnu-nm -B  mspack/.libs/system.o mspack/.libs/cabc.o mspack/.libs/cabd.o mspack/.libs/chmc.o mspack/.libs/chmd.o mspack/.libs/hlpc.o mspack/.libs/hlpd.o mspack/.libs/litc.o mspack/.libs/litd.o mspack/.libs/kwajc.o mspack/.libs/kwajd.o mspack/.libs/szddc.o mspack/.libs/szddd.o mspack/.libs/oabc.o mspack/.libs/oabd.o mspack/.libs/lzxc.o mspack/.libs/lzxd.o mspack/.libs/mszipc.o mspack/.libs/mszipd.o mspack/.libs/qtmd.o mspack/.libs/lzssd.o mspack/.libs/crc32.o   |  | /bin/sed 's/.* //' | sort | uniq > .libs/libmspack.exp
./libtool: eval: line 1774: syntax error near unexpected token `|'
./libtool: eval: line 1774: `/usr/bin/x86_64-pc-linux-gnu-nm -B  mspack/.libs/system.o mspack/.libs/cabc.o mspack/.libs/cabd.o mspack/.libs/chmc.o mspack/.libs/chmd.o mspack/.libs/hlpc.o mspack/.lib

MSZIP Compress?

I see that mszipc.c is not implemented yet. In the source code, it's mention that "MSZIP is equivalent to the deflate method". Deflate is part of the zlib library.

If deflate() can be used to decompress MSZIP files, is the opposite true as well? Can the zlib's compress() function be used to create a MSZIP compressed file? If so, what's stopping you from implementing mszipc.c?

configure / libtool fails with -flto

Complinig libmspack 1.9.1 prints:

make V=1

make  all-am
make[1]: Entering directory '/src/mail/libmspack-1.9.1/libmspack'
/bin/sh ./libtool  --tag=CC   --mode=link gcc -Wall -Wextra -Wno-unused-parameter -Wno-unused-result -flto -pipe -O3 -export-symbols-regex '^mspac
k_' -version-info 1:0:1 -no-undefined -flto=6 -Wl,-O1,-s -o libmspack.la -rpath /usr/local/lib mspack/system.lo mspack/cabc.lo mspack/cabd.lo mspa
ck/chmc.lo mspack/chmd.lo mspack/hlpc.lo mspack/hlpd.lo mspack/litc.lo mspack/litd.lo mspack/kwajc.lo mspack/kwajd.lo mspack/szddc.lo mspack/szddd
.lo mspack/oabc.lo mspack/oabd.lo mspack/lzxc.lo mspack/lzxd.lo mspack/mszipc.lo mspack/mszipd.lo mspack/qtmd.lo mspack/lzssd.lo mspack/crc32.lo  
libtool: link: /usr/local/bin/nm -B  mspack/.libs/system.o mspack/.libs/cabc.o mspack/.libs/cabd.o mspack/.libs/chmc.o mspack/.libs/chmd.o mspack/
.libs/hlpc.o mspack/.libs/hlpd.o mspack/.libs/litc.o mspack/.libs/litd.o mspack/.libs/kwajc.o mspack/.libs/kwajd.o mspack/.libs/szddc.o mspack/.li
bs/szddd.o mspack/.libs/oabc.o mspack/.libs/oabd.o mspack/.libs/lzxc.o mspack/.libs/lzxd.o mspack/.libs/mszipc.o mspack/.libs/mszipd.o mspack/.lib
s/qtmd.o mspack/.libs/lzssd.o mspack/.libs/crc32.o   |  | /usr/local/bin/sed 's/.* //' | sort | uniq > .libs/libmspack.exp
./libtool: eval: line 1845: syntax error near unexpected token `|'
./libtool: eval: line 1845: `/usr/local/bin/nm -B  mspack/.libs/system.o mspack/.libs/cabc.o mspack/.libs/cabd.o mspack/.libs/chmc.o mspack/.libs/
chmd.o mspack/.libs/hlpc.o mspack/.libs/hlpd.o mspack/.libs/litc.o mspack/.libs/litd.o mspack/.libs/kwajc.o mspack/.libs/kwajd.o mspack/.libs/szdd
c.o mspack/.libs/szddd.o mspack/.libs/oabc.o mspack/.libs/oabd.o mspack/.libs/lzxc.o mspack/.libs/lzxd.o mspack/.libs/mszipc.o mspack/.libs/mszipd
.o mspack/.libs/qtmd.o mspack/.libs/lzssd.o mspack/.libs/crc32.o   |  | /usr/local/bin/sed 's/.* //' | sort | uniq > .libs/libmspack.exp'
make[1]: *** [Makefile:894: libmspack.la] Error 2
make[1]: Leaving directory '/src/mail/libmspack-1.9.1/libmspack'
make: *** [Makefile:718: all] Error 2

I do not see anything wrong with the Makefile.am, but this is the only package that creates this problem. Moreover, the problem appars also within clamav, when the internal libmspack is used.

Support Intra Package Delta (IPD) format, aka PA30

I tried extracting this cab file using cabextract but it wasn't extracted correctly. (the folders aren't extracted)
I used following command from windows and it extracted as it should've.

‍‍expand -F:* <cabfile name>.cab C:<target_dir>

​I'm using cabextract 0.6 and libmspack 0.5

Thanks for your efforts,
Ali

memory exhausted in chmd_read_headers()

Description:

​ function chmd_read_headers() in libmspack has a memory exhausted problem

Affected version:

​ libmspack 0.9.1 alpha

Details:

​ Critical code(in chmd.c):

line 346~352:

  chm->chunk_size = EndGetI32(&buf[chmhs1_ChunkSize]);
// chm->chunk_size is directly from input file and can be controlled by attackers for malicious usage(memory exhaustion )
  chm->density    = EndGetI32(&buf[chmhs1_Density]);
  chm->depth      = EndGetI32(&buf[chmhs1_Depth]);
  chm->index_root = EndGetI32(&buf[chmhs1_IndexRoot]);
  chm->num_chunks = EndGetI32(&buf[chmhs1_NumChunks]);
  chm->first_pmgl = EndGetI32(&buf[chmhs1_FirstPMGL]);
  chm->last_pmgl  = EndGetI32(&buf[chmhs1_LastPMGL]);
...
line 418~420:

 if (!(chunk = (unsigned char *) sys->alloc(sys, (size_t)chm->chunk_size))) {
     // chm->chunk_size not checked
    return MSPACK_ERR_NOMEMORY;
  }

​ In function chmd_read_headers() in file chmd.c,chm->chunk_size was read from chm file and lately allocate memory of size chm->chunk_size, without check whether chm->chunk_size is valid, Carefully constructed chm file will lead to memory exhausted problem.

chm->chunk_size is 32bit, it can be as large as 0xffffffff. The maximum memory usage of chmd_read_headers() can be 4G RAM, even if the input file is very small.

poc file

https://github.com/JsHuang/pocs/blob/master/libmspack/oom-chm

Credit: ADLab of Venustech

libmspack tests failing at v0.6alpha

Hi, I am using libmspack for one of my projects, and I have realized some of the tests are failing.

  1. Are these tests updated for v0.6alpha?
    In cab_test, the test is expecting "test_files/cabd/partial_str_nofname.cab" to error out with MSPACK_ERR_DATAFORMAT, but it is throwing MSPACK_ERR_READ
  2. Is there any script to run cabd_c10 after we download the c10-archiver-r1.iso, or do we need to manually exctract all of it and out in separate folders manually as explained in the description?.
  3. For msdecompile_md5, could not find hhctrl.ocx and itss.dll in Microsoft HTML Help Workshop.

memory exhausted in oabd_decompress()

Description:

​ function oabd_decompress() in libmspack has a memory exhausted problem

Affected version:

​ libmspack 0.9.1 alpha

Details:

​ Critical code: oabd.c line 132~149:

  block_max   = EndGetI32(&hdrbuf[oabhead_BlockMax]); 
// block_max is directly from input file and can be controlled by attackers for malicious usage (memory exhaustion )
  target_size = EndGetI32(&hdrbuf[oabhead_TargetSize]);

  /* We use it for reading block headers too */
  if (block_max < oabblk_SIZEOF)
    block_max = oabblk_SIZEOF;

  outfh = sys->open(sys, output, MSPACK_SYS_OPEN_WRITE);
  if (!outfh) {
    ret = MSPACK_ERR_OPEN;
    goto out;
  }

  buf = sys->alloc(sys, block_max);			// block_max not checked
  if (!buf) {
    ret = MSPACK_ERR_NOMEMORY;
    goto out;
  }

​ In function oabd_decompress() in file oabd.c(line 132~149),block_max was read from oab file and lately allocate memory of size block_max, without check whether block_max is valid, Carefully constructed oab file will lead to memory exhausted problem.

block_max is 32bit, it can be as large as 0xffffffff. The maximum memory usage of oabd_decompress() can be 4G RAM, even if the input file is very small.

poc file

https://github.com/JsHuang/pocs/blob/master/libmspack/oom-oab

Credit: ADLab of Venustech

extra = 0 confusion

lzxd.c has this code: https://github.com/kyz/libmspack/blob/master/libmspack/mspack/lzxd.c#L589-L609

Which suggests that extra = 0 is not defined in the LZX spec. However, on this spec page: https://docs.microsoft.com/en-us/previous-versions/bb417343(v=msdn.10)#microsoft-lzx-data-compression-format

( The formatting is unfortunately very mangled, but it's the best I can find )

There is an explicit callout for the extra = 0 case:

                  else if (extra > 0) /* just some verbatim bits */
                        verbatim_bits ← readbits(extra)
                        aligned_bits  ← 0
                  else /* no verbatim bits */
                        verbatim_bits ← 0
                        aligned_bits  ← 0
                  endif

Implying that match_offset from the position slot table should be left alone, not reset to such a close offset. Was this another discrepancy between the Java decoder implementation and the spec, or did you misread the specification?

I noticed this when working on my own implementation; I have not checked to see if LZX files in the wild hit this case.

cabextract: Writing into symlinks

The problem
Let's say we have a CAB file that contains hello.dll and a symlink with the same name to some other file in the current directory.
With this when you extract the CAB the symlink is followed and it's target file is overwritten.

Why is it problem
AFAIK when writing files, following file symlinks is generally unsafe (?), at least within context of archive extraction (again, afaik)
EDIT: Tried what other archive tools do

  • zip (Info-ZIP) asks what to do when it finds a symlink (with same name as to-be extracted file)
  • tar -xf ignores the symlink (eg. unlinks and writes extracted file)

I've made a super simple patch in my fork https://github.com/wereii/libmspack/commits/master that adds build option for opting into symlink checks before a file is opened for writing (and unlinking/removing possible link before the fopen happens, so the file is written as is and not into the symlinked file, nothing more).

Though the patch is just a simple thing that works for me and

  1. it's not thorough, I've simply put the un/link check before opening file for writing and excluding special files
  2. there could be bunch of ways to resolve this (fail on symlinks, warn, ask, ... and probably be configurable as cli argument).

Either way this behavior requires some more though so here we are.

Parallel build issue: error: cannot find the library 'libmschmd.la' or unhandled argument 'libmschmd.la'

When compiling with make -j 4 or larger you sometimes hit a parallel make issue:

libtool: link: x86_64-pc-linux-gnu-ar cru .libs/libmscabd.a mspack/.libs/system.o mspack/.libs/cabd.o mspack/.libs/lzxd>
libtool:   error: cannot find the library 'libmschmd.la' or unhandled argument 'libmschmd.la'
libtool: link: x86_64-pc-linux-gnu-ranlib .libs/libmschmd.a
make[1]: *** [Makefile:836: test/chmd_test] Error 1

Doesn't happen with "-j1".

build.log.gz

Compiler error with 1.9.1 / gcc 9.3.1

With gcc 9.3.1 20200506, compiling libmspack 1.9.1 prints:

  CC       mspack/oabd.lo
mspack/oabd.c:375:12: error: conflicting types for ‘copy_fh’
  375 | static int copy_fh(struct mspack_system *sys, struct mspack_file *infh,
      |            ^~~~~~~
mspack/oabd.c:37:12: note: previous declaration of ‘copy_fh’ was here
   37 | static int copy_fh(struct mspack_system *sys, struct mspack_file *infh,
      |            ^~~~~~~
mspack/oabd.c:37:12: warning: ‘copy_fh’ used but never defined
mspack/oabd.c:375:12: warning: ‘copy_fh’ defined but not used [-Wunused-function]
  375 | static int copy_fh(struct mspack_system *sys, struct mspack_file *infh,
      |            ^~~~~~~
make[1]: *** [Makefile:1071: mspack/oabd.lo] Error 1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.