From be9ed7163142aae1e99b896067fbf5a025bf5155 Mon Sep 17 00:00:00 2001 From: Philipp Maier Date: Thu, 24 Feb 2022 14:41:03 +0100 Subject: [PATCH] ranap_rab_ass: check for more than one RAB assignment req The spec permits RAB AssignmentRequests with multiple RABs at a time. Even though one voice call is assigned only one RAB in practice. Since the current FSM implementation only supports a 1:1 scenario, lets check if the MSC really assigns only one RAB and block RAB Assignments that do not fit in this scheme. Change-Id: I0f1d868fd0b4dc413533d6fcc5482862825181be Related: OS#5152 --- include/osmocom/hnbgw/ranap_rab_ass.h | 2 ++ src/osmo-hnbgw/mgw_fsm.c | 10 ++++++++ src/osmo-hnbgw/ranap_rab_ass.c | 15 ++++++++++++ tests/ranap_rab_ass/ranap_rab_ass_test.c | 28 +++++++++++++++++++++++ tests/ranap_rab_ass/ranap_rab_ass_test.ok | 1 + 5 files changed, 56 insertions(+) diff --git a/include/osmocom/hnbgw/ranap_rab_ass.h b/include/osmocom/hnbgw/ranap_rab_ass.h index eb18de8..13fd2df 100644 --- a/include/osmocom/hnbgw/ranap_rab_ass.h +++ b/include/osmocom/hnbgw/ranap_rab_ass.h @@ -17,3 +17,5 @@ int ranap_rab_ass_resp_ies_replace_inet_addr(RANAP_RAB_AssignmentResponseIEs_t * bool ranap_rab_ass_req_ies_check_release(RANAP_RAB_AssignmentRequestIEs_t *ies, uint8_t rab_id); bool ranap_rab_ass_resp_ies_check_failure(RANAP_RAB_AssignmentResponseIEs_t *ies, uint8_t rab_id); + +int ranap_rab_ass_req_ies_get_count(RANAP_RAB_AssignmentRequestIEs_t *ies); diff --git a/src/osmo-hnbgw/mgw_fsm.c b/src/osmo-hnbgw/mgw_fsm.c index 3da2b60..d90571b 100644 --- a/src/osmo-hnbgw/mgw_fsm.c +++ b/src/osmo-hnbgw/mgw_fsm.c @@ -689,6 +689,16 @@ int handle_rab_ass_req(struct hnbgw_context_map *map, struct osmo_prim_hdr *oph, mgw_fsm_priv = talloc_zero(map, struct mgw_fsm_priv); mgw_fsm_priv->ranap_rab_ass_req_message = message; + /* This FSM only supports RAB assignments with a single RAB assignment only. This limitation has been taken + * into account under the assumption that voice calls typically require a single RAB only. Nevertheless, we + * will block all incoming RAB assignments that try to assign more (or less) than one RAB. */ + if (ranap_rab_ass_req_ies_get_count(&message->msg.raB_AssignmentRequestIEs) != 1) { + LOGP(DMGW, LOGL_ERROR, + "mgw_fsm_alloc_and_handle_rab_ass_req() rua_ctx_id=%d, RAB-AssignmentRequest with more than one RAB assignment -- abort!\n", + map->rua_ctx_id); + goto error; + } + /* Parse the RAB Assignment Request now, if it is bad for some reason we will exit early and not bother with * creating an FSM etc. */ ies = &mgw_fsm_priv->ranap_rab_ass_req_message->msg.raB_AssignmentRequestIEs; diff --git a/src/osmo-hnbgw/ranap_rab_ass.c b/src/osmo-hnbgw/ranap_rab_ass.c index 56886c7..5930451 100644 --- a/src/osmo-hnbgw/ranap_rab_ass.c +++ b/src/osmo-hnbgw/ranap_rab_ass.c @@ -620,3 +620,18 @@ bool ranap_rab_ass_req_ies_check_release(RANAP_RAB_AssignmentRequestIEs_t *ies, return result; } + +/*! Find out how many RAB items are present in a RAB-SetupOrModifyList inside RANAP_RAB_AssignmentRequestIEs. + * \ptmap[in] ies user provided memory with RANAP_RAB_AssignmentRequestIEs. + * \returns number of RAB items, -1 on failure. */ +int ranap_rab_ass_req_ies_get_count(RANAP_RAB_AssignmentRequestIEs_t *ies) +{ + /* Make sure we indeed deal with a setup-or-modify list */ + if (!(ies->presenceMask & RAB_ASSIGNMENTREQUESTIES_RANAP_RAB_SETUPORMODIFYLIST_PRESENT)) { + RANAP_DEBUG + ("Decoding failed, the RANAP RAB AssignmentRequest did not contain a setup-or-modify list!\n"); + return -1; + } + + return ies->raB_SetupOrModifyList.list.count; +} diff --git a/tests/ranap_rab_ass/ranap_rab_ass_test.c b/tests/ranap_rab_ass/ranap_rab_ass_test.c index 052549e..9a98cf8 100644 --- a/tests/ranap_rab_ass/ranap_rab_ass_test.c +++ b/tests/ranap_rab_ass/ranap_rab_ass_test.c @@ -320,6 +320,33 @@ void test_ranap_rab_ass_req_ies_check_release(void) ranap_ran_rx_co_free(&message); } +void test_ranap_rab_ass_req_ies_get_count(void) +{ + int rc; + ranap_message message; + uint8_t testvec[] = { + 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x01, 0x00, + 0x36, 0x40, 0x52, 0x00, 0x00, 0x01, 0x00, 0x35, + 0x00, 0x48, 0x78, 0x22, 0xcd, 0x80, 0x10, 0x2f, + 0xa7, 0x20, 0x1a, 0x2c, 0x00, 0x00, 0xf4, 0x4c, + 0x08, 0x0a, 0x02, 0x80, 0x00, 0x51, 0x40, 0x00, + 0x27, 0x20, 0x28, 0x14, 0x00, 0x67, 0x40, 0x00, + 0x00, 0x22, 0x28, 0x14, 0x00, 0x3c, 0x40, 0x00, + 0x00, 0x00, 0x50, 0x3d, 0x02, 0x00, 0x02, 0x27, + 0xc0, 0x35, 0x00, 0x01, 0x0a, 0x09, 0x01, 0xa2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1f, 0x76, + 0x00, 0x00, 0x40, 0x01, 0x00, 0x00 + }; + + rc = ranap_ran_rx_co_decode(talloc_asn1_ctx, &message, testvec, sizeof(testvec)); + OSMO_ASSERT(rc == 0); + + rc = ranap_rab_ass_req_ies_get_count(&message.msg.raB_AssignmentRequestIEs); + printf("ranap_rab_ass_req_ies_get_count rc=%d\n", rc); + ranap_ran_rx_co_free(&message); +} + static const struct log_info_cat log_cat[] = { [DRANAP] = { .name = "RANAP", .loglevel = LOGL_DEBUG, .enabled = 1, @@ -382,6 +409,7 @@ int main(int argc, char **argv) test_ranap_rab_ass_resp_ies_replace_inet_addr(); test_ranap_rab_ass_resp_ies_check_failure(); test_ranap_rab_ass_req_ies_check_release(); + test_ranap_rab_ass_req_ies_get_count(); test_cleanup(); return 0; diff --git a/tests/ranap_rab_ass/ranap_rab_ass_test.ok b/tests/ranap_rab_ass/ranap_rab_ass_test.ok index 688925c..aca4ff3 100644 --- a/tests/ranap_rab_ass/ranap_rab_ass_test.ok +++ b/tests/ranap_rab_ass/ranap_rab_ass_test.ok @@ -18,3 +18,4 @@ ranap_rab_ass_resp_ies_check_failure rab_failed_at_hnb=1 (RAB ID 23) ranap_rab_ass_resp_ies_check_failure rab_failed_at_hnb=0 (RAB ID 44, which is not in the message) ranap_rab_ass_req_ies_check_release rab_release_req=1 (RAB ID 23) ranap_rab_ass_req_ies_check_release rab_release_req=0 (RAB ID 44, which is not in the message) +ranap_rab_ass_req_ies_get_count rc=1