diff options
author | Harald Welte <laforge@osmocom.org> | 2020-12-21 17:43:54 +0100 |
---|---|---|
committer | Harald Welte <laforge@osmocom.org> | 2020-12-21 17:43:54 +0100 |
commit | d2a61179a34282924e86ccaecdb95e3a3711d1ff (patch) | |
tree | d1fda315b89bdd942f23435faba673366ed655b5 | |
parent | c296e2921a616258fbf38018e14fd563084f0fbf (diff) |
lapd_core: Don't dereference data link after sending PRIM_DL_REL
We must always send the RELEASE.{indication,confirm} last before
returning from a function. We cannot rely on the datalink to
still be around after the call, as the SAP user might have destroyed
the data link meanwhile.
This fixes a heap use-after-free (at least) with RBS2000 when the BTS
is fully brought up and the OML data link is lost, see OS#1762
Change-Id: I8ccca8d5e5d07b666557afe12ab8ac4910ddfb00
Related: OS#1761
Related: OS#1762
-rw-r--r-- | src/gsm/lapd_core.c | 9 |
1 files changed, 4 insertions, 5 deletions
diff --git a/src/gsm/lapd_core.c b/src/gsm/lapd_core.c index ed0b3209..e0c232fe 100644 --- a/src/gsm/lapd_core.c +++ b/src/gsm/lapd_core.c @@ -624,8 +624,6 @@ static void lapd_t200_cb(void *data) if (dl->retrans_ctr >= dl->n200_est_rel + 1) { /* send MDL ERROR INIDCATION to L3 */ mdl_error(MDL_CAUSE_T200_EXPIRED, &dl->lctx); - /* send RELEASE INDICATION to L3 */ - send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, &dl->lctx); /* flush tx and send buffers */ lapd_dl_flush_tx(dl); lapd_dl_flush_send(dl); @@ -634,6 +632,8 @@ static void lapd_t200_cb(void *data) /* NOTE: we must not change any other states or buffers * and queues, since we may reconnect after handover * failure. the buffered messages is replaced there */ + /* send RELEASE INDICATION to L3 */ + send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, &dl->lctx); break; } /* retransmit DISC command */ @@ -1230,13 +1230,12 @@ static int lapd_rx_u_ua(struct msgb *msg, struct lapd_msg_ctx *lctx) || !!memcmp(dl->tx_hist[0].msg->data, msg->l3h, length)) { LOGDL(dl, LOGL_INFO, "**** UA response mismatches ****\n"); - rc = send_dl_simple(PRIM_DL_REL, - PRIM_OP_INDICATION, lctx); - msgb_free(msg); /* go to idle state */ lapd_dl_flush_tx(dl); lapd_dl_flush_send(dl); lapd_dl_newstate(dl, LAPD_STATE_IDLE); + rc = send_dl_simple(PRIM_DL_REL, PRIM_OP_INDICATION, lctx); + msgb_free(msg); return 0; } } |