This is an archive of the discontinued LLVM Phabricator instance.

[DebugInfo] Prevent infinite recursion for malformed DWARF
ClosedPublic

Authored by JDevlieghere on Feb 8 2018, 2:49 PM.

Details

Summary

This prevents infinite recursion in DWARFDie::findRecursively for
malformed DWARF where a DIE references itself.

https://bugs.llvm.org/PR36257

Diff Detail

Repository
rL LLVM

Event Timeline

JDevlieghere created this revision.Feb 8 2018, 2:49 PM

I plan on adding a verifier check for this in a follow up commit.

aprantl added inline comments.Feb 8 2018, 3:05 PM
llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
312 ↗(On Diff #133496)

Perhaps add a comment what this means?

llvm/test/tools/llvm-dwarfdump/X86/invalid_abstract_origin.s
17 ↗(On Diff #133496)

Is there anything you could CHECK? Otherwise this will pass even if llvm-mc is returning empty output.

  • Add comment
  • Add CHECK clause
aprantl accepted this revision.Feb 8 2018, 3:32 PM
This revision is now accepted and ready to land.Feb 8 2018, 3:32 PM

I'm guessing this is insufficient for catching indirect recursion (DIE A refers to DIE B and B back to A)?

Ideally/the original version of this, I think was non-recursive and only specifically looked for certain attributes in order and then stopped. I'd sort of rather than, because it's more constrained.

I'm guessing this is insufficient for catching indirect recursion (DIE A refers to DIE B and B back to A)?

That's true, unfortunately. Is it worth to convert this to a worklist and keep track of the already-seen DIEs?

Ideally/the original version of this, I think was non-recursive and only specifically looked for certain attributes in order and then stopped. I'd sort of rather than, because it's more constrained.

The original find() still exists, so I'd expect this variant only to be used where the recursive property is needed.

Ideally/the original version of this, I think was non-recursive and only specifically looked for certain attributes in order and then stopped. I'd sort of rather than, because it's more constrained.

The original find() still exists, so I'd expect this variant only to be used where the recursive property is needed.

'find()' only searches the current DIE. findRecursively is needed when looking through abstract or specification references - but these aren't, so far as I know, arbitrarily nested (you can't have an unlimited chain of abstract/specifications - really you can only have at most one of each, in a specific order (abstract then specification) - as far as I recall/know). So unlimited recursion is a bit overpowered here.

Could you check the revision history here? I'm pretty sure the first version of this I reviewed from Greg wasn't recursive - and then it became recursive at some point to handle something needed, but maybe those decisions need to be reexamined?

Could you check the revision history here? I'm pretty sure the first version of this I reviewed from Greg wasn't recursive - and then it became recursive at some point to handle something needed, but maybe those decisions need to be reexamined?

It was @clayborg himself that updated the implementation. (D40156 rL319104)

The previous implementation would only look 1 DW_AT_specification or DW_AT_abstract_origin deep. This means DWARFDie::getName() would fail in certain cases. I ran into such a case while creating a tool that used the LLVM DWARF parser to generate a symbolication format so I have seen this in the wild.

JDevlieghere removed a subscriber: clayborg.
  • Turn recursion into worklist.
  • Keep track of already seen DIEs.

Use SmallSet<DWARFDie, 3> (running dsymutil over clang showed that there were never more than 3 elements in the set for valid DWARF).

aprantl accepted this revision.Apr 30 2018, 9:23 AM

Thanks for checking!

llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
300 ↗(On Diff #144485)

Perhaps add a comment explaining that this avoids infinite recursion on malformed input and empirically we never have a depth>3 ?

This revision was automatically updated to reflect the committed changes.

Sorry - could we revisit this?

I think my concerns expressed still haven't been resolved:

"Could you check the revision history here? I'm pretty sure the first
version of this I reviewed from Greg wasn't recursive - and then it became
recursive at some point to handle something needed, but maybe those
decisions need to be reexamined?" (& related comments back there)