From 05ac4e52b9d109e22a84c9468991187f11735014 Mon Sep 17 00:00:00 2001 From: Alexander Couzens Date: Mon, 4 Jan 2021 19:07:05 +0100 Subject: gprs_ns2: check if persistent nsei or nsvc exists when creating dynamic NSE When receiving a NS Reset over an unknown NSVC the NS code would create a dynamic NSE. If the NSEI or NSVCI is already configured to a persistant NSE/NSVC the packet should be ignored. Related: SYS#5208 Change-Id: I855911e7d364f2e5b08ea05857747aa63fcf1cd3 --- src/gb/gprs_ns2.c | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/gb/gprs_ns2.c b/src/gb/gprs_ns2.c index 3ca87a4b..7f43cf02 100644 --- a/src/gb/gprs_ns2.c +++ b/src/gb/gprs_ns2.c @@ -861,18 +861,49 @@ enum gprs_ns2_cs ns2_create_vc(struct gprs_ns2_vc_bind *bind, return GPRS_NS2_CS_REJECTED; } - /* find or create NSE */ nsei = tlvp_val16be(&tp, NS_IE_NSEI); + nsvci = tlvp_val16be(&tp, NS_IE_VCI); + + /* find or create NSE */ nse = gprs_ns2_nse_by_nsei(bind->nsi, nsei); if (!nse) { - if (!bind->nsi->create_nse) { + /* only create nse for udp & ipaccess */ + if (bind->ll != GPRS_NS2_LL_UDP || dialect != NS2_DIALECT_IPACCESS) + return GPRS_NS2_CS_SKIPPED; + + if (!bind->nsi->create_nse || !bind->accept_ipaccess) return GPRS_NS2_CS_SKIPPED; - } nse = gprs_ns2_create_nse(bind->nsi, nsei, bind->ll, dialect); if (!nse) { + LOGP(DLNS, LOGL_ERROR, "Failed to create NSE(%05u)\n", nsei); return GPRS_NS2_CS_ERROR; } + } else { + /* nsei already known */ + if (nse->ll != bind->ll) { + LOGP(DLNS, LOGL_ERROR, "Received NS-RESET NS-VCI(%05u) with wrong linklayer(%s) for already known NSE(%05u/%s)\n", + nsei, gprs_ns2_lltype_str(bind->ll), nse->nsei, gprs_ns2_lltype_str(nse->ll)); + return GPRS_NS2_CS_SKIPPED; + } + } + + nsvc = gprs_ns2_nsvc_by_nsvci(bind->nsi, nsvci); + if (nsvc) { + if (nsvc->persistent) { + LOGP(DLNS, LOGL_ERROR, "Received NS-RESET for a persistent NSE(%05u) NS-VCI(%05u) over wrong connection.\n", + nsei, nsvci); + return GPRS_NS2_CS_SKIPPED; + } + /* destroy old dynamic nsvc */ + gprs_ns2_free_nsvc(nsvc); + } + + /* do nse persistent check late to be more precise on the error message */ + if (nse->persistent) { + LOGP(DLNS, LOGL_ERROR, "Received NS-RESET for a persistent NSE(%05u) but the unknown NS-VCI(%05u)\n", + nsei, nsvci); + return GPRS_NS2_CS_SKIPPED; } vc_mode = gprs_ns2_dialect_to_vc_mode(dialect); @@ -880,7 +911,6 @@ enum gprs_ns2_cs ns2_create_vc(struct gprs_ns2_vc_bind *bind, if (!nsvc) return GPRS_NS2_CS_SKIPPED; - nsvci = tlvp_val16be(&tp, NS_IE_VCI); nsvc->nsvci = nsvci; nsvc->nsvci_is_valid = true; -- cgit v1.2.3