From 73b89726ad993f5accdfe9e60bb2ea94662076c6 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Fri, 7 Feb 2025 17:24:27 +0100 Subject: [PATCH] Remove harcoded Slice Differentiator (SD) in NAS decode_nssai_ie and update the processing logic The SD stored in the allowed S-NSSAI list was hardcoded in the decoding function, however this IE is not mandatory but optional, therefore the check of the decoded message contents should take into account this and check the stored value against the one from the UICC only when the field is present. If no SD was received, consider the UICC SD a valid one. Also, add free function to Registration Accept library and adopt in stack to free NAS Registration Accept after use: heap memory is allocated for this message during decoding and shall be free after processing. --- .../NR_UE/5GS/5GMM/MSG/RegistrationAccept.c | 40 +++++++++++++++---- .../NR_UE/5GS/5GMM/MSG/RegistrationAccept.h | 8 ++-- openair3/NAS/NR_UE/nr_nas_msg.c | 12 ++++-- 3 files changed, 45 insertions(+), 15 deletions(-) diff --git a/openair3/NAS/NR_UE/5GS/5GMM/MSG/RegistrationAccept.c b/openair3/NAS/NR_UE/5GS/5GMM/MSG/RegistrationAccept.c index d65d196701..f6b67edb11 100644 --- a/openair3/NAS/NR_UE/5GS/5GMM/MSG/RegistrationAccept.c +++ b/openair3/NAS/NR_UE/5GS/5GMM/MSG/RegistrationAccept.c @@ -79,7 +79,6 @@ static int decode_nssai_ie(nr_nas_msg_snssai_t *nssai, uint8_t *num_slices, uint const uint8_t *end = buf + length; while (buf < end) { nr_nas_msg_snssai_t *item = nssai + nssai_cnt; - item->sd = 0xffffff; const int item_len = *buf++; // Length of S-NSSAI IE item switch (item_len) { case 1: @@ -89,31 +88,38 @@ static int decode_nssai_ie(nr_nas_msg_snssai_t *nssai, uint8_t *num_slices, uint case 2: item->sst = *buf++; - item->hplmn_sst = *buf++; + item->hplmn_sst = malloc_or_fail(sizeof(*item->hplmn_sst)); + *item->hplmn_sst = *buf++; nssai_cnt++; break; case 4: item->sst = *buf++; - item->sd = 0xffffff & ntoh_int24_buf(buf); + item->sd = malloc_or_fail(sizeof(*item->sd)); + *item->sd = 0xffffff & ntoh_int24_buf(buf); buf += 3; nssai_cnt++; break; case 5: item->sst = *buf++; - item->sd = 0xffffff & ntoh_int24_buf(buf); + item->sd = malloc_or_fail(sizeof(*item->sd)); + *item->sd = 0xffffff & ntoh_int24_buf(buf); buf += 3; - item->hplmn_sst = *buf++; + item->hplmn_sst = malloc_or_fail(sizeof(*item->hplmn_sst)); + *item->hplmn_sst = *buf++; nssai_cnt++; break; case 8: item->sst = *buf++; - item->sd = 0xffffff & ntoh_int24_buf(buf); + item->sd = malloc_or_fail(sizeof(*item->sd)); + *item->sd = 0xffffff & ntoh_int24_buf(buf); buf += 3; - item->hplmn_sst = *buf++; - item->hplmn_sd = 0xffffff & ntoh_int24_buf(buf); + item->hplmn_sst = malloc_or_fail(sizeof(*item->hplmn_sst)); + *item->hplmn_sst = *buf++; + item->hplmn_sd = malloc_or_fail(sizeof(*item->hplmn_sd)); + *item->hplmn_sd = 0xffffff & ntoh_int24_buf(buf); buf += 3; nssai_cnt++; break; @@ -198,3 +204,21 @@ int encode_registration_accept(const registration_accept_msg *registration_accep return encoded; } + +/** Memory management of NAS Registration Accept */ + +static void free_nssai(nr_nas_msg_snssai_t *msg) +{ + free(msg->hplmn_sd); + free(msg->hplmn_sst); + free(msg->sd); +} + +void free_fgmm_registration_accept(registration_accept_msg *msg) +{ + free(msg->guti); + for (int i = 0; i < NAS_MAX_NUMBER_SLICES; i++) { + free_nssai(&msg->nas_allowed_nssai[i]); + free_nssai(&msg->config_nssai[i]); + } +} diff --git a/openair3/NAS/NR_UE/5GS/5GMM/MSG/RegistrationAccept.h b/openair3/NAS/NR_UE/5GS/5GMM/MSG/RegistrationAccept.h index 4c50de9384..c373c067fa 100644 --- a/openair3/NAS/NR_UE/5GS/5GMM/MSG/RegistrationAccept.h +++ b/openair3/NAS/NR_UE/5GS/5GMM/MSG/RegistrationAccept.h @@ -51,9 +51,9 @@ typedef enum { // 9.11.3.37 of 3GPP TS 24.501 typedef struct { int sst; - int hplmn_sst; - int sd; - int hplmn_sd; + int *hplmn_sst; + int *sd; + int *hplmn_sd; } nr_nas_msg_snssai_t; /* @@ -81,4 +81,6 @@ size_t decode_registration_accept(registration_accept_msg *registrationaccept, c int encode_registration_accept(const registration_accept_msg *registrationaccept, uint8_t *buffer, uint32_t len); +void free_fgmm_registration_accept(registration_accept_msg *msg); + #endif /* ! defined(REGISTRATION_ACCEPT_H_) */ diff --git a/openair3/NAS/NR_UE/nr_nas_msg.c b/openair3/NAS/NR_UE/nr_nas_msg.c index 5ee233172c..55bad1c2eb 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg.c +++ b/openair3/NAS/NR_UE/nr_nas_msg.c @@ -1410,11 +1410,14 @@ static void request_default_pdusession(nr_ue_nas_t *nas) itti_send_msg_to_task(TASK_NAS_NRUE, nas->UE_id, message_p); } -static int get_user_nssai_idx(const nr_nas_msg_snssai_t allowed_nssai[8], const nr_ue_nas_t *nas) +static int get_user_nssai_idx(const nr_nas_msg_snssai_t allowed_nssai[NAS_MAX_NUMBER_SLICES], const nr_ue_nas_t *nas) { - for (int i = 0; i < 8; i++) { + for (int i = 0; i < NAS_MAX_NUMBER_SLICES; i++) { const nr_nas_msg_snssai_t *nssai = allowed_nssai + i; - if ((nas->uicc->nssai_sst == nssai->sst) && (nas->uicc->nssai_sd == nssai->sd)) + /* If it was received in Registration Accept, check the SD + in the stored Allowed N-SSAI, else, consider the SD valid */ + bool sd_match = !nssai->sd || (nas->uicc->nssai_sd == *nssai->sd); + if ((nas->uicc->nssai_sst == nssai->sst) && sd_match) return i; } return -1; @@ -1476,7 +1479,6 @@ static void handle_registration_accept(nr_ue_nas_t *nas, const uint8_t *pdu_buff // process GUTI if (msg.guti) { process_guti(&msg.guti->guti, nas); - free(msg.guti); } else { LOG_W(NAS, "no GUTI in registration accept\n"); } @@ -1495,6 +1497,8 @@ static void handle_registration_accept(nr_ue_nas_t *nas, const uint8_t *pdu_buff } else { request_default_pdusession(nas); } + // Free local message after processing + free_fgmm_registration_accept(&msg); } /* 3GPP TS 24.008 10.5.7.3 GPRS Timer */