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.
This commit is contained in:
Andre Puschmann 2021-09-24 11:29:20 +02:00
parent 9230bc3b23
commit 59e1bca3f5
2 changed files with 10 additions and 2 deletions

View File

@ -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);

View File

@ -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<std::mutex> 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<uint32_t>(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<std::mutex> 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<std::mutex> 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();