@@ -75,11 +75,13 @@ bool QUICParser::quic_check_pointer_pos(const uint8_t *current, const uint8_t *e
7575
7676uint64_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