New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ISO9660 writer segfaults on deep directories #780
Comments
I just expanded that Wiki page considerably. Please let us know what other information would be helpful. |
Thank you very much for the quick response. Trying it out now. |
It would be tremendously helpful if there could be a minimal "hello world" example like this (but actually working):
|
Here's our basic example for writing an archive: https://github.com/libarchive/libarchive/wiki/Examples#a-basic-write-example The only pieces different for you would be setting the format differently, and setting the zisofs option with:
There are other samples in the |
Thanks, I started with |
Is it expected that generating a large zisofs will segfault? I followed minitar.c with minimal changes to enable zisofs generation. Works when archiving a few files but not with larger amounts (e.g, 10k files with 300 MB total). Segfault happens after all the files have been shown with -v. Here is my code. |
A stack trace would certainly help to narrow down the issue. That code is omitting a lot of error checks. In particular, you should absolutely be checking the return codes from these calls:
Note that the ISO9660 writer does a lot of work when you close the archive, so it's essential that you check the error codes from the |
Using the method from http://stackoverflow.com/questions/77005/how-to-generate-a-stacktrace-when-my-gcc-c-app-crashes I get:
I guess that's not too helpful? |
When I change the section to read
then I get
Is this normal? |
That stack overflow post is discussing how to build one part of an automatic problem reporting system. It's overkill for your needs. To get useful stack traces, you first need to recompile your app with the -g flag to enable debug information. If you are compiling and linking separately, you need to include it in both places. The easiest way to get a useful backtrace is simply to run your program under a debugger. If you have gdb, for instance:
When it fails, you can then use |
You should also print out the value of |
Thanks for the detailed instructions @kientzle helps me a lot.
So it looks to me like it has problems in |
This does help a lot:
Those comparison functions are not so simple that I can just eyeball the problem, though. Could you recompile a debug version of libarchive and see if you get any more detail? |
Assuming you mean
|
So it looks like cmp = p1->parent->dir_number - p2->parent->dir_number; causes the issue?
|
Changed the code like so:
With this result:
Just speculating here: p2 has NULL identifier, hence is the root directory, hence has no parent, yet the cmp line tries to access its parent, which SEGFAULTs? |
I think that explains the crash but not the bug. I think the bug might be that the root directory should not be in this table at all. It's been a long time since I looked at this code and I need to look up what the path_table is for. |
From ECMA-119 (also known as ISO9660), section 6.9:
So the compare function should always put the root directory before anything else. The following should achieve this:
|
If it really needs the fix above, it seems like it should crash in other cases as well. There's something else going on here... |
Does not crash on the cmp anymore, but now crashes in
and, for another set of test data (KDevelop-5.0.0-1-x86_64.AppImage), in
|
Can you reproduce this crash with a smaller number of files? If you could try running your sample program on just half of your input files, then keep cutting in half until you stop getting the crash, that would be interesting. (It would be easier for me to reproduce your problem if I could do it with fewer input files.) |
So you are saying you cannot reproduce the issue with an arbitrary large amount of files? |
I can consistently reproduce it with a particular directory of 598 files, but another with 1,000 files does not cause the problem. It still happens without the zisofs option, so that's unrelated. |
After some more experimenting, I've managed to narrow it further: the issue is triggered when you have a deep directory hierarchy. Here's my repro case:
That's a small enough case that I should be able to build a test around it and debug it. |
@probonopd : Could you tell me the deepest directory in the tree you're trying to archive? I think you can do this with something like the following:
This just lists all the files, replaces the file/dir names with '_' and sorts the result. You should see something like this:
The last item in this example has 13 '_' characters; that's the deepest part of the tree. Background: Plain ISO9660 has a limit of 7 directory levels. We use a standard "deep directory relocation" technique to handle directories deeper than that, but our current implementation only doubles the depth we can handle, resulting in a total limit of 13 directory levels. We seem to have a bug that results in a messed-up directory tree in memory when we exceed that limit. That should never happen: We should either handle it or produce a legible error message. I'll do some research to see if there are standard ways to push the deep-directory support further and also expand the tests to make sure we produce proper errors whenever we encounter directories deeper than we can handle. |
That's 16 "_", and xorriso with RR seems to do this. |
I would appreciate if you could experiment a bit and see if this explains what you're seeing: Do you consistently see the crash when the directory tree is more than 13 levels deep (and see it work correctly when the directory tree is shallower than that)? From what I'm seeing, it does not matter the number of files, only the depth of directory nesting. |
So far I can confirm that. |
Commit 14144ae extends the existing iso9660 test to exercise directories that are 13 levels deep. If you modify the test to go a couple more levels, you get a failing test that can be used to demonstrate this bug. |
@probonopd any update on this? |
Sorry, I have not followed up on this since I no longer have a need for writing ISO9660/zisofs. |
Unfortunately https://github.com/libarchive/libarchive/wiki/FormatISO9660 has been in a bad shape for a while; please document it better.
Is it possible to write zisofs with libarchive?
libarchive/libarchive/archive_write_set_options.3
Lines 366 to 398 in 7bb6d70
The text was updated successfully, but these errors were encountered: