From ff48422ec03d953269cde88b8e60388f8f5d59ea Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 5 Jan 2016 14:29:18 -0500 Subject: [PATCH] check I2NP message buffer size --- I2NPProtocol.cpp | 29 ++++++++++++----------------- I2NPProtocol.h | 13 +++++++++++-- SSUData.cpp | 4 ++-- TunnelEndpoint.cpp | 8 ++++---- 4 files changed, 29 insertions(+), 25 deletions(-) diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index 698475fe..16d5e245 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -51,21 +51,16 @@ namespace i2p SetExpiration (i2p::util::GetMillisecondsSinceEpoch () + 5000); } - std::shared_ptr CreateI2NPMessage (I2NPMessageType msgType, const uint8_t * buf, int len, uint32_t replyMsgID) + std::shared_ptr CreateI2NPMessage (I2NPMessageType msgType, const uint8_t * buf, size_t len, uint32_t replyMsgID) { auto msg = NewI2NPMessage (len); - if (msg->len + len < msg->maxLen) - { - memcpy (msg->GetPayload (), buf, len); - msg->len += len; - } - else - LogPrint (eLogError, "I2NP: message length ", len, " exceeds max length"); + if (msg->Concat (buf, len) < len) + LogPrint (eLogError, "I2NP: message length ", len, " exceeds max length ", msg->maxLen); msg->FillI2NPMessageHeader (msgType, replyMsgID); return msg; } - std::shared_ptr CreateI2NPMessage (const uint8_t * buf, int len, std::shared_ptr from) + std::shared_ptr CreateI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr from) { auto msg = NewI2NPMessage (); if (msg->offset + len < msg->maxLen) @@ -413,8 +408,7 @@ namespace i2p std::shared_ptr CreateTunnelDataMsg (const uint8_t * buf) { auto msg = NewI2NPShortMessage (); - memcpy (msg->GetPayload (), buf, i2p::tunnel::TUNNEL_DATA_MSG_SIZE); - msg->len += i2p::tunnel::TUNNEL_DATA_MSG_SIZE; + msg->Concat (buf, i2p::tunnel::TUNNEL_DATA_MSG_SIZE); msg->FillI2NPMessageHeader (eI2NPTunnelData); return msg; } @@ -422,9 +416,9 @@ namespace i2p std::shared_ptr CreateTunnelDataMsg (uint32_t tunnelID, const uint8_t * payload) { auto msg = NewI2NPShortMessage (); - memcpy (msg->GetPayload () + 4, payload, i2p::tunnel::TUNNEL_DATA_MSG_SIZE - 4); htobe32buf (msg->GetPayload (), tunnelID); - msg->len += i2p::tunnel::TUNNEL_DATA_MSG_SIZE; + msg->len += 4; // tunnelID + msg->Concat (payload, i2p::tunnel::TUNNEL_DATA_MSG_SIZE - 4); msg->FillI2NPMessageHeader (eI2NPTunnelData); return msg; } @@ -442,8 +436,9 @@ namespace i2p uint8_t * payload = msg->GetPayload (); htobe32buf (payload + TUNNEL_GATEWAY_HEADER_TUNNELID_OFFSET, tunnelID); htobe16buf (payload + TUNNEL_GATEWAY_HEADER_LENGTH_OFFSET, len); - memcpy (payload + TUNNEL_GATEWAY_HEADER_SIZE, buf, len); - msg->len += TUNNEL_GATEWAY_HEADER_SIZE + len; + msg->len += TUNNEL_GATEWAY_HEADER_SIZE; + if (msg->Concat (buf, len) < len) + LogPrint (eLogError, "I2NP: tunnel gateway buffer overflow ", msg->maxLen); msg->FillI2NPMessageHeader (eI2NPTunnelGateway); return msg; } @@ -473,8 +468,8 @@ namespace i2p size_t gatewayMsgOffset = I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE; msg->offset += gatewayMsgOffset; msg->len += gatewayMsgOffset; - memcpy (msg->GetPayload (), buf, len); - msg->len += len; + if (msg->Concat (buf, len) < len) + LogPrint (eLogError, "I2NP: tunnel gateway buffer overflow ", msg->maxLen); msg->FillI2NPMessageHeader (msgType, replyMsgID); // create content message len = msg->GetLength (); msg->offset -= gatewayMsgOffset; diff --git a/I2NPProtocol.h b/I2NPProtocol.h index e6f20558..9c41a06b 100644 --- a/I2NPProtocol.h +++ b/I2NPProtocol.h @@ -155,6 +155,15 @@ namespace tunnel } } + size_t Concat (const uint8_t * buf1, size_t len1) + { + // make sure with don't write beyond maxLen + if (len + len1 > maxLen) len1 = maxLen - len; + memcpy (buf + len, buf1, len1); + len += len1; + return len1; + } + I2NPMessage& operator=(const I2NPMessage& other) { memcpy (buf + offset, other.buf + other.offset, other.GetLength ()); @@ -200,8 +209,8 @@ namespace tunnel std::shared_ptr NewI2NPShortMessage (); std::shared_ptr NewI2NPMessage (size_t len); - std::shared_ptr CreateI2NPMessage (I2NPMessageType msgType, const uint8_t * buf, int len, uint32_t replyMsgID = 0); - std::shared_ptr CreateI2NPMessage (const uint8_t * buf, int len, std::shared_ptr from = nullptr); + std::shared_ptr CreateI2NPMessage (I2NPMessageType msgType, const uint8_t * buf, size_t len, uint32_t replyMsgID = 0); + std::shared_ptr CreateI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr from = nullptr); std::shared_ptr CreateDeliveryStatusMsg (uint32_t msgID); std::shared_ptr CreateRouterInfoDatabaseLookupMsg (const uint8_t * key, const uint8_t * from, diff --git a/SSUData.cpp b/SSUData.cpp index 33c85d71..cb9d1015 100644 --- a/SSUData.cpp +++ b/SSUData.cpp @@ -19,8 +19,8 @@ namespace transport *newMsg = *msg; msg = newMsg; } - memcpy (msg->buf + msg->len, fragment, fragmentSize); - msg->len += fragmentSize; + if (msg->Concat (fragment, fragmentSize) < fragmentSize) + LogPrint (eLogError, "SSU: I2NP buffer overflow ", msg->maxLen); nextFragmentNum++; } diff --git a/TunnelEndpoint.cpp b/TunnelEndpoint.cpp index 271c115d..5225c8d8 100644 --- a/TunnelEndpoint.cpp +++ b/TunnelEndpoint.cpp @@ -152,8 +152,8 @@ namespace tunnel *newMsg = *(msg.data); msg.data = newMsg; } - memcpy (msg.data->buf + msg.data->len, fragment, size); // concatenate fragment - msg.data->len += size; + if (msg.data->Concat (fragment, size) < size) // concatenate fragment + LogPrint (eLogError, "Tunnel endpoint I2NP buffer overflow ", msg.data->maxLen); if (isLastFragment) { // message complete @@ -208,8 +208,8 @@ namespace tunnel *newMsg = *(msg.data); msg.data = newMsg; } - memcpy (msg.data->buf + msg.data->len, it->second.data->GetBuffer (), size); // concatenate out-of-sync fragment - msg.data->len += size; + if (msg.data->Concat (it->second.data->GetBuffer (), size) < size) // concatenate out-of-sync fragment + LogPrint (eLogError, "Tunnel endpoint I2NP buffer overflow ", msg.data->maxLen); if (it->second.isLastFragment) { // message complete