diff options
author | Pau Espin Pedrol <pespin@sysmocom.de> | 2022-02-28 13:58:51 +0100 |
---|---|---|
committer | Pau Espin Pedrol <pespin@sysmocom.de> | 2022-03-01 12:38:58 +0100 |
commit | 9b288b788ef400a464f907f7d03ef8fe765f3d90 (patch) | |
tree | 2de1f6fd75e570300606d159302432f4744b1619 /gtp | |
parent | 134ac7e7c8b0481f13cb5ea629755e540476409f (diff) |
libgtp: Fix ggsn crash if pdp alloc array is full (PDP_MAX)
osmo-ggsn crashes when concurrent pdp context num 1024 is created, due to
the gsn->pdpa array (of size PDP_MAX, 1024) being full.
The crash happens because return code of gtp_pdp_newpdp was not checked,
and hence a pointer "pdp" pointing to a temporary not-fully-allocated
object was being passed to gsn->cb_create_context_ind() callback.
Let's avoid crashing and instead reject the PDP context.
Related: OS#5469
Change-Id: I0d94ffad97eb4fef477d981bf285bf99740592a3
Diffstat (limited to 'gtp')
-rw-r--r-- | gtp/gtp.c | 13 |
1 files changed, 12 insertions, 1 deletions
@@ -1809,7 +1809,16 @@ int gtp_create_pdp_ind(struct gsn_t *gsn, int version, } } - gtp_pdp_newpdp(gsn, &pdp, pdp->imsi, pdp->nsapi, pdp); + rc = gtp_pdp_newpdp(gsn, &pdp, pdp->imsi, pdp->nsapi, pdp); + if (rc != 0) { + GTP_LOGPKG(LOGL_ERROR, peer, pack, len, + "Failed creating a new PDP context, array full (%u)\n", PDP_MAX); + /* &pdp in gtp_pdp_newpdp is untouched if it failed: */ + rc = gtp_create_pdp_resp(gsn, version, pdp, GTPCAUSE_NO_MEMORY); + /* Don't pass it to emit_cb_recovery, since allocation failed and it was already rejected: */ + pdp = NULL; + goto recover_ret; + } /* Callback function to validate login */ if (gsn->cb_create_context_ind != 0) @@ -1820,6 +1829,8 @@ int gtp_create_pdp_ind(struct gsn_t *gsn, int version, rc = gtp_create_pdp_resp(gsn, version, pdp, GTPCAUSE_NOT_SUPPORTED); } + +recover_ret: if (recovery_recvd) emit_cb_recovery(gsn, peer, pdp, recovery); return rc; |