From fccfd5e1408206049139ecb7b029ecfb922222b5 Mon Sep 17 00:00:00 2001 From: Robert Falkenberg Date: Mon, 23 May 2022 12:15:25 +0200 Subject: [PATCH] lib,rlc_am_{lte,nr}: fix/add tx_window overrun protection This commit fixes as bug causing a crash of the eNB in case of many pending RETX and the reception of a trimmed PDU. The following sequence leads to a crash: - RETX queue contains many PDUs for RETX - Receive trimmed PDU containing a trimmed subset of NACKs - RETX queue is cleared and re-populated with a trimmed subset - After all RETX (/!\ trimmed subset) is done, continue TX new PDUs - tx_window blows up - tx_window overflows if another status PDU is not received in time - Overflow overwrites oldest element in tx_window - Handling of next status PDU fails due to missing elements in tx_window Related PR #4029 --- lib/src/rlc/rlc_am_lte.cc | 4 ++-- lib/src/rlc/rlc_am_nr.cc | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/src/rlc/rlc_am_lte.cc b/lib/src/rlc/rlc_am_lte.cc index e11780011..8279a8858 100644 --- a/lib/src/rlc/rlc_am_lte.cc +++ b/lib/src/rlc/rlc_am_lte.cc @@ -690,8 +690,8 @@ int rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_bytes) } // do not build any more PDU if window is already full - if (tx_sdu == NULL && tx_window.size() >= RLC_AM_WINDOW_SIZE) { - RlcInfo("Tx window full."); + if (tx_window.size() >= RLC_AM_WINDOW_SIZE) { + RlcInfo("Cannot build data PDU - Tx window full."); return 0; } diff --git a/lib/src/rlc/rlc_am_nr.cc b/lib/src/rlc/rlc_am_nr.cc index dda2e66a0..2ddb062d4 100644 --- a/lib/src/rlc/rlc_am_nr.cc +++ b/lib/src/rlc/rlc_am_nr.cc @@ -175,6 +175,13 @@ uint32_t rlc_am_nr_tx::build_new_pdu(uint8_t* payload, uint32_t nof_bytes) RlcInfo("Not enough bytes for payload plus header. nof_bytes=%d", nof_bytes); return 0; } + + // do not build any more PDU if window is already full + if (tx_window->size() >= RLC_AM_WINDOW_SIZE) { + RlcInfo("Cannot build data PDU - Tx window full."); + return 0; + } + // Read new SDU from TX queue unique_byte_buffer_t tx_sdu; RlcDebug("Reading from RLC SDU queue. Queue size %d", tx_sdu_queue.size());