From 3bbb3cc1f23a74987b2fc993fbc38e8c05c6ac08 Mon Sep 17 00:00:00 2001 From: Pau Espin Pedrol Date: Tue, 31 Aug 2021 14:09:42 +0200 Subject: [PATCH] Fix crash with dyn TS when using direct pcu It seems there may be a race conditon where lower layers (direct PCU) send UL blocks to us while the PDCH was already disabled (due to a call entering on a dynamic TS). As the PDCH is disabled, the ULC is NULL and shouldn't be used before being enabled again. Related: OS#5222 Change-Id: I4b8931f0cc7cfc787a1cc35196295402524b15c3 --- src/bts.cpp | 36 +++++++++++++++++++++--------------- src/pcu_l1_if.cpp | 5 +++++ 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/bts.cpp b/src/bts.cpp index 12a1b04b..62870db5 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -1159,25 +1159,31 @@ void bts_update_tbf_ta(struct gprs_rlcmac_bts *bts, const char *p, uint32_t fn, uint8_t trx_no, uint8_t ts, int8_t ta, bool is_rach) { struct gprs_rlcmac_pdch *pdch = &bts->trx[trx_no].pdch[ts]; - struct pdch_ulc_node *poll = pdch_ulc_get_node(pdch->ulc, fn); + struct pdch_ulc_node *poll; struct gprs_rlcmac_ul_tbf *tbf; + if (!pdch->is_enabled()) + goto no_tbf; + + poll = pdch_ulc_get_node(pdch->ulc, fn); if (!poll || poll->type !=PDCH_ULC_NODE_TBF_POLL || poll->tbf_poll.poll_tbf->direction != GPRS_RLCMAC_UL_TBF) - LOGP(DL1IF, LOGL_DEBUG, "[%s] update TA = %u ignored due to " - "unknown UL TBF on TRX = %d, TS = %d, FN = %d\n", - p, ta, trx_no, ts, fn); - else { - tbf = as_ul_tbf(poll->tbf_poll.poll_tbf); - /* we need to distinguish TA information provided by L1 - * from PH-DATA-IND and PHY-RA-IND so that we can properly - * update TA for given TBF - */ - if (is_rach) - set_tbf_ta(tbf, (uint8_t)ta); - else - update_tbf_ta(tbf, ta); + goto no_tbf; - } + tbf = as_ul_tbf(poll->tbf_poll.poll_tbf); + /* we need to distinguish TA information provided by L1 + * from PH-DATA-IND and PHY-RA-IND so that we can properly + * update TA for given TBF + */ + if (is_rach) + set_tbf_ta(tbf, (uint8_t)ta); + else + update_tbf_ta(tbf, ta); + return; + +no_tbf: + LOGP(DL1IF, LOGL_DEBUG, "[%s] update TA = %u ignored due to " + "unknown UL TBF on TRX = %d, TS = %d, FN = %d\n", + p, ta, trx_no, ts, fn); } void bts_trx_init(struct gprs_rlcmac_trx *trx, struct gprs_rlcmac_bts *bts, uint8_t trx_no) diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp index 5aa88494..4530e1a5 100644 --- a/src/pcu_l1_if.cpp +++ b/src/pcu_l1_if.cpp @@ -281,6 +281,11 @@ int pcu_rx_data_ind_pdtch(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_pdch * { int rc; + if (!pdch->is_enabled()) { + LOGPDCH(pdch, DL1IF, LOGL_INFO, "Received DATA.ind (PDTCH) on disabled TS\n"); + return -EINVAL; + } + rc = pdch->rcv_block(data, len, fn, meas); pdch_ulc_expire_fn(pdch->ulc, fn); return rc;