Skip to content

Commit 1aba873

Browse files
authored
enhance cppclient tsblock deserialize validation (#17464)
* fix tsblock deserialize * fix ut error on win * Revert "fix ut error on win" This reverts commit 34b8de4.
1 parent a6006f3 commit 1aba873

4 files changed

Lines changed: 40 additions & 2 deletions

File tree

iotdb-client/client-cpp/src/main/ColumnDecoder.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@ std::unique_ptr<Column> BinaryArrayColumnDecoder::readColumn(
151151
if (!nullIndicators.empty() && nullIndicators[i]) continue;
152152

153153
int32_t length = buffer.getInt();
154+
if (length < 0) {
155+
throw IoTDBException("BinaryArrayColumnDecoder: negative TEXT length");
156+
}
154157

155158
std::vector<uint8_t> value(length);
156159
for (int32_t j = 0; j < length; j++) {

iotdb-client/client-cpp/src/main/Common.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,10 @@ double MyStringBuffer::getDouble() {
293293
}
294294

295295
char MyStringBuffer::getChar() {
296+
if (pos >= str.size()) {
297+
throw IoTDBException("MyStringBuffer::getChar: read past end (pos=" + std::to_string(pos) +
298+
", size=" + std::to_string(str.size()) + ")");
299+
}
296300
return str[pos++];
297301
}
298302

@@ -301,8 +305,16 @@ bool MyStringBuffer::getBool() {
301305
}
302306

303307
std::string MyStringBuffer::getString() {
304-
size_t len = getInt();
305-
size_t tmpPos = pos;
308+
const int lenInt = getInt();
309+
if (lenInt < 0) {
310+
throw IoTDBException("MyStringBuffer::getString: negative length");
311+
}
312+
const size_t len = static_cast<size_t>(lenInt);
313+
if (pos > str.size() || len > str.size() - pos) {
314+
throw IoTDBException("MyStringBuffer::getString: length exceeds buffer (pos=" + std::to_string(pos) +
315+
", len=" + std::to_string(len) + ", size=" + std::to_string(str.size()) + ")");
316+
}
317+
const size_t tmpPos = pos;
306318
pos += len;
307319
return str.substr(tmpPos, len);
308320
}
@@ -351,6 +363,10 @@ void MyStringBuffer::checkBigEndian() {
351363
}
352364

353365
const char* MyStringBuffer::getOrderedByte(size_t len) {
366+
if (pos > str.size() || len > str.size() - pos) {
367+
throw IoTDBException("MyStringBuffer::getOrderedByte: read past end (pos=" + std::to_string(pos) +
368+
", len=" + std::to_string(len) + ", size=" + std::to_string(str.size()) + ")");
369+
}
354370
const char* p = nullptr;
355371
if (isBigEndian) {
356372
p = str.c_str() + pos;

iotdb-client/client-cpp/src/main/TsBlock.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
* specific language governing permissions and limitations
1717
* under the License.
1818
*/
19+
#include <cstdint>
1920
#include <stdexcept>
2021
#include <algorithm>
2122
#include "TsBlock.h"
@@ -34,6 +35,14 @@ std::shared_ptr<TsBlock> TsBlock::deserialize(const std::string& data) {
3435

3536
// Read value column count
3637
int32_t valueColumnCount = buffer.getInt();
38+
if (valueColumnCount < 0) {
39+
throw IoTDBException("TsBlock::deserialize: negative valueColumnCount");
40+
}
41+
const int64_t minHeaderBytes =
42+
9LL + 2LL * static_cast<int64_t>(valueColumnCount);
43+
if (minHeaderBytes > static_cast<int64_t>(data.size())) {
44+
throw IoTDBException("TsBlock::deserialize: truncated header");
45+
}
3746

3847
// Read value column data types
3948
std::vector<TSDataType::TSDataType> valueColumnDataTypes(valueColumnCount);
@@ -43,6 +52,9 @@ std::shared_ptr<TsBlock> TsBlock::deserialize(const std::string& data) {
4352

4453
// Read position count
4554
int32_t positionCount = buffer.getInt();
55+
if (positionCount < 0) {
56+
throw IoTDBException("TsBlock::deserialize: negative positionCount");
57+
}
4658

4759
// Read column encodings
4860
std::vector<ColumnEncoding> columnEncodings(valueColumnCount + 1);

iotdb-client/client-cpp/src/test/cpp/sessionIT.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "catch.hpp"
2121
#include "Session.h"
2222
#include "SessionBuilder.h"
23+
#include "TsBlock.h"
2324

2425
using namespace std;
2526

@@ -858,4 +859,10 @@ TEST_CASE("UrlUtils - parseTEndPointIpv4AndIpv6Url", "[UrlUtils]") {
858859
REQUIRE_TENDPOINT(UrlUtils::parseTEndPointIpv4AndIpv6Url("localhost:0"), "localhost", 0);
859860
REQUIRE_TENDPOINT(UrlUtils::parseTEndPointIpv4AndIpv6Url("127.0.0.1:65535"), "127.0.0.1", 65535);
860861
}
862+
}
863+
864+
TEST_CASE("TsBlock deserialize rejects truncated malicious payload", "[TsBlockDeserialize]") {
865+
std::string data(18, '\0');
866+
data[3] = '\x10';
867+
REQUIRE_THROWS_AS(TsBlock::deserialize(data), IoTDBException);
861868
}

0 commit comments

Comments
 (0)