[paging] In expiration handling remove the request before doing the callback

Not doing this could lead to a double deletion due the paging
request being removed during the callback and afterwards as
well. Change the code to save the callback data, remove the
request, do the callback.

A patch was proposed by Andreas Eversberg and this one is
based on it.
diff --git a/openbsc/src/paging.c b/openbsc/src/paging.c
index 87c7e7d..69902e8 100644
--- a/openbsc/src/paging.c
+++ b/openbsc/src/paging.c
@@ -197,6 +197,8 @@
 {
 	struct gsm_paging_request *req = (struct gsm_paging_request *)data;
 	struct paging_signal_data sig_data;
+	void *cbfn_param;
+	gsm_cbfn *cbfn;
 
 	DEBUGP(DPAG, "T3113 expired for request %p (%s)\n",
 		req, req->subscr->imsi);
@@ -205,11 +207,15 @@
 	sig_data.bts	= req->bts;
 	sig_data.lchan	= NULL;
 
-	dispatch_signal(SS_PAGING, S_PAGING_COMPLETED, &sig_data);
-	if (req->cbfn)
-		req->cbfn(GSM_HOOK_RR_PAGING, GSM_PAGING_EXPIRED, NULL, NULL,
-			  req->cbfn_param);
+	/* must be destroyed before calling cbfn, to prevent double free */
+	cbfn_param = req->cbfn_param;
+	cbfn = req->cbfn;
 	paging_remove_request(&req->bts->paging, req);
+
+	dispatch_signal(SS_PAGING, S_PAGING_COMPLETED, &sig_data);
+	if (cbfn)
+		cbfn(GSM_HOOK_RR_PAGING, GSM_PAGING_EXPIRED, NULL, NULL,
+			  cbfn_param);
 }
 
 static int _paging_request(struct gsm_bts *bts, struct gsm_subscriber *subscr,