Skip to content

Commit 00f3ef7

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 df01fd3 commit 00f3ef7

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
@@ -694,8 +694,10 @@ void MyMesh::onContactResponse(const ContactInfo &contact, const uint8_t *data,
694694
out_frame[i++] = 0; // reserved
695695
memcpy(&out_frame[i], contact.id.pub_key, 6);
696696
i += 6; // pub_key_prefix
697-
memcpy(&out_frame[i], &data[4], len - 4);
698-
i += (len - 4);
697+
int copy_len = len - 4;
698+
if (copy_len > MAX_FRAME_SIZE - i) copy_len = MAX_FRAME_SIZE - i;
699+
memcpy(&out_frame[i], &data[4], copy_len);
700+
i += copy_len;
699701
_serial->writeFrame(out_frame, i);
700702
} else if (len > 4 && tag == pending_telemetry) { // check for matching response tag
701703
pending_telemetry = 0;
@@ -705,8 +707,10 @@ void MyMesh::onContactResponse(const ContactInfo &contact, const uint8_t *data,
705707
out_frame[i++] = 0; // reserved
706708
memcpy(&out_frame[i], contact.id.pub_key, 6);
707709
i += 6; // pub_key_prefix
708-
memcpy(&out_frame[i], &data[4], len - 4);
709-
i += (len - 4);
710+
int copy_len = len - 4;
711+
if (copy_len > MAX_FRAME_SIZE - i) copy_len = MAX_FRAME_SIZE - i;
712+
memcpy(&out_frame[i], &data[4], copy_len);
713+
i += copy_len;
710714
_serial->writeFrame(out_frame, i);
711715
} else if (len > 4 && tag == pending_req) { // check for matching response tag
712716
pending_req = 0;
@@ -716,8 +720,10 @@ void MyMesh::onContactResponse(const ContactInfo &contact, const uint8_t *data,
716720
out_frame[i++] = 0; // reserved
717721
memcpy(&out_frame[i], &tag, 4); // app needs to match this to RESP_CODE_SENT.tag
718722
i += 4;
719-
memcpy(&out_frame[i], &data[4], len - 4);
720-
i += (len - 4);
723+
int copy_len = len - 4;
724+
if (copy_len > MAX_FRAME_SIZE - i) copy_len = MAX_FRAME_SIZE - i;
725+
memcpy(&out_frame[i], &data[4], copy_len);
726+
i += copy_len;
721727
_serial->writeFrame(out_frame, i);
722728
}
723729
}

0 commit comments

Comments
 (0)