Skip to content

Commit c9c698b

Browse files
committed
QUIC: Added buffer overflow checks
1 parent 5dc1509 commit c9c698b

File tree

1 file changed

+32
-7
lines changed

1 file changed

+32
-7
lines changed

process/quic_parser.cpp

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,13 @@ bool QUICParser::quic_check_pointer_pos(const uint8_t *current, const uint8_t *e
7575

7676
uint64_t QUICParser::quic_get_variable_length(const uint8_t *start, uint64_t &offset)
7777
{
78-
// find out length of parameter field (and load parameter, then move offset) , defined in:
79-
// https://www.rfc-editor.org/rfc/rfc9000.html#name-summary-of-integer-encoding
80-
// this approach is used also in length field , and other QUIC defined fields.
81-
uint64_t tmp = 0;
8278

79+
uint64_t tmp = 0;
80+
if (offset >= CURRENT_BUFFER_SIZE - 1) {
81+
DEBUG_MSG("Error, buffer overflow\n");
82+
offset++;
83+
return 0;
84+
}
8385
uint8_t two_bits = *(start + offset) & 0xC0;
8486

8587
switch (two_bits) {
@@ -88,14 +90,29 @@ uint64_t QUICParser::quic_get_variable_length(const uint8_t *start, uint64_t &of
8890
offset += sizeof(uint8_t);
8991
return tmp;
9092
case 64:
93+
if (offset >= CURRENT_BUFFER_SIZE - 2) {
94+
DEBUG_MSG("Error, buffer overflow\n");
95+
offset+=2;
96+
return 0;
97+
}
9198
tmp = be16toh(*(uint16_t *) (start + offset)) & 0x3FFF;
9299
offset += sizeof(uint16_t);
93100
return tmp;
94101
case 128:
102+
if (offset >= CURRENT_BUFFER_SIZE - 4) {
103+
DEBUG_MSG("Error, buffer overflow\n");
104+
offset+=4;
105+
return 0;
106+
}
95107
tmp = be32toh(*(uint32_t *) (start + offset)) & 0x3FFFFFFF;
96108
offset += sizeof(uint32_t);
97109
return tmp;
98110
case 192:
111+
if (offset >= CURRENT_BUFFER_SIZE - 8) {
112+
DEBUG_MSG("Error, buffer overflow\n");
113+
offset+=8;
114+
return 0;
115+
}
99116
tmp = be64toh(*(uint64_t *) (start + offset)) & 0x3FFFFFFFFFFFFFFF;
100117
offset += sizeof(uint64_t);
101118
return tmp;
@@ -660,7 +677,7 @@ inline void QUICParser::quic_skip_ack1(uint8_t *start, uint64_t &offset)
660677

661678
quic_get_variable_length(start, offset);
662679

663-
for (uint64_t x = 0; x < quic_ack_range_count; x++) {
680+
for (uint64_t x = 0; x < quic_ack_range_count && offset < CURRENT_BUFFER_SIZE; x++) {
664681
quic_get_variable_length(start, offset);
665682
quic_get_variable_length(start, offset);
666683
}
@@ -677,7 +694,7 @@ inline void QUICParser::quic_skip_ack2(uint8_t *start, uint64_t &offset)
677694

678695
quic_get_variable_length(start, offset);
679696

680-
for (uint64_t x = 0; x < quic_ack_range_count; x++) {
697+
for (uint64_t x = 0; x < quic_ack_range_count && offset < CURRENT_BUFFER_SIZE; x++) {
681698
quic_get_variable_length(start, offset);
682699
quic_get_variable_length(start, offset);
683700
}
@@ -716,6 +733,9 @@ inline void QUICParser::quic_copy_crypto(uint8_t *start, uint64_t &offset)
716733
uint16_t frame_offset = quic_get_variable_length(start, offset);
717734
uint16_t frame_length = quic_get_variable_length(start, offset);
718735

736+
frame_offset = std::min(frame_offset, (uint16_t)(CURRENT_BUFFER_SIZE-1));
737+
frame_length = std::min((uint16_t)(CURRENT_BUFFER_SIZE-1-frame_offset), frame_length);
738+
719739
memcpy(assembled_payload + frame_offset, start + offset, frame_length);
720740
if (frame_offset < quic_crypto_start) {
721741
quic_crypto_start = frame_offset;
@@ -733,6 +753,11 @@ bool QUICParser::quic_reassemble_frames()
733753
uint64_t offset = 0;
734754
uint8_t *payload_end = decrypted_payload + payload_len;
735755
uint8_t *current = decrypted_payload + offset;
756+
757+
if (payload_len > CURRENT_BUFFER_SIZE) {
758+
DEBUG_MSG("Payload length too long\n");
759+
return false;
760+
}
736761

737762
while (quic_check_pointer_pos(current, payload_end)) {
738763
// https://www.rfc-editor.org/rfc/rfc9000.html#name-frames-and-frame-types
@@ -742,7 +767,7 @@ bool QUICParser::quic_reassemble_frames()
742767
} else if (quic_check_frame_type(current, ACK1)) {
743768
quic_skip_ack1(decrypted_payload, offset);
744769
} else if (quic_check_frame_type(current, ACK2)) {
745-
quic_skip_ack1(decrypted_payload, offset);
770+
quic_skip_ack2(decrypted_payload, offset);
746771
} else if (quic_check_frame_type(current, CONNECTION_CLOSE1)) {
747772
quic_skip_connection_close1(decrypted_payload, offset);
748773
} else if (quic_check_frame_type(current, CONNECTION_CLOSE2)) {

0 commit comments

Comments
 (0)