From f70e99cb2d7040869e4fa24b80916af34a4890bb Mon Sep 17 00:00:00 2001 From: Wessel Nieboer Date: Wed, 11 Feb 2026 03:30:02 +0100 Subject: [PATCH] fix out-of-bounds read in TRACE packet hash matching The TRACE handler uses isHashMatch() to compare this node's hash against an entry in the payload, but did not verify that enough bytes remain in the payload for the full hash comparison. The hash size is variable (1, 2, 4, or 8 bytes depending on path_sz), so when offset is close to the end of the payload, isHashMatch reads past the buffer boundary. Add a bounds check ensuring offset + hash_sz <= len before calling isHashMatch, preventing the over-read. --- src/Mesh.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Mesh.cpp b/src/Mesh.cpp index c11f37cacf..c1a48c4081 100644 --- a/src/Mesh.cpp +++ b/src/Mesh.cpp @@ -53,9 +53,10 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) { // path_len*entry_size can exceed 255 (path_len up to 63, entry_size up to 8); // a uint8_t offset would wrap and steer the isHashMatch() read to the wrong place. uint16_t offset = (uint16_t)pkt->path_len << path_sz; + uint8_t hash_sz = 1 << path_sz; if (offset >= len) { // TRACE has reached end of given path onTraceRecv(pkt, trace_tag, auth_code, flags, pkt->path, &pkt->payload[i], len); - } else if (self_id.isHashMatch(&pkt->payload[i + offset], 1 << path_sz) && allowPacketForward(pkt) && !_tables->wasSeen(pkt)) { + } else if (offset + hash_sz <= len && self_id.isHashMatch(&pkt->payload[i + offset], hash_sz) && allowPacketForward(pkt) && !_tables->wasSeen(pkt)) { _tables->markSeen(pkt); // append SNR (Not hash!) pkt->path[pkt->path_len++] = (int8_t) (pkt->getSNR()*4);