From 59e1bca3f55d191015c9c94ae6347aaf0ae34e8b Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 24 Sep 2021 11:29:20 +0200 Subject: [PATCH] rlc_am_lte: fix potential crash when attempting to resize tx queue under some circumstances it could happen that the RLC is configured when SDUs are already being written to the queue. The resize operation of the underlying container would fail in this case. Make sure to empty the queue before doing the resize. --- lib/include/srsran/rlc/rlc_am_lte.h | 1 + lib/src/rlc/rlc_am_lte.cc | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/include/srsran/rlc/rlc_am_lte.h b/lib/include/srsran/rlc/rlc_am_lte.h index 4d235bff2..abfe17504 100644 --- a/lib/include/srsran/rlc/rlc_am_lte.h +++ b/lib/include/srsran/rlc/rlc_am_lte.h @@ -392,6 +392,7 @@ private: void update_notification_ack_info(uint32_t rlc_sn); void debug_state(); + void empty_queue_unsafe(); int required_buffer_size(const rlc_amd_retx_t& retx); void retransmit_pdu(uint32_t sn); diff --git a/lib/src/rlc/rlc_am_lte.cc b/lib/src/rlc/rlc_am_lte.cc index 700d79265..62fc19f35 100644 --- a/lib/src/rlc/rlc_am_lte.cc +++ b/lib/src/rlc/rlc_am_lte.cc @@ -299,6 +299,7 @@ void rlc_am_lte::rlc_am_lte_tx::set_bsr_callback(bsr_callback_t callback) bool rlc_am_lte::rlc_am_lte_tx::configure(const rlc_config_t& cfg_) { + std::lock_guard lock(mutex); if (cfg_.tx_queue_length > MAX_SDUS_PER_RLC_PDU) { logger.error("Configuring Tx queue length of %d PDUs too big. Maximum value is %d.", cfg_.tx_queue_length, @@ -325,6 +326,8 @@ bool rlc_am_lte::rlc_am_lte_tx::configure(const rlc_config_t& cfg_) poll_retx_timer.set(static_cast(cfg.t_poll_retx), [this](uint32_t timerid) { timer_expired(timerid); }); } + // make sure Tx queue is empty before attempting to resize + empty_queue_unsafe(); tx_sdu_queue.resize(cfg_.tx_queue_length); tx_enabled = true; @@ -334,10 +337,10 @@ bool rlc_am_lte::rlc_am_lte_tx::configure(const rlc_config_t& cfg_) void rlc_am_lte::rlc_am_lte_tx::stop() { - empty_queue(); - std::lock_guard lock(mutex); + empty_queue_unsafe(); + tx_enabled = false; if (parent->timers != nullptr && poll_retx_timer.is_valid()) { @@ -369,7 +372,11 @@ void rlc_am_lte::rlc_am_lte_tx::stop() void rlc_am_lte::rlc_am_lte_tx::empty_queue() { std::lock_guard lock(mutex); + empty_queue_unsafe(); +} +void rlc_am_lte::rlc_am_lte_tx::empty_queue_unsafe() +{ // deallocate all SDUs in transmit queue while (tx_sdu_queue.size() > 0) { unique_byte_buffer_t buf = tx_sdu_queue.read();