diff --git a/CHANGELOG b/CHANGELOG index 8bf1c4b..41679b5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,13 @@ +2022-08-16 + - 3.1.2 + - Update ls-qpack to 2.4.0 to address a use-after-free bug + - Address a few corner cases that trigger assert failures. + - Properly handle unexpected large packet for gQUIC. + - Fix memory leak in shared hash interface + - Fix IPv6 MTU detection + - Fix wrong size used in packet regeneration. + + 2022-05-13 - 3.1.1 - Fix memory leak in processing stream frames (isse #368) diff --git a/docs/conf.py b/docs/conf.py index 9d8c2a9..f0b2f9d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -26,7 +26,7 @@ author = u'LiteSpeed Technologies' # The short X.Y version version = u'3.1' # The full version, including alpha/beta/rc tags -release = u'3.1.1' +release = u'3.1.2' # -- General configuration --------------------------------------------------- diff --git a/include/lsquic.h b/include/lsquic.h index 0dba46e..1532d21 100644 --- a/include/lsquic.h +++ b/include/lsquic.h @@ -25,7 +25,7 @@ extern "C" { #define LSQUIC_MAJOR_VERSION 3 #define LSQUIC_MINOR_VERSION 1 -#define LSQUIC_PATCH_VERSION 1 +#define LSQUIC_PATCH_VERSION 2 /** * Engine flags: diff --git a/src/liblsquic/ls-qpack b/src/liblsquic/ls-qpack index ecccd91..b97e714 160000 --- a/src/liblsquic/ls-qpack +++ b/src/liblsquic/ls-qpack @@ -1 +1 @@ -Subproject commit ecccd9193f1ed94e496aeedd76fd1dc0cc3b4c02 +Subproject commit b97e714470a01c7c8b1999cb42f267b34265fcae diff --git a/src/liblsquic/lsquic_full_conn_ietf.c b/src/liblsquic/lsquic_full_conn_ietf.c index 5af1642..c8c9575 100644 --- a/src/liblsquic/lsquic_full_conn_ietf.c +++ b/src/liblsquic/lsquic_full_conn_ietf.c @@ -3130,6 +3130,7 @@ ietf_full_conn_ci_destroy (struct lsquic_conn *lconn) lsquic_malo_destroy(conn->ifc_pub.packet_out_malo); if (conn->ifc_flags & IFC_CREATED_OK) conn->ifc_enpub->enp_stream_if->on_conn_closed(&conn->ifc_conn); + assert(conn->ifc_conn.cn_conn_ctx == NULL); if (conn->ifc_conn.cn_enc_session) conn->ifc_conn.cn_esf.i->esfi_destroy(conn->ifc_conn.cn_enc_session); while (!STAILQ_EMPTY(&conn->ifc_stream_ids_to_ss)) diff --git a/src/liblsquic/lsquic_handshake.c b/src/liblsquic/lsquic_handshake.c index d292f72..f6d3b35 100644 --- a/src/liblsquic/lsquic_handshake.c +++ b/src/liblsquic/lsquic_handshake.c @@ -3088,6 +3088,12 @@ decrypt_packet (struct lsquic_enc_session *enc_session, uint8_t path_id, sizeof(path_id_packet_number)); *out_len = data_len; + if (data_len + *header_len > max_out_len) + { + LSQ_DEBUG("decrypt_packet size is larger than 1370, header: %zd, " + "data: %zu, giveup.", *header_len, data_len); + return (enum enc_level) -1; + } ret = lsquic_aes_aead_dec(key, buf, *header_len, nonce, 12, diff --git a/src/liblsquic/lsquic_stock_shi.c b/src/liblsquic/lsquic_stock_shi.c index eca31f5..280461a 100644 --- a/src/liblsquic/lsquic_stock_shi.c +++ b/src/liblsquic/lsquic_stock_shi.c @@ -43,8 +43,6 @@ struct hash_elem static void free_key_data (struct hash_elem *he) { - if (he->data_sz) - free(he->data); free(he->key.buf); } @@ -87,9 +85,17 @@ stock_shi_insert (void *hash_ctx, void *key, unsigned key_sz, he = lsquic_malo_get(hash->malo); if (!he) return -1; - he->key.buf = key; + he->key.buf = malloc(key_sz + data_sz + 1); + if (!he->key.buf) + { + lsquic_malo_put(he); + return -1; + } + memmove(he->key.buf, key, key_sz); + ((char *)(he->key.buf))[key_sz] = 0; he->key.sz = key_sz; - he->data = data; + he->data = he->key.buf + he->key.sz + 1; + memmove(he->data, data, data_sz); he->data_sz = data_sz; he->expiry = expiry; memset(&he->lhash_elem, 0, sizeof(he->lhash_elem)); diff --git a/src/liblsquic/lsquic_stream.c b/src/liblsquic/lsquic_stream.c index 0fb1856..9020115 100644 --- a/src/liblsquic/lsquic_stream.c +++ b/src/liblsquic/lsquic_stream.c @@ -4359,14 +4359,16 @@ void lsquic_stream_acked (struct lsquic_stream *stream, enum quic_frame_type frame_type) { - assert(stream->n_unacked); - --stream->n_unacked; - LSQ_DEBUG("ACKed; n_unacked: %u", stream->n_unacked); - if (frame_type == QUIC_FRAME_RST_STREAM) + if (stream->n_unacked > 0) { - SM_HISTORY_APPEND(stream, SHE_RST_ACKED); - LSQ_DEBUG("RESET that we sent has been acked by peer"); - stream->stream_flags |= STREAM_RST_ACKED; + --stream->n_unacked; + LSQ_DEBUG("ACKed; n_unacked: %u", stream->n_unacked); + if (frame_type == QUIC_FRAME_RST_STREAM) + { + SM_HISTORY_APPEND(stream, SHE_RST_ACKED); + LSQ_DEBUG("RESET that we sent has been acked by peer"); + stream->stream_flags |= STREAM_RST_ACKED; + } } if (0 == stream->n_unacked) { diff --git a/src/liblsquic/lsquic_tokgen.c b/src/liblsquic/lsquic_tokgen.c index 28dc214..45caab4 100644 --- a/src/liblsquic/lsquic_tokgen.c +++ b/src/liblsquic/lsquic_tokgen.c @@ -89,7 +89,8 @@ get_or_generate_state (struct lsquic_engine_public *enpub, time_t now, { const struct lsquic_shared_hash_if *const shi = enpub->enp_shi; void *const ctx = enpub->enp_shi_ctx; - void *data, *copy, *key_copy; + void *data, *copy; + char key_copy[TOKGEN_SHM_KEY_SIZE]; int s; unsigned sz; size_t bufsz; @@ -166,28 +167,13 @@ get_or_generate_state (struct lsquic_engine_public *enpub, time_t now, memcpy(shm_state->tgss_magic_bottom, TOKGEN_SHM_MAGIC_BOTTOM, sizeof(TOKGEN_SHM_MAGIC_BOTTOM) - 1); - data = malloc(sizeof(*shm_state)); - if (!data) - { - LSQ_ERROR("%s: malloc", __func__); - return -1; - } - memcpy(data, shm_state, sizeof(*shm_state)); - key_copy = malloc(TOKGEN_SHM_KEY_SIZE); - if (!key_copy) - { - LSQ_ERROR("%s: malloc", __func__); - free(data); - return -1; - } + data = shm_state; memcpy(key_copy, TOKGEN_SHM_KEY, TOKGEN_SHM_KEY_SIZE); s = shi->shi_insert(ctx, key_copy, TOKGEN_SHM_KEY_SIZE, data, sizeof(*shm_state), 0); if (s != 0) { LSQ_ERROR("cannot insert into SHM"); - free(data); - free(key_copy); return -1; } sz = sizeof(*shm_state); diff --git a/tests/test_shi.c b/tests/test_shi.c index 138c7f7..492701d 100644 --- a/tests/test_shi.c +++ b/tests/test_shi.c @@ -24,30 +24,6 @@ static const struct pair { }; -struct data { - size_t size; /* Overall size including the payload */ - char *key; - char *value; - char data[0]; /* key followed by value */ -}; - - -static struct data * -new_data (const char *key, const char *value) -{ - size_t klen = strlen(key); - size_t vlen = strlen(value); - size_t size = klen + vlen + 2 + sizeof(struct data); - struct data *data = malloc(size); - data->size = size; - data->key = data->data; - data->value = data->data + klen + 1; - memcpy(data->data, key, klen); - data->key[klen] = '\0'; - memcpy(data->value, value, vlen); - data->value[vlen] = '\0'; - return data; -} #define N_PAIRS (sizeof(pairs) / sizeof(pairs[0])) @@ -73,7 +49,6 @@ test_shi (const struct order *order) const time_t now = time(NULL); time_t expiry; void *datap; - struct data *data; hash = lsquic_stock_shared_hash_new(); @@ -84,9 +59,8 @@ test_shi (const struct order *order) expiry = now + 1; else expiry = 0; - data = new_data(pair->key, pair->value); - s = stock_shi.shi_insert(hash, strdup(data->key), strlen(data->key), - data, data->size, expiry); + s = stock_shi.shi_insert(hash, (char *)pair->key, strlen(pair->key), + (char *)pair->value, strlen(pair->value), expiry); assert(0 == s); } @@ -107,11 +81,9 @@ test_shi (const struct order *order) } else { - data = datap; assert(1 == s); - assert(data_sz == data->size); - assert(0 == strcmp(pair->key, data->key)); - assert(0 == strcmp(pair->value, data->value)); + assert(data_sz == strlen(pair->value)); + assert(0 == strncmp(pair->value, datap, data_sz)); } }