This is an archive of the discontinued LLVM Phabricator instance.

[llvm-readobj/elf] - Refine the code for broken PT_DYNAMIC segment diagnostic.
ClosedPublic

Authored by grimar on Aug 7 2020, 5:32 AM.

Details

Summary

The code that reports "PT_DYNAMIC segment offset + size exceeds the size of the file"
has an issue: it is possible to bypass the validation by overflowing the size + offset result.

Diff Detail

Event Timeline

grimar created this revision.Aug 7 2020, 5:32 AM
grimar requested review of this revision.Aug 7 2020, 5:32 AM

Maybe it would be a good idea to split this change in two - one to update the test, and the other to change the behaviour - to ensure we don't accidentally break something in the test and behaviour at the same time. What do you think?

llvm/test/tools/llvm-readobj/ELF/malformed-pt-dynamic.test
136–137

Do we actually need to strip the section headers any more? I'm not sure the original issue really applies any more, as it was just to do with yaml2obj's previous limitations.

grimar planned changes to this revision.EditedAug 10 2020, 7:37 AM
grimar marked an inline comment as done.

Maybe it would be a good idea to split this change in two - one to update the test, and the other to change the behaviour - to ensure we don't accidentally break something in the test and behaviour at the same time. What do you think?

Well, OK. It might require more than 2 changes then, I think. Currently we report "PT_DYNAMIC segment offset + size exceeds the size of the file" for two slightly different cases
and it does not provide enough information about the difference. So I'd start from improving this message first. Then partially rewriting the test to a new one, simplified, which will use the new messages.
And then a third patch will change the logic and add the corresponding testing.

llvm/test/tools/llvm-readobj/ELF/malformed-pt-dynamic.test
136–137

I'll answer on this later. I am observing a different behavior without stripping headers - llvm-readobj complains about broken PT_DYNAMIC and says it going to use some information from the sections header instead. But I had no chance to investigate it better yet.

grimar marked an inline comment as done.
grimar added inline comments.
llvm/test/tools/llvm-readobj/ELF/malformed-pt-dynamic.test
136–137

The behavior with and without the section header table is slightly different. In D86073 I am testing both cases.

grimar updated this revision to Diff 286534.Aug 19 2020, 4:25 AM
grimar edited the summary of this revision. (Show Details)
  • Rebased and updated after landing patches that were splitted out.

(Now we have here a behavior update and the corresponding test case changes only).

This revision is now accepted and ready to land.Aug 20 2020, 12:06 AM
grimar reopened this revision.Aug 20 2020, 4:06 AM
This revision is now accepted and ready to land.Aug 20 2020, 4:06 AM
grimar planned changes to this revision.EditedAug 20 2020, 4:08 AM

Reverted, because broke UBSan. The test triggers an overflow issue in the different place in the llvm-readobj code.
(http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-bootstrap-ubsan/builds/21386/steps/check-llvm%20ubsan/logs/stdio)

grimar updated this revision to Diff 286974.Aug 21 2020, 2:13 AM
  • Updated checks in createDRI to fix issue reported by UBSan.

(I've verified that malformed-pt-dynamic.test now pass with -DLLVM_USE_SANITIZER=Undefined)

This revision is now accepted and ready to land.Aug 21 2020, 2:13 AM
grimar requested review of this revision.Aug 21 2020, 2:13 AM

PTAL

jhenderson accepted this revision.Aug 21 2020, 3:28 AM

Looks okay, but what was causing the UBSAN failure?

This revision is now accepted and ready to land.Aug 21 2020, 3:28 AM

Looks okay, but what was causing the UBSAN failure?

This line:

const uint8_t *Addr = Obj->base() + Offset;

I believe pointers are not allowed to overflow.

Looks okay, but what was causing the UBSAN failure?

This line:

const uint8_t *Addr = Obj->base() + Offset;

I believe pointers are not allowed to overflow.

Makes sense, thanks!