Skip to content

Commit d2cb030

Browse files
committed
[io] More checks to the buffer properties of TKey and TBuffer
thanks to @manop55555
1 parent dab4218 commit d2cb030

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 ROOT::Internal {
84+
int CheckKeyObjLenOverflow(const char *methodName, int keyLen, int 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 1;
91+
}
92+
return 0;
93+
}
94+
} // namespace ROOT::Internal
8395

8496
////////////////////////////////////////////////////////////////////////////////
8597
/// TKey default constructor.
@@ -1246,9 +1258,9 @@ void TKey::ReadKeyBuffer(char *&buffer)
12461258
return;
12471259
}
12481260

1249-
constexpr auto maxInt_t = std::numeric_limits<Int_t>::max();
1250-
if (fKeylen > (maxInt_t - fObjlen)) {
1251-
Error("ReadKeyBuffer", "fObjlen (%d) + fKeylen (%d) > max int (%d): cannot continue to read the key buffer.", fObjlen, fKeylen, maxInt_t);
1261+
if(0 != ROOT::Internal::CheckKeyObjLenOverflow("ReadKeyBuffer", fKeylen, fObjlen)){
1262+
fKeylen = 0;
1263+
fObjlen = 0;
12521264
MakeZombie();
12531265
return;
12541266
}
@@ -1424,6 +1436,10 @@ void TKey::Streamer(TBuffer &b)
14241436
MakeZombie();
14251437
fNbytes = 0;
14261438
}
1439+
if (0 != ROOT::Internal::CheckKeyObjLenOverflow("Streamer", fKeylen, fObjlen)) {
1440+
MakeZombie();
1441+
return;
1442+
}
14271443

14281444
} else {
14291445
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)