Skip to content

Commit 1afd314

Browse files
[CAS] Add some error handing in Trie traversal
Add some error handling in `TrieVisitor` to identify issues in the on disk trie and prevent debugging tool crashes on invalid inputs. rdar://138026973 (cherry picked from commit b829f49)
1 parent 519ea5a commit 1afd314

File tree

1 file changed

+14
-0
lines changed

1 file changed

+14
-0
lines changed

llvm/lib/CAS/OnDiskHashMappedTrie.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "llvm/CAS/OnDiskHashMappedTrie.h"
1010
#include "HashMappedTrieIndexGenerator.h"
1111
#include "llvm/ADT/ScopeExit.h"
12+
#include "llvm/ADT/StringExtras.h"
1213
#include "llvm/ADT/StringMap.h"
1314
#include "llvm/CAS/MappedFileRegionBumpPtr.h"
1415
#include "llvm/Support/Compiler.h"
@@ -1168,6 +1169,11 @@ class TriePrinter : public TrieVisitor {
11681169
};
11691170
} // namespace
11701171

1172+
static Error createInvalidTrieError(uint64_t Offset, const Twine &Msg) {
1173+
return createStringError(make_error_code(std::errc::protocol_error),
1174+
"invalid trie at 0x" + toHex(Offset) + ": " + Msg);
1175+
}
1176+
11711177
Error TrieVisitor::visit(HashMappedTrieHandle Trie) {
11721178
auto Root = Trie.getRoot();
11731179
if (!Root)
@@ -1179,6 +1185,11 @@ Error TrieVisitor::visit(HashMappedTrieHandle Trie) {
11791185
}
11801186

11811187
Error TrieVisitor::traverseTrieNode(SubtrieHandle Node, StringRef Prefix) {
1188+
char *Addr = reinterpret_cast<char *>(&Node.getHeader());
1189+
if (Addr + Node.getSize() >=
1190+
Trie.getRegion().data() + Trie.getRegion().size())
1191+
return createInvalidTrieError((uint64_t)Addr, "subtrie node out of bound");
1192+
11821193
if (auto Err = visitSubTrie(Prefix, Node))
11831194
return Err;
11841195

@@ -1189,6 +1200,9 @@ Error TrieVisitor::traverseTrieNode(SubtrieHandle Node, StringRef Prefix) {
11891200
SubtrieSlotValue Slot = Node.load(I);
11901201
if (!Slot)
11911202
continue;
1203+
uint64_t Offset = Slot.isSubtrie() ? Slot.asSubtrie() : Slot.asData();
1204+
if (Offset >= (uint64_t)Trie.getRegion().size())
1205+
return createInvalidTrieError(Offset, "slot points out of bound");
11921206
std::string SubtriePrefix = Prefix.str();
11931207
appendIndexBits(SubtriePrefix, I, NumSlots);
11941208
if (Slot.isSubtrie()) {

0 commit comments

Comments
 (0)