Skip to content

Commit 4ae839e

Browse files
committed
validate advert payload length before parsing
The ADVERT handler copied pub_key, timestamp, and signature from the payload before checking whether payload_len was large enough to contain them. With a short payload, the memcpy operations read uninitialized data from within the payload buffer. Move the bounds check before any parsing so undersized adverts are rejected immediately. The minimum required is PUB_KEY_SIZE + 4 + SIGNATURE_SIZE (100 bytes).
1 parent 06ab9f7 commit 4ae839e

1 file changed

Lines changed: 7 additions & 3 deletions

File tree

src/Mesh.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,16 +238,20 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
238238
}
239239
case PAYLOAD_TYPE_ADVERT: {
240240
int i = 0;
241+
int min_advert_len = PUB_KEY_SIZE + 4 + SIGNATURE_SIZE;
242+
if (pkt->payload_len < min_advert_len) {
243+
MESH_DEBUG_PRINTLN("%s Mesh::onRecvPacket(): incomplete advertisement packet, payload_len=%d", getLogDateTime(), (int)pkt->payload_len);
244+
break;
245+
}
246+
241247
Identity id;
242248
memcpy(id.pub_key, &pkt->payload[i], PUB_KEY_SIZE); i += PUB_KEY_SIZE;
243249

244250
uint32_t timestamp;
245251
memcpy(&timestamp, &pkt->payload[i], 4); i += 4;
246252
const uint8_t* signature = &pkt->payload[i]; i += SIGNATURE_SIZE;
247253

248-
if (i > pkt->payload_len) {
249-
MESH_DEBUG_PRINTLN("%s Mesh::onRecvPacket(): incomplete advertisement packet", getLogDateTime());
250-
} else if (self_id.matches(id.pub_key)) {
254+
if (self_id.matches(id.pub_key)) {
251255
MESH_DEBUG_PRINTLN("%s Mesh::onRecvPacket(): receiving SELF advert packet", getLogDateTime());
252256
} else if (!_tables->hasSeen(pkt)) {
253257
uint8_t* app_data = &pkt->payload[i];

0 commit comments

Comments
 (0)