[PATCH] D126898: [COFF] Check table ptr more thoroughly and ignore empty sections
Martin Storsjö via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 8 05:35:07 PDT 2022
mstorsjo added a comment.
In D126898#3566111 <https://reviews.llvm.org/D126898#3566111>, @glandium wrote:
> In D126898#3565873 <https://reviews.llvm.org/D126898#3565873>, @mstorsjo wrote:
>
>> Can you upload that binary somewhere?
>
> This is not the exact binary this happened with, but it's reproducible with this one:
>
> - download https://firefox-ci-tc.services.mozilla.com/api/queue/v1/task/CVYLgJ7JTzKIZqeMnxZaXA/runs/0/artifacts/public/build/target.zip
> - unzip `firefox/uninstall/helper.exe` from that zip
> - run `llvm-strip` on it.
Thanks! I can see what's happening here. Unfortunately, it seems like that binary is somewhat broken, and libObject used to accept it silently before.
Looking at the binary with `llvm-readobj --sections --file-headers`, I see this:
BaseRelocationTableRVA: 0x43000
BaseRelocationTableSize: 0xB68
Section {
Number: 4
Name: .ndata (2E 6E 64 61 74 61 00 00)
VirtualSize: 0x1C000
VirtualAddress: 0x40000
RawDataSize: 512
Section {
Number: 6
Name: .reloc (2E 72 65 6C 6F 63 00 00)
VirtualSize: 0xB68
VirtualAddress: 0x64000
RawDataSize: 3072
The base relocation table usually resides in the `.reloc` section, and as the exact size (`0xB68`) matches, it looks like it just has got the wrong RVA in the header. With the new, more thorough checks, libObject notices that the RVA points into the `.ndata` section (within `0x40000 - 0x5C000`) but there's only raw data covering `0x40000 - 0x40200`, and `0x43000` is outside of that. Previously we'd just set up a pointer into bogus/out of range data in these cases, now we error out.
So the file is clearly buggy here, but it could, in some cases, be quite valid to have RVAs pointing outside of the allocated raw data. (Normally, the data size outside of `RawDataSize` up until `VirtualSize` is allocated and readable at runtime, but zero-initialized instead of initialized with data from the file.)
In this case, the check was added to avoid crashes, and for the specific case of `SizeOfRawData == 0` we return `SectionStrippedError`, which then is silently treated as not an error (but not initializing e.g. the `BaseRelocHeader` pointer, to avoid trying to read from it).
To avoid crashing from RVAs outside of the allocated bounds, but still not flat out erroring out on binaries that are somewhat broken (the same issue causes llvm-readobj to reject the binary, so I had to use an older llvm-readobj binary to look at it), should we just treat all those cases as a silent "section stripped" case?
E.g. this fixes the issue:
diff --git a/llvm/lib/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp
index 65166b3710a0..f7d957ee2682 100644
--- a/llvm/lib/Object/COFFObjectFile.cpp
+++ b/llvm/lib/Object/COFFObjectFile.cpp
@@ -483,18 +483,12 @@ Error COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res,
// fail, otherwise it will be impossible to use this object as debug info
// in LLDB. Return SectionStrippedError here so that
// COFFObjectFile::initialize can ignore the error.
- if (Section->SizeOfRawData == 0)
- return make_error<SectionStrippedError>();
+ // Somewhat common binaries may have RVAs pointing outside of the
+ // provided raw data. Instead of rejecting the binaries, just
+ // treat the section as stripped for these purposes.
if (Section->SizeOfRawData < Section->VirtualSize &&
Addr >= SectionStart + Section->SizeOfRawData) {
- if (ErrorContext)
- return createStringError(object_error::parse_failed,
- "RVA 0x%" PRIx32
- " for %s found but data is incomplete",
- Addr, ErrorContext);
- return createStringError(
- object_error::parse_failed,
- "RVA 0x%" PRIx32 " found but data is incomplete", Addr);
+ return make_error<SectionStrippedError>();
}
uint32_t Offset = Addr - SectionStart;
Res = reinterpret_cast<uintptr_t>(base()) + Section->PointerToRawData +
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D126898/new/
https://reviews.llvm.org/D126898
More information about the llvm-commits
mailing list