diff options
author | Nardi Ivan <nardi.ivan@gmail.com> | 2020-09-10 18:19:18 +0200 |
---|---|---|
committer | Nardi Ivan <nardi.ivan@gmail.com> | 2020-09-10 18:19:18 +0200 |
commit | 8db084ab06ae73e26c2373e92b35cbc5407d41bd (patch) | |
tree | dcc3d072d6e530190738e27e1a921850c0df9614 /src | |
parent | 7d5a0e1f04bce1b3de1eb5f4eea07fc4d25c8c92 (diff) |
TLS: fix memory accesses in QUIC transport parameters extension
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/protocols/quic.c | 16 | ||||
-rw-r--r-- | src/lib/protocols/tls.c | 25 |
2 files changed, 37 insertions, 4 deletions
diff --git a/src/lib/protocols/quic.c b/src/lib/protocols/quic.c index 1913a8d85..f58c030f5 100644 --- a/src/lib/protocols/quic.c +++ b/src/lib/protocols/quic.c @@ -170,6 +170,22 @@ int quic_len(const uint8_t *buf, uint64_t *value) return 0; } } +int quic_len_buffer_still_required(uint8_t value) +{ + switch(value >> 6) { + case 0: + return 0; + case 1: + return 1; + case 2: + return 3; + case 3: + return 7; + default: /* No Possible */ + return 0; + } +} + static uint16_t gquic_get_u16(const uint8_t *buf, uint32_t version) { diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c index 18a56622f..0545d4972 100644 --- a/src/lib/protocols/tls.c +++ b/src/lib/protocols/tls.c @@ -37,6 +37,7 @@ extern int http_process_user_agent(struct ndpi_detection_module_struct *ndpi_str const u_int8_t *ua_ptr, u_int16_t ua_ptr_len); /* QUIC/GQUIC stuff */ extern int quic_len(const uint8_t *buf, uint64_t *value); +extern int quic_len_buffer_still_required(uint8_t value); extern int is_version_with_var_int_transport_params(uint32_t version); // #define DEBUG_TLS_MEMORY 1 @@ -1374,13 +1375,17 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, } } else if(extension_id == 65445 /* QUIC transport parameters */) { u_int16_t s_offset = offset+extension_offset; - uint32_t final_offset; + uint16_t final_offset; int using_var_int = is_version_with_var_int_transport_params(quic_version); if(!using_var_int) { - u_int16_t seq_len = ntohs(*((u_int16_t*)&packet->payload[s_offset])); - s_offset += 2; - final_offset = MIN(total_len, s_offset + seq_len); + if(s_offset+1 >= total_len) { + final_offset = 0; /* Force skipping extension */ + } else { + u_int16_t seq_len = ntohs(*((u_int16_t*)&packet->payload[s_offset])); + s_offset += 2; + final_offset = MIN(total_len, s_offset + seq_len); + } } else { final_offset = MIN(total_len, s_offset + extension_len); } @@ -1389,17 +1394,29 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, u_int64_t param_type, param_len; if(!using_var_int) { + if(s_offset+3 >= final_offset) + break; param_type = ntohs(*((u_int16_t*)&packet->payload[s_offset])); param_len = ntohs(*((u_int16_t*)&packet->payload[s_offset + 2])); s_offset += 4; } else { + if(s_offset >= final_offset || + (s_offset + quic_len_buffer_still_required(packet->payload[s_offset])) >= final_offset) + break; s_offset += quic_len(&packet->payload[s_offset], ¶m_type); + + if(s_offset >= final_offset || + (s_offset + quic_len_buffer_still_required(packet->payload[s_offset])) >= final_offset) + break; s_offset += quic_len(&packet->payload[s_offset], ¶m_len); } #ifdef DEBUG_TLS printf("Client SSL [QUIC TP: Param 0x%x Len %d]\n", (int)param_type, (int)param_len); #endif + if(s_offset+param_len >= final_offset) + break; + if(param_type==0x3129) { #ifdef DEBUG_TLS printf("UA [%.*s]\n", (int)param_len, &packet->payload[s_offset]); |