Skip to content

Commit e5794ae

Browse files
committed
Create out of bounds check for first element of iterator, allowing normal iterator behavior, and fixes filecheck
1 parent 123f6ed commit e5794ae

File tree

3 files changed

+26
-18
lines changed

3 files changed

+26
-18
lines changed

llvm/include/llvm/Object/Minidump.h

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,8 @@ class MinidumpFile : public Binary {
140140
size_t Stride;
141141
};
142142

143-
144-
/// Class the provides an iterator over the memory64 memory ranges. Ranges
145-
/// are not validated before hand, and so any increment operation could fail.
146-
/// For this reason, the iterator in it's initial state points to a default
147-
/// initialized std::pair and should be advanced before dereferencing.
143+
/// Class the provides an iterator over the memory64 memory ranges. Only the
144+
/// the first descriptor is validated as readable beforehand.
148145
class Memory64Iterator {
149146
public:
150147
static Memory64Iterator
@@ -159,18 +156,18 @@ class MinidumpFile : public Binary {
159156
std::pair<minidump::MemoryDescriptor_64, ArrayRef<uint8_t>> Current;
160157

161158
bool operator==(const Memory64Iterator &R) const {
162-
return isEnd == R.isEnd;
159+
return IsEnd == R.IsEnd;
163160
}
164161

165162
bool operator!=(const Memory64Iterator &R) const { return !(*this == R); }
166163

167164
const std::pair<minidump::MemoryDescriptor_64, ArrayRef<uint8_t>> &
168-
operator*() const {
165+
operator*() {
169166
return Current;
170167
}
171168

172169
const std::pair<minidump::MemoryDescriptor_64, ArrayRef<uint8_t>> *
173-
operator->() const {
170+
operator&() {
174171
return &Current;
175172
}
176173

@@ -190,29 +187,37 @@ class MinidumpFile : public Binary {
190187

191188
ArrayRef<uint8_t> Content = Storage.slice(RVA, Descriptor.DataSize);
192189
Current = std::make_pair(Descriptor, Content);
193-
RVA += Descriptor.DataSize;
194190
Index++;
191+
RVA += Descriptor.DataSize;
195192
if (Index >= Descriptors.size())
196-
isEnd = true;
193+
IsEnd = true;
197194
return Error::success();
198195
}
199196

200197
private:
198+
// This constructor will only happen after a validation check to see
199+
// if the first descriptor is readable.
201200
Memory64Iterator(ArrayRef<uint8_t> Storage,
202201
ArrayRef<minidump::MemoryDescriptor_64> Descriptors,
203202
uint64_t BaseRVA)
204203
: RVA(BaseRVA), Storage(Storage), Descriptors(Descriptors),
205-
isEnd(false) {}
204+
IsEnd(false) {
205+
assert(Descriptors.size() > 0);
206+
assert(Storage.size() >= BaseRVA + Descriptors.front().DataSize);
207+
Current =
208+
std::make_pair(Descriptors.front(),
209+
Storage.slice(BaseRVA, Descriptors.front().DataSize));
210+
}
206211

207212
Memory64Iterator()
208213
: RVA(0), Storage(ArrayRef<uint8_t>()),
209-
Descriptors(ArrayRef<minidump::MemoryDescriptor_64>()), isEnd(true) {}
214+
Descriptors(ArrayRef<minidump::MemoryDescriptor_64>()), IsEnd(true) {}
210215

211216
size_t Index = 0;
212217
uint64_t RVA;
213218
ArrayRef<uint8_t> Storage;
214219
ArrayRef<minidump::MemoryDescriptor_64> Descriptors;
215-
bool isEnd;
220+
bool IsEnd;
216221
};
217222

218223
using FallibleMemory64Iterator = llvm::fallible_iterator<Memory64Iterator>;

llvm/lib/Object/Minidump.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,10 @@ MinidumpFile::getMemory64List(Error &Err) const {
175175
if (!Descriptors)
176176
return Descriptors.takeError();
177177

178+
if (!Descriptors->empty() &&
179+
ListHeader->BaseRVA + Descriptors->front().DataSize > getData().size())
180+
return createEOFError();
181+
178182
return make_range(
179183
FallibleMemory64Iterator::itr(
180184
Memory64Iterator::begin(getData(), *Descriptors, ListHeader->BaseRVA),

llvm/lib/ObjectYAML/MinidumpYAML.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -539,13 +539,12 @@ Stream::create(const Directory &StreamDesc, const object::MinidumpFile &File) {
539539
if (!ExpectedList)
540540
return ExpectedList.takeError();
541541
std::vector<Memory64ListStream::entry_type> Ranges;
542-
for (auto It = ExpectedList->begin(); It != ExpectedList->end();) {
543-
// Explicilty advance the iterator before dereference.
544-
++It;
542+
for (auto It = ExpectedList->begin(); It != ExpectedList->end(); ++It) {
545543
const auto Pair = *It;
546-
if (!Err) {
544+
if (!Err)
547545
Ranges.push_back({Pair.first, Pair.second});
548-
}
546+
else
547+
break;
549548
}
550549

551550
// If we don't have an error, or if any of the reads succeed, return ranges

0 commit comments

Comments
 (0)