From fd0355e2a6cb619868cca3255bdb3f497c17b579 Mon Sep 17 00:00:00 2001 From: Wessel Nieboer Date: Wed, 11 Feb 2026 04:35:15 +0100 Subject: [PATCH] Check ACK payload_len before memcpy, not after Both ACK handlers (direct-route early ACK and flood ACK) copy 4 bytes from the payload before checking payload_len >= 4. Move the bounds check before the memcpy so short ACK packets are rejected without reading stale buffer data. --- src/Mesh.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/Mesh.cpp b/src/Mesh.cpp index 0548c9073..49db40331 100644 --- a/src/Mesh.cpp +++ b/src/Mesh.cpp @@ -79,13 +79,10 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) { if (pkt->isRouteDirect() && pkt->path_len >= PATH_HASH_SIZE) { // check for 'early received' ACK - if (pkt->getPayloadType() == PAYLOAD_TYPE_ACK) { - int i = 0; + if (pkt->getPayloadType() == PAYLOAD_TYPE_ACK && pkt->payload_len >= 4) { uint32_t ack_crc; - memcpy(&ack_crc, &pkt->payload[i], 4); i += 4; - if (i <= pkt->payload_len) { - onAckRecv(pkt, ack_crc); - } + memcpy(&ack_crc, pkt->payload, 4); + onAckRecv(pkt, ack_crc); } if (self_id.isHashMatch(pkt->path) && allowPacketForward(pkt)) { @@ -115,12 +112,13 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) { switch (pkt->getPayloadType()) { case PAYLOAD_TYPE_ACK: { - int i = 0; - uint32_t ack_crc; - memcpy(&ack_crc, &pkt->payload[i], 4); i += 4; - if (i > pkt->payload_len) { + if (pkt->payload_len < 4) { MESH_DEBUG_PRINTLN("%s Mesh::onRecvPacket(): incomplete ACK packet", getLogDateTime()); - } else if (!_tables->hasSeen(pkt)) { + break; + } + uint32_t ack_crc; + memcpy(&ack_crc, pkt->payload, 4); + if (!_tables->hasSeen(pkt)) { onAckRecv(pkt, ack_crc); action = routeRecvPacket(pkt); }