Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions roottest/root/tree/basket/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,11 @@ ROOTTEST_ADD_TEST(basket
MACRO rundropbasket.C
COPY_TO_BUILDDIR DataTest3_cel.root
OUTREF dropbasket.ref)

# corrupted.root contains a TTree "tree" with a corrupted TBasket that has fNevBufSize == 4 and fNevBuf == 4210752.
# Since fNevBuf is much larger than fNevBufSize this would cause oob reads unless TBasket properly validates this.
# Verify that it does.
ROOTTEST_ADD_TEST(corrupted_basket
COPY_TO_BUILDDIR corrupted.root
COMMAND ${ROOT_root_CMD} -q -l -e "(new TFile(\"corrupted.root\"))->template Get<TTree>(\"tree\")->GetEntry(0)"
PASSREGEX "Inconsistent length of the entry buffer. Refusing to deserialize.")
Binary file added roottest/root/tree/basket/corrupted.root
Binary file not shown.
24 changes: 21 additions & 3 deletions tree/tree/src/TBasket.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1005,16 +1005,34 @@ void TBasket::Streamer(TBuffer &b)
flag -= 80;
}
if (!mustGenerateOffsets && flag && (flag % 10 != 2)) {
if (fNevBuf > fNevBufSize) {
Error(
"Streamer",
"Inconsistent length of the entry buffer (%d events for a buffer size of %d). Refusing to deserialize.",
fNevBuf, fNevBufSize);
MakeZombie();
return;
}
ResetEntryOffset();
fEntryOffset = new Int_t[fNevBufSize];
if (fNevBuf) b.ReadArray(fEntryOffset);
if (fNevBuf) {
// Alas, ReadArray will read the number of elements to store into fEntryOffset from the file, but it
// has no way of knowing whether we're passing a large-enough array.
// Therefore we prevent the problem altogether by ignoring fNevBufSize and just having ReadArray allocate
// the buffer for us. This way we are sure that it will be of the correct size even if the file contains
// corrupted data.
fEntryOffset = nullptr;
b.ReadArray(fEntryOffset);
} else {
fEntryOffset = new Int_t[fNevBufSize];
}
if (20<flag && flag<40) {
for(int i=0; i<fNevBuf; i++){
fEntryOffset[i] &= ~kDisplacementMask;
}
}
if (flag>40) {
fDisplacement = new Int_t[fNevBufSize];
// ReadArray will allocate this for us.
fDisplacement = nullptr;
b.ReadArray(fDisplacement);
}
} else if (mustGenerateOffsets) {
Expand Down
7 changes: 7 additions & 0 deletions tree/tree/src/TBranch.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -3136,6 +3136,13 @@ void TBranch::Streamer(TBuffer& b)
}
fBasketEntry = new Long64_t[fMaxBaskets];
b >> n;
if (n > fMaxBaskets) {
Error("Streamer",
"Inconsistent number of baskets: refusing to deserialize. Read %d for an expected maximum of %d.", n,
fMaxBaskets);
MakeZombie();
return;
}
for (i=0;i<n;i++) {b >> ijunk; fBasketEntry[i] = ijunk;}
fBasketBytes = new Int_t[fMaxBaskets];
if (v > 4) {
Expand Down
Loading