Skip to content

Commit b5068d3

Browse files
committed
[io] More checks to the buffer properties of TKey and TBuffer
thanks to @manop55555 (cherry picked from commit 7a1aedd)
1 parent 189ef42 commit b5068d3

2 files changed

Lines changed: 46 additions & 3 deletions

File tree

io/io/src/TKey.cxx

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,18 @@ const UChar_t kPidOffsetShift = 48;
8080
const static TString gTDirectoryString("TDirectory");
8181
std::atomic<UInt_t> keyAbsNumber{0};
8282

83+
namespace {
84+
bool CheckKeyObjLenOverflow(const char *methodName, Int_t keyLen, Int_t objLen)
85+
{
86+
constexpr auto maxInt_t = std::numeric_limits<Int_t>::max();
87+
if (keyLen > (maxInt_t - objLen)) {
88+
Error(methodName, "fObjlen (%d) + fKeylen (%d) > max int (%d): cannot continue to read the key buffer.", objLen,
89+
keyLen, maxInt_t);
90+
return true;
91+
}
92+
return false;
93+
}
94+
} // namespace
8395

8496
////////////////////////////////////////////////////////////////////////////////
8597
/// TKey default constructor.
@@ -1266,9 +1278,9 @@ void TKey::ReadKeyBuffer(char *&buffer)
12661278
return;
12671279
}
12681280

1269-
constexpr auto maxInt_t = std::numeric_limits<Int_t>::max();
1270-
if (fKeylen > (maxInt_t - fObjlen)) {
1271-
Error("ReadKeyBuffer", "fObjlen (%d) + fKeylen (%d) > max int (%d): cannot continue to read the key buffer.", fObjlen, fKeylen, maxInt_t);
1281+
if(CheckKeyObjLenOverflow("ReadKeyBuffer", fKeylen, fObjlen)){
1282+
fKeylen = 0;
1283+
fObjlen = 0;
12721284
MakeZombie();
12731285
return;
12741286
}
@@ -1444,6 +1456,10 @@ void TKey::Streamer(TBuffer &b)
14441456
MakeZombie();
14451457
fNbytes = 0;
14461458
}
1459+
if (CheckKeyObjLenOverflow("Streamer", fKeylen, fObjlen)) {
1460+
MakeZombie();
1461+
return;
1462+
}
14471463

14481464
} else {
14491465
b << fNbytes;

tree/tree/src/TBasket.cxx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
*************************************************************************/
1010

1111
#include <chrono>
12+
#include <limits>
1213

1314
#include "TBasket.h"
1415
#include "TBuffer.h"
@@ -31,6 +32,7 @@
3132
const UInt_t kDisplacementMask = 0xFF000000; // In the streamer the two highest bytes of
3233
// the fEntryOffset are used to stored displacement.
3334

35+
constexpr auto gMaxInt_t = std::numeric_limits<Int_t>::max();
3436

3537
/** \class TBasket
3638
\ingroup tree
@@ -575,6 +577,31 @@ Int_t TBasket::ReadBasketBuffers(Long64_t pos, Int_t len, TFile *file)
575577
memcpy(rawCompressedBuffer, fBufferRef->Buffer(), len);
576578
}
577579
}
580+
// Sanitize nbytes and lengths
581+
if (fKeylen < 0) {
582+
Error("ReadBasketBuffers", "The value of fKeylen is incorrect (%d) ; trying to recover by setting it to zero", fKeylen);
583+
MakeZombie();
584+
fKeylen = 0;
585+
return 1;
586+
}
587+
if (fObjlen < 0) {
588+
Error("ReadBasketBuffers", "The value of fObjlen is incorrect (%d) ; trying to recover by setting it to zero", fObjlen);
589+
MakeZombie();
590+
fObjlen = 0;
591+
return 1;
592+
}
593+
if (fNbytes < 0) {
594+
Error("ReadBasketBuffers", "The value of fNbytes is incorrect (%d) ; trying to recover by setting it to zero", fNbytes);
595+
MakeZombie();
596+
fNbytes = 0;
597+
return 1;
598+
}
599+
if (fKeylen > (gMaxInt_t - fObjlen)) {
600+
Error("ReadBasketBuffers", "fObjlen (%d) + fKeylen (%d) > max int (%d): cannot continue to read the key buffer.",
601+
fObjlen, fKeylen, gMaxInt_t);
602+
MakeZombie();
603+
return 1;
604+
}
578605

579606
// Initialize buffer to hold the uncompressed data
580607
// Note that in previous versions we didn't allocate buffers until we verified

0 commit comments

Comments
 (0)