From 0a083834711135afb13e7798d8662a21b2490d09 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 10 Nov 2024 09:15:23 -0500 Subject: [PATCH] check msg size in HandleTunnelBuildResponse --- libi2pd/Tunnel.cpp | 37 ++++++++++++++++--------------------- libi2pd/TunnelConfig.h | 4 +++- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 4ce8f526..54e276ad 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -130,8 +130,19 @@ namespace tunnel bool Tunnel::HandleTunnelBuildResponse (uint8_t * msg, size_t len) { - LogPrint (eLogDebug, "Tunnel: TunnelBuildResponse ", (int)msg[0], " records."); - + int num = msg[0]; + LogPrint (eLogDebug, "Tunnel: TunnelBuildResponse ", num, " records."); + if (num > MAX_NUM_RECORDS) + { + LogPrint (eLogError, "Tunnel: Too many records in TunnelBuildResponse", num); + return false; + } + if (len < num*m_Config->GetRecordSize () + 1) + { + LogPrint (eLogError, "Tunnel: TunnelBuildResponse of ", num, " records is too short ", len); + return false; + } + TunnelHopConfig * hop = m_Config->GetLastHop (); while (hop) { @@ -152,7 +163,7 @@ namespace tunnel while (hop1) { auto idx = hop1->recordIndex; - if (idx >= 0 && idx < msg[0]) + if (idx >= 0 && idx < num) hop->DecryptRecord (msg + 1, idx); else LogPrint (eLogWarning, "Tunnel: Hop index ", idx, " is out of range"); @@ -671,28 +682,12 @@ namespace tunnel void Tunnels::HandleTunnelBuildReplyMsg (std::shared_ptr msg, bool isShort) { - if (!msg) return; - uint8_t * buf = msg->GetPayload(); - size_t len = msg->GetPayloadLength(); - int num = buf[0]; - LogPrint (eLogDebug, "Tunnel: TunnelBuildReplyMsg of ", num, " records replyMsgID=", msg->GetMsgID()); - if (num > i2p::tunnel::MAX_NUM_RECORDS) - { - LogPrint (eLogError, "Tunnel: Too many records in TunnelBuildReply message ", num); - return; - } - size_t recordSize = isShort ? SHORT_TUNNEL_BUILD_RECORD_SIZE : TUNNEL_BUILD_RECORD_SIZE; - if (len < num*recordSize + 1) - { - LogPrint (eLogError, "Tunnel: TunnelBuildReply message of ", num, " records is too short ", len); - return; - } - auto tunnel = GetPendingOutboundTunnel (msg->GetMsgID()); // replyMsgID if (tunnel) { // reply for outbound tunnel - if (tunnel->HandleTunnelBuildResponse (buf, len)) + LogPrint (eLogDebug, "Tunnel: TunnelBuildReply for tunnel ", tunnel->GetTunnelID ()); + if (tunnel->HandleTunnelBuildResponse (msg->GetPayload(), msg->GetPayloadLength())) { LogPrint (eLogInfo, "Tunnel: Outbound tunnel ", tunnel->GetTunnelID (), " has been created"); tunnel->SetState (eTunnelStateEstablished); diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 9dcf2c02..718a6fdb 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2021, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -181,6 +181,8 @@ namespace tunnel return peers; } + size_t GetRecordSize () const { return m_IsShort ? SHORT_TUNNEL_BUILD_RECORD_SIZE : TUNNEL_BUILD_RECORD_SIZE; }; + protected: // this constructor can't be called from outside