pombreda / libarchive

Automatically exported from code.google.com/p/libarchive
Other
0 stars 0 forks source link

segmentation fault when writing iso9660 image #378

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
It's pretty difficult to reproduce. I've observed seg faults during the copy of 
an iso9660 image. Equivalent test code is something like:

#include <archive.h>
#include <archive_entry.h>

int stuff() {
    struct archive *in = NULL;
    struct archive *out = NULL;
    struct archive_entry *entry = NULL;
    int r = 0;
    char* data = NULL;
    const int sizeBuffer = 10000000;

    in = archive_read_new();
    out = archive_write_new();
    archive_read_support_format_iso9660(in);
    archive_write_set_format_iso9660(out);

    archive_write_set_options(out, "boot-type=no-emulation,boot=boot/isolinux/isolinux.bin,boot-catalog=boot/isolinux/boot.cat,boot-load-size=4,boot-info-table");
    data = (char*) malloc(sizeBuffer);

    archive_read_open_filename(in, "Core.iso", 10490);
    archive_write_open_filename(out, "test1.iso");

    // copy cycle
    while(archive_read_next_header(in, &entry) == ARCHIVE_OK)
    {
            archive_write_header(out, entry);
            r = archive_read_data(in, data, sizeBuffer);
            if(r != archive_write_data(out, data, r))
            {
                break;
            }
    }

    archive_write_close(out);
    archive_read_close(in);
    archive_write_finish(out);
    archive_read_finish(in);
    free(data);

    return 0;
}

int main() {
  while(1) {
    stuff();
  }
  return 0;
}

However, it seems to be critically dependent on the length of the system temp 
path.

What version are you using?
libarchive 3.1.2

On what operating system?
Windows/MinGW

How did you build?  (cmake, configure, or pre-packaged binary)
configure/make

What compiler or development environment (please include version)?
mingw/gcc4.8.2

Please provide any additional information below.

The root cause in my case was some bad pointer arithmetic in __archive_mktemp:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 7924.0x19f4]
0x75379b6b in msvcrt!memcpy () from C:\Windows\syswow64\msvcrt.dll
(gdb) where
#0  0x75379b6b in msvcrt!memcpy () from C:\Windows\syswow64\msvcrt.dll
#1  0x72ba2f40 in ?? () from C:\Windows\SysWOW64\rsaenh.dll
#2  0x72ba2e08 in ?? () from C:\Windows\SysWOW64\rsaenh.dll
#3  0x72ba4449 in RSAENH!CPGenRandom () from C:\Windows\SysWOW64\rsaenh.dll
#4  0x72bf4fb9 in CryptGenRandom () from C:\Windows\SysWOW64\cryptsp.dll
#5  0xfafc8614 in ?? ()
#6  0x004427ef in __archive_mktemp (tmpdir=tmpdir@entry=0x0)
    at libarchive/archive_util.c:300
#7  0x00432ee3 in iso9660_write_header (a=0x16c37818, entry=0x16c1b1a0)
    at libarchive/archive_write_set_format_iso9660.c:1620
#8  0x0042980c in _archive_write_header (_a=0x16c37818, entry=0x16c1b1a0)
    at libarchive/archive_write.c:640
(gdb) up (x6)

#6  0x004427ef in __archive_mktemp (tmpdir=tmpdir@entry=0x0)
    at libarchive/archive_util.c:300
300                     if (!CryptGenRandom(hProv, (DWORD)(ep - 
p)*sizeof(wchar_t),
(gdb) print (ep -p)
$2 = -16749434

The relevant pointer initialisers are:
    /*
     * Create a temporary file.
     */
    archive_wstrcat(&temp_name, L"libarchive_");
    xp = temp_name.s + archive_strlen(&temp_name);
    archive_wstrcat(&temp_name, L"XXXXXXXXXX");
    ep = temp_name.s + archive_strlen(&temp_name);

The problem is that archive_wstrcat can reallocate temp_name's buffer if it's 
not long enough and seemingly this does occasionally happen. The fix is 
relatively straightforward:
    /*
     * Create a temporary file.
     */
    const wchar_t* suffix =  L"XXXXXXXXXX";
    archive_wstrcat(&temp_name, L"libarchive_");
    archive_wstrcat(&temp_name,suffix);
    ep = temp_name.s + archive_strlen(&temp_name);
    xp = ep - wcslen(suffix);

Original issue reported on code.google.com by veg...@gmail.com on 25 Sep 2014 at 4:32

GoogleCodeExporter commented 9 years ago
Thank you for such a detailed bug report.

I've made the changes you suggest at

https://github.com/libarchive/libarchive/commit/c1732828cd802c26e18891c4c95f49c1
5819c985

Could you please verify that this fixes the issue you've been seeing?

Original comment by kientzle@gmail.com on 26 Sep 2014 at 1:53

GoogleCodeExporter commented 9 years ago
Hi there,

No problem - it's the least I can do :-). Yes, a build based on this committal 
is working in my system here.

Thanks,
Andy

Original comment by veg...@gmail.com on 29 Sep 2014 at 10:59