mirror of
https://github.com/open5gs/open5gs.git
synced 2025-10-23 07:41:57 +00:00
[PFCP] Validate F-TEID parameters to prevent UPF/SGWU crash (#3747)
This commit introduces robust validation for the F-TEID information element in the PFCP message handling. Previously, malformed F-TEID values (such as a zero length, zero TEID, or a TEID exceeding the pool size) could lead to an assertion failure and crash the UPF. The changes ensure that: - The F-TEID length is greater than zero, confirming the IE is present. - The TEID is a non-zero value, as a valid TEID must be positive. - The TEID does not exceed the allowed pool size (max_ue * 4 * 16). If any of these conditions are not met, an error is logged with the F-TEID length and TEID value, and the function returns an error code (OGS_PFCP_CAUSE_MANDATORY_IE_INCORRECT), preventing further processing of the malformed message.
This commit is contained in:
@@ -1356,14 +1356,30 @@ ogs_pfcp_pdr_t *ogs_pfcp_pdr_find_or_add(
|
||||
return pdr;
|
||||
}
|
||||
|
||||
void ogs_pfcp_pdr_swap_teid(ogs_pfcp_pdr_t *pdr)
|
||||
int ogs_pfcp_pdr_swap_teid(ogs_pfcp_pdr_t *pdr)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
ogs_assert(pdr);
|
||||
ogs_assert(!pdr->f_teid.ch);
|
||||
ogs_assert(pdr->f_teid.teid > 0 &&
|
||||
pdr->f_teid.teid <= ogs_pfcp_pdr_teid_pool.size);
|
||||
|
||||
/*
|
||||
* Issues #3747, #3574
|
||||
*
|
||||
* This code validates the F-TEID (Fully encapsulated TEID) information
|
||||
* element within a PDR structure before further processing the PFCP
|
||||
* message. The validation ensures that the F-TEID is present and
|
||||
* within acceptable limits defined by the system.
|
||||
*/
|
||||
if (pdr->f_teid_len > 0 &&
|
||||
pdr->f_teid.teid > 0 &&
|
||||
pdr->f_teid.teid <= ogs_pfcp_pdr_teid_pool.size) {
|
||||
/* PASS OK */
|
||||
} else {
|
||||
ogs_error("F-TEID LEN[%d] TEID[0x%x]",
|
||||
pdr->f_teid_len, pdr->f_teid.teid);
|
||||
return OGS_PFCP_CAUSE_MANDATORY_IE_INCORRECT;
|
||||
}
|
||||
|
||||
/* Find out the Array Index for the restored TEID. */
|
||||
i = pdr_random_to_index[pdr->f_teid.teid];
|
||||
@@ -1379,6 +1395,8 @@ void ogs_pfcp_pdr_swap_teid(ogs_pfcp_pdr_t *pdr)
|
||||
ogs_pfcp_pdr_teid_pool.array[i] = *(pdr->teid_node);
|
||||
*(pdr->teid_node) = pdr->f_teid.teid;
|
||||
}
|
||||
|
||||
return OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
|
||||
}
|
||||
|
||||
void ogs_pfcp_object_teid_hash_set(
|
||||
|
@@ -436,7 +436,7 @@ ogs_pfcp_pdr_t *ogs_pfcp_pdr_find(
|
||||
ogs_pfcp_pdr_t *ogs_pfcp_pdr_find_or_add(
|
||||
ogs_pfcp_sess_t *sess, ogs_pfcp_pdr_id_t id);
|
||||
|
||||
void ogs_pfcp_pdr_swap_teid(ogs_pfcp_pdr_t *pdr);
|
||||
int ogs_pfcp_pdr_swap_teid(ogs_pfcp_pdr_t *pdr);
|
||||
|
||||
void ogs_pfcp_object_teid_hash_set(
|
||||
ogs_pfcp_object_type_e type, ogs_pfcp_pdr_t *pdr,
|
||||
|
@@ -105,8 +105,11 @@ void sgwu_sxa_handle_session_establishment_request(
|
||||
* a new TEID for the first time, so performing a swap is not appropriate
|
||||
* in this case.
|
||||
*/
|
||||
if (pdr->f_teid.ch == false && pdr->f_teid_len)
|
||||
ogs_pfcp_pdr_swap_teid(pdr);
|
||||
if (pdr->f_teid.ch == false) {
|
||||
cause_value = ogs_pfcp_pdr_swap_teid(pdr);
|
||||
if (cause_value != OGS_PFCP_CAUSE_REQUEST_ACCEPTED)
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
restoration_indication = true;
|
||||
}
|
||||
@@ -116,6 +119,7 @@ void sgwu_sxa_handle_session_establishment_request(
|
||||
if (OGS_ERROR == ogs_pfcp_setup_far_gtpu_node(far)) {
|
||||
ogs_fatal("CHECK CONFIGURATION: sgwu.gtpu");
|
||||
ogs_fatal("ogs_pfcp_setup_far_gtpu_node() failed");
|
||||
cause_value = OGS_PFCP_CAUSE_SYSTEM_FAILURE;
|
||||
goto cleanup;
|
||||
}
|
||||
if (far->gnode)
|
||||
|
@@ -162,8 +162,11 @@ void upf_n4_handle_session_establishment_request(
|
||||
* a new TEID for the first time, so performing a swap is not appropriate
|
||||
* in this case.
|
||||
*/
|
||||
if (pdr->f_teid.ch == false && pdr->f_teid_len)
|
||||
ogs_pfcp_pdr_swap_teid(pdr);
|
||||
if (pdr->f_teid.ch == false) {
|
||||
cause_value = ogs_pfcp_pdr_swap_teid(pdr);
|
||||
if (cause_value != OGS_PFCP_CAUSE_REQUEST_ACCEPTED)
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
restoration_indication = true;
|
||||
}
|
||||
|
Reference in New Issue
Block a user