[PATCH] osmo-msc[master]: sub_pres_vlr_fsm_start: fix heap use after free

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Neels Hofmeyr gerrit-no-reply at lists.osmocom.org
Sat Nov 18 22:58:33 UTC 2017


Review at  https://gerrit.osmocom.org/4923

sub_pres_vlr_fsm_start: fix heap use after free

When sub_pres_vlr_fsm_start() is called, it dispatches an event which may in
some cases already cause tear down and free of the parent FSM instance, after
which storing the returned instance pointer in that parent's metadata will use
freed memory. Instead, pass the target pointer to remember the instance at to
sub_pres_vlr_fsm_start() and assign the pointer *before* firing the event.

Explain so in a new comment.

I haven't checked whether that pointer is actually used at all -- this is the
easiest way to fix the use-after-free without getting sucked into semantic
questions.

Change-Id: Ibdc0b64cd12ba3e2b9737e3517d8484e67abcf04
---
M include/osmocom/msc/vlr.h
M src/libvlr/vlr_access_req_fsm.c
M src/libvlr/vlr_lu_fsm.c
3 files changed, 20 insertions(+), 14 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-msc refs/changes/23/4923/1

diff --git a/include/osmocom/msc/vlr.h b/include/osmocom/msc/vlr.h
index d5306fa..9e6b12c 100644
--- a/include/osmocom/msc/vlr.h
+++ b/include/osmocom/msc/vlr.h
@@ -274,9 +274,10 @@
 
 /* internal use only */
 
-struct osmo_fsm_inst *sub_pres_vlr_fsm_start(struct osmo_fsm_inst *parent,
-					     struct vlr_subscr *vsub,
-					     uint32_t term_event);
+void sub_pres_vlr_fsm_start(struct osmo_fsm_inst **fsm,
+			    struct osmo_fsm_inst *parent,
+			    struct vlr_subscr *vsub,
+			    uint32_t term_event);
 struct osmo_fsm_inst *
 upd_hlr_vlr_proc_start(struct osmo_fsm_inst *parent,
 		       struct vlr_subscr *vsub,
diff --git a/src/libvlr/vlr_access_req_fsm.c b/src/libvlr/vlr_access_req_fsm.c
index 41620b9..e90d8de 100644
--- a/src/libvlr/vlr_access_req_fsm.c
+++ b/src/libvlr/vlr_access_req_fsm.c
@@ -241,8 +241,7 @@
 	if (vsub->ms_not_reachable_flag) {
 		/* Start Subscriber_Present_VLR */
 		osmo_fsm_inst_state_chg(fi, PR_ARQ_S_WAIT_SUB_PRES, 0, 0);
-		par->sub_pres_vlr_fsm = sub_pres_vlr_fsm_start(fi, vsub,
-							PR_ARQ_E_PRES_RES);
+		sub_pres_vlr_fsm_start(&par->sub_pres_vlr_fsm, fi, vsub, PR_ARQ_E_PRES_RES);
 		return;
 	}
 	_proc_arq_vlr_post_pres(fi);
diff --git a/src/libvlr/vlr_lu_fsm.c b/src/libvlr/vlr_lu_fsm.c
index 37fe235..a3a68ed 100644
--- a/src/libvlr/vlr_lu_fsm.c
+++ b/src/libvlr/vlr_lu_fsm.c
@@ -252,21 +252,29 @@
 	.event_names = sub_pres_vlr_event_names,
 };
 
-struct osmo_fsm_inst *sub_pres_vlr_fsm_start(struct osmo_fsm_inst *parent,
-					     struct vlr_subscr *vsub,
-					     uint32_t term_event)
+/* Note that the start event is dispatched right away, so in case the FSM immediately concludes from that
+ * event, the created FSM struct may no longer be valid as it already deallocated again, and it may
+ * furthermore already have invoked the parent FSM instance's deallocation as well. Hence, instead of
+ * returning, store the created FSM instance address in *fi_p before dispatching the event. It is thus
+ * possible to store the instance's pointer in a parent FSM instance without running danger of using
+ * already freed memory. */
+void sub_pres_vlr_fsm_start(struct osmo_fsm_inst **fi_p,
+			    struct osmo_fsm_inst *parent,
+			    struct vlr_subscr *vsub,
+			    uint32_t term_event)
 {
 	struct osmo_fsm_inst *fi;
 
+	OSMO_ASSERT(fi_p);
+
 	fi = osmo_fsm_inst_alloc_child(&sub_pres_vlr_fsm, parent,
 					term_event);
+	*fi_p = fi;
 	if (!fi)
-		return NULL;
+		return;
 
 	fi->priv = vsub;
 	osmo_fsm_inst_dispatch(fi, SUB_PRES_VLR_E_START, NULL);
-
-	return fi;
 }
 
 /***********************************************************************
@@ -384,9 +392,7 @@
 	osmo_fsm_inst_state_chg(fi, LU_COMPL_VLR_S_WAIT_SUB_PRES,
 				LU_TIMEOUT_LONG, 0);
 
-	lcvp->sub_pres_vlr_fsm = sub_pres_vlr_fsm_start(fi, vsub,
-						LU_COMPL_VLR_E_SUB_PRES_COMPL);
-
+	sub_pres_vlr_fsm_start(&lcvp->sub_pres_vlr_fsm, fi, vsub, LU_COMPL_VLR_E_SUB_PRES_COMPL);
 }
 
 static void lu_compl_vlr_new_tmsi(struct osmo_fsm_inst *fi)

-- 
To view, visit https://gerrit.osmocom.org/4923
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ibdc0b64cd12ba3e2b9737e3517d8484e67abcf04
Gerrit-PatchSet: 1
Gerrit-Project: osmo-msc
Gerrit-Branch: master
Gerrit-Owner: Neels Hofmeyr <nhofmeyr at sysmocom.de>



More information about the gerrit-log mailing list