This is an archive of the discontinued LLVM Phabricator instance.

[ELF] - Fixed behavior when amount of inputsections is too large.
AbandonedPublic

Authored by grimar on Oct 5 2016, 4:53 AM.

Details

Summary

There were 2 problems in this case. Imagine that anount of input sections
is incorrect and huge (> UINT32_MAX). Lets say it is x = UINT32_MAX + 1;

  1. On 64bit systems it just may crash with std::length_error when will try to allocate

more memory than is available.

  1. On 32bits situation is more interesting.
Sections.resize(Size);

will truncate Size to 0, so resize will work fine.
Next loop will never execute:

for (const Elf_Shdr &Sec : Obj.sections())

because Obj.sections() will return empty array because of implementation of:

template <class ELFT>
const typename ELFFile<ELFT>::Elf_Shdr *ELFFile<ELFT>::section_end() const {
  return section_begin() + getNumSections();
}

And finally linkage can complete fine without errors. That is what I am observing with testcase.
I suggest to limit amount of input sections to some reasonable amount. Not sure what is better
UINT16_MAX or UINT32_MAX., patch uses first for now.

Diff Detail

Event Timeline

grimar updated this revision to Diff 73622.Oct 5 2016, 4:53 AM
grimar retitled this revision from to [ELF] - Fixed behavior when amount of inputsections is too large..
grimar updated this object.
grimar added reviewers: ruiu, rafael, davide.
grimar added subscribers: llvm-commits, grimar, evgeny777.
ruiu edited edge metadata.Oct 5 2016, 10:46 AM

I got a feeling that these error checks are getting picky. It is OK to reject crazy numbers that only crash the linker, but essentially we should do what the object files tell us do. At least object files containing >65536 secitons seem plausible.

grimar updated this revision to Diff 74120.Oct 10 2016, 5:56 AM
grimar edited edge metadata.
  • Updated logic.
grimar added a comment.EditedOct 10 2016, 5:58 AM
In D25272#562436, @ruiu wrote:

I got a feeling that these error checks are getting picky. It is OK to reject crazy numbers that only crash the linker, but essentially we should do what the object files tell us do. At least object files containing >65536 secitons seem plausible.

What about current diff ? This change allows to move all check logic to inside Obj.sections(). Where I am planning to check if
size of total amount of sections exceeds the file buffer size.

ruiu added a comment.Oct 10 2016, 11:33 AM

Isn't this the same as the previous code?

In D25272#566393, @ruiu wrote:

Isn't this the same as the previous code?

Not exactly. It has almost the same functionality. My motivation was following. When we have code like:

uint64_t Size = this->ELFObj.getNumSections();
Sections.resize(Size);

Then we are almost unable to do something with possible crash and overflow on lld side. Ideally I think we do not want to insert checks in getNumSections() probably as some utils like llvm-objdump for example may want to show the value even if it is incorrect. So issue checking should happen only if we try to access the section content.
So plan was to do some checking in Obj.sections().

At the same time current Object/ELF.h code already has some code that has checks for amount of sections. And it do that on object loading. Code does not work well though, and I posted first patch for it: D25432. Though I am not sure that doing a check during loading is the best way.

Lets put this on hold until some changes in ELF.h be landed.

grimar abandoned this revision.Dec 2 2016, 11:47 PM

Depricated.