This is an archive of the discontinued LLVM Phabricator instance.

[libcxxabi][demangler] Fix a crash in the demangler
ClosedPublic

Authored by erik.pilkington on May 19 2017, 2:15 PM.

Details

Summary

This patch fixes a bug in the demangler where a pack expansion template parameter substitution with more than one element in a lambda's parameter list resulted in either a misdemangle or a crash. I'll commit this change to ItaniumDemangle.cpp as well, as it has the same problem.

rdar://32098667

Thanks for taking a look,
Erik

Diff Detail

Repository
rL LLVM

Event Timeline

compnerd requested changes to this revision.May 21 2017, 8:27 PM
compnerd added inline comments.
src/cxa_demangle.cpp
3036 ↗(On Diff #99625)

I'm not sure how k1 can be < than k0. Isn't this effectively always going down the == path? If I'm just mistaken, then I think that this needs a comment.

3042–3051 ↗(On Diff #99625)

I think that using a bit of algorithm here might be nice.

std::ostringstream oss(db.names[lambda_pos]);
std::copy_if(db.names[k0], db.names[k1], std::ostream_iterator<std::string>(oss, ",  "),
             [](const std::string &s) -> bool { return !s.empty(); });
This revision now requires changes to proceed.May 21 2017, 8:27 PM
dexonsmith added inline comments.May 21 2017, 10:43 PM
src/cxa_demangle.cpp
3042–3051 ↗(On Diff #99625)

Introducing a dependency on std::ostream would be awkward. libc++abi.dylib cannot link against libc++.dylib, and it would bloat libc++abi.dylib to use custom traits to pull in a full copy.

src/cxa_demangle.cpp
3036 ↗(On Diff #99625)

I agree that it should be impossible, but the previous version handled this case with the if (db.names.size() < 2) check, when really db.names.size() can only be 1 or greater. I think it makes more sense to be paranoid here, I trust this file about as far as I can throw it (And I can't throw it very far, its not a tangible object).

compnerd added inline comments.May 22 2017, 9:17 PM
src/cxa_demangle.cpp
3036 ↗(On Diff #99625)

Hmm, how about being paranoid, and converting that to an assertion and then doing the == check? This code is already incredibly complicated, so adding additional things like this only makes it harder to understand whats going on.

3042–3051 ↗(On Diff #99625)

Ugh, thats a good point. Very well. However, there doesnt seem to be any iterator invalidation here, so we can still just iterate over a slice here, which would be nicer.

erik.pilkington edited edge metadata.

In this new patch:

Thanks for taking a look,
Erik

compnerd accepted this revision.May 23 2017, 5:45 PM
This revision is now accepted and ready to land.May 23 2017, 5:45 PM
dexonsmith added inline comments.May 23 2017, 7:08 PM
src/cxa_demangle.cpp
3036 ↗(On Diff #99930)

There's no #include <cassert> in this file. Depending on the standard library you're building against, you made need that here.

src/cxa_demangle.cpp
3036 ↗(On Diff #99930)

Sure, I'll commit this with that change.

This revision was automatically updated to reflect the committed changes.
kcc added a subscriber: kcc.May 24 2017, 1:44 PM

oss-fuzz finds the assertion failure in this new code:
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1834

r303806 removes the assertion (instead just returning first). I though this should never happen, I'm looking into this testcase to see if there is another bug here.
Thanks,
Erik

kcc added a comment.May 24 2017, 1:57 PM

I also encourage you to run the fuzzer on every change in this code.

kcc added a comment.May 24 2017, 2:01 PM

Also, are you now maintaining this code?
I am trying to find someone who wants to be CC-ed to other demangler bugs automatically reported by oss-fuzz.

Also, are you now maintaining this code?
I am trying to find someone who wants to be CC-ed to other demangler bugs automatically reported by oss-fuzz.

I don’t think I’ll accept the title of maintainer, (I only have one commit in this file!) but I have some plans to work on it and would be interested in hearing about any bugs found in the fuzzer.
Can you add erik.pilkington@gmail.com to your CC list?