Skip to content

Commit 9430290

Browse files
committed
fix out_frame buffer overflow in companion radio response handlers
The onContactResponse handler copies peer response data into out_frame (MAX_FRAME_SIZE + 1 bytes) without checking whether the data fits. A peer response with len close to MAX_PACKET_PAYLOAD (184) writes up to 188 bytes into the 173-byte buffer, overflowing by 15 bytes. This affects the status response, telemetry response, and binary response code paths. A malicious peer can trigger the overflow by sending a large response payload, corrupting the stack. Cap each memcpy to the remaining space in out_frame before copying.
1 parent e6e87fb commit 9430290

1 file changed

Lines changed: 12 additions & 6 deletions

File tree

examples/companion_radio/MyMesh.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -650,8 +650,10 @@ void MyMesh::onContactResponse(const ContactInfo &contact, const uint8_t *data,
650650
out_frame[i++] = 0; // reserved
651651
memcpy(&out_frame[i], contact.id.pub_key, 6);
652652
i += 6; // pub_key_prefix
653-
memcpy(&out_frame[i], &data[4], len - 4);
654-
i += (len - 4);
653+
int copy_len = len - 4;
654+
if (copy_len > MAX_FRAME_SIZE - i) copy_len = MAX_FRAME_SIZE - i;
655+
memcpy(&out_frame[i], &data[4], copy_len);
656+
i += copy_len;
655657
_serial->writeFrame(out_frame, i);
656658
} else if (len > 4 && tag == pending_telemetry) { // check for matching response tag
657659
pending_telemetry = 0;
@@ -661,8 +663,10 @@ void MyMesh::onContactResponse(const ContactInfo &contact, const uint8_t *data,
661663
out_frame[i++] = 0; // reserved
662664
memcpy(&out_frame[i], contact.id.pub_key, 6);
663665
i += 6; // pub_key_prefix
664-
memcpy(&out_frame[i], &data[4], len - 4);
665-
i += (len - 4);
666+
int copy_len = len - 4;
667+
if (copy_len > MAX_FRAME_SIZE - i) copy_len = MAX_FRAME_SIZE - i;
668+
memcpy(&out_frame[i], &data[4], copy_len);
669+
i += copy_len;
666670
_serial->writeFrame(out_frame, i);
667671
} else if (len > 4 && tag == pending_req) { // check for matching response tag
668672
pending_req = 0;
@@ -672,8 +676,10 @@ void MyMesh::onContactResponse(const ContactInfo &contact, const uint8_t *data,
672676
out_frame[i++] = 0; // reserved
673677
memcpy(&out_frame[i], &tag, 4); // app needs to match this to RESP_CODE_SENT.tag
674678
i += 4;
675-
memcpy(&out_frame[i], &data[4], len - 4);
676-
i += (len - 4);
679+
int copy_len = len - 4;
680+
if (copy_len > MAX_FRAME_SIZE - i) copy_len = MAX_FRAME_SIZE - i;
681+
memcpy(&out_frame[i], &data[4], copy_len);
682+
i += copy_len;
677683
_serial->writeFrame(out_frame, i);
678684
}
679685
}

0 commit comments

Comments
 (0)