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.
This commit is contained in:
Guido Casati
2025-04-15 19:54:23 +02:00
parent c6271a23e4
commit 73b89726ad
3 changed files with 45 additions and 15 deletions
@@ -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]);
}
}
@@ -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_) */
+8 -4
View File
@@ -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 */