From 1a0003e3b96e9aed3b3612ae5013552bc99b4f8e Mon Sep 17 00:00:00 2001 From: Dmitri Tikhonov Date: Wed, 6 Jan 2021 17:53:07 -0500 Subject: [PATCH] Release 2.27.2 - [BUGFIX] Memory corruption in receive history copy-ranges function. --- CHANGELOG | 4 ++++ LICENSE | 2 +- README.md | 2 +- docs/conf.py | 4 ++-- include/lsquic.h | 2 +- src/liblsquic/lsquic_full_conn_ietf.c | 3 ++- src/liblsquic/lsquic_rechist.c | 11 +++++++---- tests/test_rechist.c | 21 +++++++++++++++++++++ 8 files changed, 39 insertions(+), 10 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index aa6e4617b..f4104c003 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +2021-01-06 + - 2.27.2 + - [BUGFIX] Memory corruption in receive history copy-ranges function. + 2021-01-06 - 2.27.1 - [API] New knob to set outgoing packet batch size. diff --git a/LICENSE b/LICENSE index 921653c1f..b825fe57b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc +Copyright (c) 2017 - 2021 LiteSpeed Technologies Inc Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index fff0c97b5..ea96691f8 100644 --- a/README.md +++ b/README.md @@ -165,4 +165,4 @@ Have fun, LiteSpeed QUIC Team. -Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc +Copyright (c) 2017 - 2021 LiteSpeed Technologies Inc diff --git a/docs/conf.py b/docs/conf.py index dfbfe38c2..dd7d2328b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -20,13 +20,13 @@ # -- Project information ----------------------------------------------------- project = u'lsquic' -copyright = u'2020, LiteSpeed Technologies' +copyright = u'2021, LiteSpeed Technologies' author = u'LiteSpeed Technologies' # The short X.Y version version = u'2.27' # The full version, including alpha/beta/rc tags -release = u'2.27.1' +release = u'2.27.2' # -- General configuration --------------------------------------------------- diff --git a/include/lsquic.h b/include/lsquic.h index 298ea4ba2..506f62de5 100644 --- a/include/lsquic.h +++ b/include/lsquic.h @@ -25,7 +25,7 @@ extern "C" { #define LSQUIC_MAJOR_VERSION 2 #define LSQUIC_MINOR_VERSION 27 -#define LSQUIC_PATCH_VERSION 1 +#define LSQUIC_PATCH_VERSION 2 /** * Engine flags: diff --git a/src/liblsquic/lsquic_full_conn_ietf.c b/src/liblsquic/lsquic_full_conn_ietf.c index 9e83f5ce3..f5fec6fd1 100644 --- a/src/liblsquic/lsquic_full_conn_ietf.c +++ b/src/liblsquic/lsquic_full_conn_ietf.c @@ -8076,7 +8076,8 @@ ietf_full_conn_ci_set_min_datagram_size (struct lsquic_conn *lconn, if (new_size > USHRT_MAX) { - LSQ_DEBUG("min datagram size cannot be larger than %hu", USHRT_MAX); + LSQ_DEBUG("min datagram size cannot be larger than %hu", + (unsigned short) USHRT_MAX); return -1; } diff --git a/src/liblsquic/lsquic_rechist.c b/src/liblsquic/lsquic_rechist.c index e9a6c327c..222f58680 100644 --- a/src/liblsquic/lsquic_rechist.c +++ b/src/liblsquic/lsquic_rechist.c @@ -496,13 +496,13 @@ lsquic_rechist_copy_ranges (struct lsquic_rechist *rechist, void *src_rechist, { const struct lsquic_packno_range *range; struct rechist_elem *el; - unsigned *next_idx; + unsigned prev_idx; int idx; /* This function only works if rechist contains no elements */ assert(rechist->rh_n_used == 0); - next_idx = &rechist->rh_head; + prev_idx = UINT_MAX; for (range = first(src_rechist); range; range = next(src_rechist)) { idx = rechist_alloc_elem(rechist); @@ -512,8 +512,11 @@ lsquic_rechist_copy_ranges (struct lsquic_rechist *rechist, void *src_rechist, el->re_low = range->low; el->re_count = range->high - range->low + 1; el->re_next = UINT_MAX; - *next_idx = idx; - next_idx = &el->re_next; + if (prev_idx == UINT_MAX) + rechist->rh_head = idx; + else + rechist->rh_elems[prev_idx].re_next = idx; + prev_idx = idx; } return 0; diff --git a/tests/test_rechist.c b/tests/test_rechist.c index 5fa80e54f..4af4ce3ba 100644 --- a/tests/test_rechist.c +++ b/tests/test_rechist.c @@ -116,6 +116,23 @@ rechist2str (lsquic_rechist_t *rechist, char *buf, size_t bufsz) } +static void +test_range_copy (struct lsquic_rechist *orig, int ietf) +{ + char orig_str[0x1000], new_str[0x1000]; + struct lsquic_rechist new; + + rechist2str(orig, orig_str, sizeof(orig_str)); + + lsquic_rechist_init(&new, ietf, 0); + lsquic_rechist_copy_ranges(&new, orig, + (const struct lsquic_packno_range * (*) (void *)) lsquic_rechist_first, + (const struct lsquic_packno_range * (*) (void *)) lsquic_rechist_next); + rechist2str(&new, new_str, sizeof(new_str)); + assert(0 == strcmp(orig_str, new_str)); +} + + static void test5 (void) { @@ -150,6 +167,7 @@ test5 (void) assert(0 == strcmp(buf, "[12-12][10-10][8-6][4-3][1-1]")); lsquic_rechist_received(&rechist, 9, 0); + test_range_copy(&rechist, 0); rechist2str(&rechist, buf, sizeof(buf)); assert(0 == strcmp(buf, "[12-12][10-6][4-3][1-1]")); @@ -182,6 +200,8 @@ test_rand_sequence (unsigned seed, unsigned max) assert(st == REC_ST_OK || st == REC_ST_DUP); } + test_range_copy(&rechist, 1); + range = lsquic_rechist_first(&rechist); assert(range); assert(range->high >= range->low); @@ -246,6 +266,7 @@ test_shuffle_1000 (unsigned seed) st = lsquic_rechist_received(&rechist, els[i].packno, 0); assert(st == REC_ST_OK || st == REC_ST_DUP); } + test_range_copy(&rechist, 1); range = lsquic_rechist_first(&rechist); assert(range);