[llvm-bugs] [Bug 25877] New: Segfault when creating archive from lib.exe-created archive

via llvm-bugs llvm-bugs at lists.llvm.org
Thu Dec 17 16:47:32 PST 2015


https://llvm.org/bugs/show_bug.cgi?id=25877

            Bug ID: 25877
           Summary: Segfault when creating archive from lib.exe-created
                    archive
           Product: tools
           Version: trunk
          Hardware: PC
                OS: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: llvm-ar
          Assignee: unassignedbugs at nondot.org
          Reporter: alex at crichton.co
                CC: llvm-bugs at lists.llvm.org
    Classification: Unclassified

Over in Rust-land we've got some custom code to create an archive by merging in
archives from other sources, often lib.exe created archives. Some of the
generated archives by LLVM end up being corrupted, spurring on some
investigation.

To reproduce this, the following sequence of steps should suffice. This is
currently specific to MSVC, but I suspect the bug is not Windows-specific:

1. Create an object file foo.obj from cl.exe
2. Create a directory named "reallylongname" and put foo.obj inside
3. Run "lib.exe /out:foo.lib reallylongname/foo.obj"
4. Create the following MRI script

    create libfoo.a
    addlib foo.lib
    save
    end

5. Run "llvm-ar.exe -M < script"

That should suffice in segfaulting llvm-ar (at least it does locally). In some
of our own tests we haven't seen segfaults but instead corrupt archives, but I
think it's all basically the same.

What I believe is going on here is that lib.exe creates archives where the name
of each member typically contains the full path rather than just the filename
component. For example the if you run `llvm-ar.exe t foo.lib` it will print
"reallylongname/foo.obj". Upon inspecting the archive it looks like lib.exe
handles these long file names via the standard put-the-name-in-the-string-table
method.

In the code for writeArchive, however, there's some disagreement about whether
filename(Name) or Name is emitted as the name of an entry. For example when
creating the string table (the writeStringTable function), the test for whether
an entry is emitted is based on filename(I.getName()). When emitting an old
entry, however, the name of the entry is I.getName() (in writeArchive). This
disagreement causes the StringMapIndexIter value to overrun the end of the
vector its iterating over, causing the segfault.

I believe we only see this on MSVC because lib.exe stores full paths whereas
most other archivers store file names (e.g. filename(Name) == Name).

tl;dr;, I think the fix is to change the call to printMemberHeader to use
filename(I.getName()), but I could be wrong! If you need any more info, just
let me know.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20151218/cbd7aa15/attachment.html>


More information about the llvm-bugs mailing list