aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2017-12-13 19:05:36 +0100
committerNeels Hofmeyr <neels@hofmeyr.de>2017-12-13 19:13:44 +0100
commit719322693c2803803326a909a9d3e57564ad7236 (patch)
tree49a43a7e5b1c3d18946755a2cb85b89ec68f2887
parent61b0c30cca80cba5522b172b884b2904b91eb516 (diff)
fix segfault upon release paging on BSSMAP Reset: init llist
Initialize the llist head gsm_bts->paging.pending_requests at the time gsm_bts is allocated, not only at paging_init_if_needed(). The gsm_bts->paging sub-struct is invalid as long as gsm_bts->paging.bts doesn't point back to bts. Hence the recently added iteration of gsm_bts->paging.pending_requests should have checked whether bts is NULL. The llist_head pending_requests is not initialized unless paging_init_if_needed() has been called (and paging.bts is hence set). However, this fix is a safer way to prevent errors like this in general. The segfault was introduced by d382bf63e2b7e28fe41c5310c26fe584f0356897 / If3f53d3bb66ad2dc02db823cb813590c6b59c700 Related: OS#2747 Change-Id: Idfafac4e2c0e0a241a62aecbbdc22be71febf840
-rw-r--r--src/libbsc/paging.c6
-rw-r--r--src/libcommon/gsm_data_shared.c3
2 files changed, 8 insertions, 1 deletions
diff --git a/src/libbsc/paging.c b/src/libbsc/paging.c
index 8d54d0a5e..d657bd306 100644
--- a/src/libbsc/paging.c
+++ b/src/libbsc/paging.c
@@ -240,7 +240,11 @@ static void paging_init_if_needed(struct gsm_bts *bts)
return;
bts->paging.bts = bts;
- INIT_LLIST_HEAD(&bts->paging.pending_requests);
+
+ /* This should be initialized only once. There is currently no code that sets bts->paging.bts
+ * back to NULL, so let's just assert this one instead of graceful handling. */
+ OSMO_ASSERT(llist_empty(&bts->paging.pending_requests));
+
osmo_timer_setup(&bts->paging.work_timer, paging_worker,
&bts->paging);
diff --git a/src/libcommon/gsm_data_shared.c b/src/libcommon/gsm_data_shared.c
index 2f7e7e353..30ef1cafe 100644
--- a/src/libcommon/gsm_data_shared.c
+++ b/src/libcommon/gsm_data_shared.c
@@ -364,7 +364,10 @@ struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, uint8_t bts_num)
bts->rach_b_thresh = -1;
bts->rach_ldavg_slots = -1;
+
bts->paging.free_chans_need = -1;
+ INIT_LLIST_HEAD(&bts->paging.pending_requests);
+
bts->features.data = &bts->_features_data[0];
bts->features.data_len = sizeof(bts->_features_data);