aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2021-10-12 19:52:02 +0200
committerPau Espin Pedrol <pespin@sysmocom.de>2021-10-12 20:07:19 +0200
commitb9fede74ef0b9ac98acbe64a95e704cfbffac342 (patch)
tree70e8f4c1eda66be91354cce2df5f769a186ae84a
parentffa2918bc55c25e3aa3e514e4bd6a22856b61d0e (diff)
tbf: Avoid keeping poll nodes in pdch_ulc of temporary control_ts used during PACCH assignment
When MS sends us the Packet Resource Request as RRBP from final UL ACK/NACK, we create a new TBF with a different set of allocated TS. However, we must send the Pkt UL Assignment with information of the new TBF using that same TS where we receive the Packet Resource Request, which happens to be the control TS of the previous/old TBF. The original control TS of the new TBF is kept in tbf->first_common_ts. Hence the code does gprs_rlcmac_pdch::rcv_resource_request(): """ ul_tbf->control_ts = ts_no; """ And later, when we receive a CTRL ACK answering the Pkt UL Assigment, we change the control TS of the new TBF back to the new one, by calling tbf_assign_control_ts(), which basically does: """ tbf->control_ts = tbf->first_common_ts; """ So, for instance we have a TBF which was allocated with tbf->control_ts=4 and hence is only attached to PDCH 4 (tbf->pdch[]), but for which is temporarily applied tbf->control_ts=7. Hence, when a poll is requested, it is done in control_ts, aka 7, which is not in the array of attached PDCH. The problem is of course if we never reach the point where the final control_ts is set, due to never receiving the CTRL ACK. If the TBF is freed (due to timer X2001) before receiving the CTRL ACK and hence tbf_assign_control_ts() is called, a crash may occur, because potentially a poll for the TBF is left in TS 7 because it's not a PDCH attached to the TBF and hence poll entries on that TS are not released, hence keeping a pointer to the freed TBF. Related: SYS#5647 Change-Id: I0c49f2695e0d932d956c01976c9458eebee63cd4
-rw-r--r--src/tbf.cpp10
1 files changed, 10 insertions, 0 deletions
diff --git a/src/tbf.cpp b/src/tbf.cpp
index af15c725..0331a808 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -243,6 +243,16 @@ static void tbf_unlink_pdch(struct gprs_rlcmac_tbf *tbf)
{
int ts;
+ /* During assignment (state=ASSIGN), tbf may be temporarily using
+ * tbf->control_ts from a previous TBF/SBA to transmit the UL/DL
+ * Assignment, which may not be necessarly be a TS where the current TBF
+ * is attached to. Hence, we may have ULC pollings ongoing and we need
+ * to make sure we drop all reserved nodes there: */
+ if (tbf_state(tbf) == TBF_ST_ASSIGN &&
+ tbf->control_ts != TBF_CONTROL_TS_UNSET && !tbf->pdch[tbf->control_ts])
+ pdch_ulc_release_tbf(tbf->trx->pdch[tbf->control_ts].ulc, tbf);
+
+ /* Now simply detach from all attached PDCHs */
for (ts = 0; ts < 8; ts++) {
if (!tbf->pdch[ts])
continue;