When bearer contexts are migrated between MME-UE objects during UE
context relocation (OLD UE -> NEW UE), the existing ogs_pool-based
EBI tracking could become inconsistent.
In mme_ue_set_imsi(), bearer->ebi_node was freed from the old UE pool
without reserving the same EBI in the new UE context. This allowed
duplicate allocations and eventually exhausted the EBI pool (5..15),
triggering a fatal assertion in mme_bearer_add().
This patch replaces the pool-node based EBI handling with a bitmap
allocator, which is safe across UE context migration and supports
explicit EBI reservation.
Also update related test cases to match the new allocation order.
Fixes: #4294
Bug:
A double-free scenario in the error handling path:
When ogs_sbi_send_request_with_sepp_discovery failed, it called
ogs_sbi_xact_remove(xact) internally.
The function then returned false to its caller. The caller
(smf_sbi_discover_and_send) also called ogs_sbi_xact_remove(xact)
on failure.
This caused the discovery_option structure to be freed twice,
leading to the valgrind error:
```
==90== Invalid read of size 8
==90== at 0x49AFBB6: ogs_sbi_discovery_option_free (message.c:3633)
==90== by 0x49CC100: ogs_sbi_xact_remove (context.c:2674)
==90== by 0x407DDDC: smf_sbi_discover_and_send (sbi-path.c:392)
```
Fix:
Now the function follows proper resource ownership semantics:
the caller who creates the transaction is responsible for cleanup
when the function fails, making the error handling consistent and
preventing double-free issues.
Added missing cleanup to ogs_sbi_send_request_to_nf_instance and
af_sbi_discover_and_send.
When handling Create Indirect Data Forwarding Tunnel Request,
SGW-C unconditionally sent a PFCP Session Modification Request
with OGS_PFCP_MODIFY_INDIRECT|CREATE.
However, some session contexts do not contain any indirect
DL/UL forwarding tunnel information, which leads to assertion
failures inside PFCP handling.
This patch checks whether a session actually has an indirect
forwarding tunnel before sending the PFCP modification request,
and logs detailed context information otherwise.
This is the same class of issue previously observed with
Delete Indirect Tunnel handling in issue #4073.
Fixes: #4073
Fix an AMF crash when a UE sends a new Registration Request immediately
after UE-initiated Deregistration.
In this scenario, SM Context release and SDM subscription DELETE requests
are triggered during deregistration, but their SBI responses may arrive
later while the AMF is already handling a subsequent Registration Request
(Integrity Protected).
Previously, late SDM_SUBSCRIPTIONS DELETE responses were processed in
unexpected GMM states (registered, authentication, initial-context-setup),
leading to ogs_assert_if_reached() and AMF crashes.
This commit changes the behavior to explicitly ignore late
SDM_SUBSCRIPTIONS DELETE responses in such states, treating them as stale
and non-actionable. Fatal assertions in these paths are replaced with
warnings to prevent crashes caused by valid out-of-order SBI responses.
The fix is covered by a new regression test reproducing issue #4209,
including scenarios with and without active PDU sessions.
Limit authentication retries on repeated synchronization failures.
When the UE reports consecutive authentication failures with
"synchronization failure" cause, AMF and MME now track the failure
count per authentication procedure and send AUTHENTICATION REJECT
after two attempts, instead of retrying indefinitely.
The counter is reset on authentication state entry.
This aligns the behavior with 3GPP authentication procedures and
prevents infinite authentication loops caused by persistent
synchronization failures.
Issues: #4238
Handle BearerResourceFailureIndication arriving after the associated
S11 transaction has already expired.
Look up the associated S11 transaction before committing the S5-C
transaction, and gracefully drop the indication if the S11 transaction
no longer exists, instead of asserting and crashing.
This prevents a possible remote DoS caused by delayed S5-C failure
indications.
Issues: #4268
When handling ModifyBearerResponse in the OI (Operation Indication) path,
SGW-C assumed that the PGW S5U tunnel address was always initialized.
If the Bearer Context was not parsed and ul_tunnel->remote_ip remained
unset, building the S11 CreateSessionResponse could trigger an assertion
failure and crash the SGW-C process.
Add a defensive check in sgwc_s5c_handle_modify_bearer_response() to
validate the UL tunnel remote IP before proceeding, and return a proper
GTP error instead of aborting. Also replace an assertion with graceful
error handling in the SxA session modification response path.
This prevents a remotely triggerable SGW-C crash (DoS) caused by malformed
or incomplete ModifyBearerResponse messages.
Issues: #4257
Avoid aborting on malformed or oversized GTP messages that exhaust the
internal TLV pool.
- Replace ogs_assert() in ogs_tlv_get() with error handling and NULL return
- Detect TLV allocation and parsing failures in ogs_tlv_parse_block()
- Clean up partially parsed TLVs and return failure instead of aborting
- Limit hexdump size to prevent log flooding on malformed input
This prevents a single malformed message from crashing SGW-C/PGW-C/MME
and ensures graceful failure when TLV allocation or parsing fails.
Issues: #4234
SGW-C could be forced to abort when handling a crafted or delayed
S5-C response (Create/Modify/Delete Session) if the associated S11
transaction no longer exists.
The S5-C handler assumed that the corresponding S11 transaction is
always present and unconditionally asserted its existence, leading
to a process abort and denial-of-service.
This change removes the fatal assertion and safely handles the case
where the associated S11 transaction cannot be found by logging an
error and ignoring the response.
Issues: #4226
Prevent SGW-C and SMF from aborting when receiving late or orphan
GTPv2 bearer responses (Create/Update/Delete Bearer).
This change removes fatal assertions on missing UE/session contexts
and instead treats such cases as "Context Not Found" per 3GPP
TS 29.274.
In addition, improve FSM-level UE/session lookup by retrying context
identification using the locally stored TEID when the received TEID
is missing, zero, or no longer valid. This aligns the behavior with
TS 29.274 §5.5.2 and allows graceful handling of late responses after
context cleanup.
Together, these changes ensure that late or orphan GTPv2 responses
never crash SGW-C or SMF and are handled gracefully.
Issues: #4225
Handle late or out-of-order ESM/NAS events more safely by removing
assert-based assumptions on runtime UE/S1 contexts.
Replace fatal assertions with defensive runtime checks in ESM, NAS,
GTP, and S11 paths so that late messages received after bearer/session
or eNB-UE context release do not terminate the MME process.
This allows ongoing GTP/S11 procedures to continue or clean up safely
while gracefully handling missing S1 context, improving robustness
under real-world race conditions.
Issues: #4236
Add explicit error handling for missing EPS Bearer ID and S5/S8 U F-TEID
in Create Session Response processing. Instead of breaking out of the
loop, immediately send an appropriate GTPv2 error response and abort
processing.
Also handle the case where the referenced bearer context does not exist
by returning CONTEXT_NOT_FOUND, and add missing error logs for failed
F-TEID to IP conversion.
These changes prevent silent failures and ensure correct GTP error
signaling toward the MME.
Issues: #4224
Replace ogs_assert() and ogs_fatal() with runtime checks when allocating
UE contexts, transactions, and timers.
Handle pool and timer exhaustion gracefully by logging errors, cleaning
up partially created objects, and returning NULL instead of aborting
the process, improving control-plane robustness under high load or
resource limits.
Issues: #4220, #4221
Do not abort SGW-C when a Downlink Data Notification Ack arrives
after the related bearer or session has already been released.
Replace assert-based assumptions with runtime checks and logging,
and always commit the S11 transaction safely to prevent process
termination on late or malformed ACK messages.
Remove hard assertions in GTPv2 Bearer QoS and Flow QoS parsers and
replace them with defensive length validation. Invalid IEs are now
gracefully rejected by the caller instead of aborting the process.
Update SGW-C and SMF handlers to validate parser results and return
appropriate GTP-C error causes, preventing daemon crashes on malformed
GTPv2 messages.
Issues: #4217
SGW-C could abort when handling malformed GTPv2-C messages where an
F-TEID has neither IPv4 nor IPv6 flags set. In such cases,
ogs_gtp2_f_teid_to_ip() returned an error but the caller asserted on
OGS_OK, causing a process abort.
This change removes assertions on F-TEID and PFCP outer header creation
and replaces them with proper runtime validation and error handling.
Malformed or semantically incorrect messages are now rejected with an
appropriate GTP-C cause instead of crashing the control plane.
For Create Session Request handling, all error paths are unified through
a cleanup path to ensure partially created sessions are removed before
sending an error response, preventing resource leaks.
Issues: #4203
The meaning of pfcp_xact->assoc_xact_id differs depending on whether a PFCP
Session Modification response is related to an Error Indication.
For PFCP DEACTIVATE responses with OGS_PFCP_MODIFY_ERROR_INDICATION set,
assoc_xact_id refers to a bearer context rather than an S11 transaction.
Handle this case explicitly by resolving the bearer and UE context and
processing the session synchronization path accordingly.
For other DEACTIVATE cases, continue to resolve assoc_xact_id as an S11
transaction ID and send an appropriate GTPv2-C error response when possible,
while safely handling missing S11 transactions.
This change avoids incorrect transaction lookups and improves robustness
when handling PFCP Error Indication related DEACTIVATE responses.
When handling PFCP Session Modification responses with the DEACTIVATE flag,
SGWC assumed that a corresponding S11 transaction always existed and enforced
this with an assertion.
In some error paths (e.g. SGWU rejecting a PFCP modification due to missing
mandatory IEs or asynchronous cleanup), the associated S11 transaction may
already be released or may not exist at all. This caused SGWC to crash on
assertion failure.
Replace the assertion with a NULL check and log the condition (including IMSI
and associated transaction ID) when the S11 transaction is missing, while
allowing the PFCP transaction to be committed safely.
This change adds extensive logging across SGW-C GTP and PFCP paths
to identify the root cause of an assertion failure triggered when
building a PFCP Session Modification Request with no PDR/FAR changes.
The assertion was hit when the total number of remove/create/update
PDR/FAR entries was zero, indicating an invalid PFCP modification
state.
To trace where this condition originates, this commit:
- Promotes key debug logs to info level for better visibility
- Adds contextual logs when PFCP Session/Bearer Modification is invoked
from S11, S5-C, and SXA handlers
- Logs PFCP transaction state, modify flags, and bearer lists
- Logs detailed counters before asserting in
sgwc_sxa_build_bearer_to_modify_list()
These logs allow correlating GTP control-plane events with PFCP
modification requests and identifying cases where modification flags
are set but no effective PDR/FAR changes are generated.
A malformed SBI request with `"pduSessionId":0` (UNASSIGNED) or without
`pduSessionId` caused `smf_sess_find_by_psi()` to assert and crash.
This patch adds defensive validation in:
- smf_sess_add_by_sm_context()
- smf_sess_add_by_pdu_session()
If `is_pdu_session_id == false` or `pdu_session_id ==
OGS_NAS_PDU_SESSION_IDENTITY_UNASSIGNED`, log an error and safely discard
the request instead of creating a session.
Issues: #4201
Align full-DNN construction with 3GPP TS 23.003 §9.1.2 by switching the
Operator Identifier format from "5gc.mncXXX.mccYYY.3gppnetwork.org" to
"mncXXX.mccYYY.gprs". Introduce new helper utilities to extract and build
OI (Operator Identifier) from both PLMN-ID and FQDN, and replace the
legacy `ogs_home_network_domain_from_fqdn()` usage in AMF/SMF/PCF paths.
This resolves DNN misalignment in vSMF–hSMF PDU Session Create that
caused interop issues with external 5G core vendors during HR roaming.
Includes updates across AMF/SMF/PCF, unit tests, and supporting helpers.
Issues: #4096
In long-running deployments, a mismatch can occur between SMF’s stored
Gx/Gy/S6b Session-Id and the freeDiameter session table, typically after
peer reconnection, watchdog timeout, or internal cleanup. In such cases
`fd_sess_fromsid_msg()` may return `new != 0`, indicating that the
Diameter stack created a new session instance instead of retrieving the
existing one.
Previously, this condition triggered `ogs_assert(new == 0)` which caused
a fatal crash of the SMF (and potentially SGWC), interrupting normal
operation.
This patch replaces the assertion with a graceful recovery path:
- Log an error indicating that the Diameter session has been lost
- Free the pending request message and stored Session-Id
- Return early to trigger PDU session release handling by the upper layer
- Avoid process termination and maintain service continuity
This significantly improves robustness in long-running and fault-tolerant
deployments with commercial-grade operational requirements.
Issues: #4195
When a CPE (4G router) loses power abruptly without sending a Detach
Request, the ENB-UE context is removed first, causing the implicit
detach process to fail. This leaves sessions active in SMF/UPF/SGWC/SGWU.
Changes:
- Allow mme_send_delete_session_or_detach() to accept NULL enb_ue
- Remove enb_ue assertion in mme_gtp_send_delete_session_request()
- Conditionally set xact->enb_ue_id only when enb_ue is present
- Remove enb_ue assertion in mme_gtp_send_delete_all_sessions()
- Move ENB-UE context check in mme_s11_handle_delete_session_response()
after session cleanup to ensure proper resource release
- Change log level to INFO for Mobile Reachable timer in registered state
This ensures that implicit detach proceeds correctly even when the
ENB-UE context has already been released, allowing proper cleanup of
core network sessions.
Fixes session leak issue reported in GitHub issue #4194
Fix crash triggered by malformed PDU Session Resource Modify / Path Switch /
Handover Request Acknowledge transfers that contain invalid GTP Tunnel parameters
(IPv4/IPv6 flags both zero). Previously, these invalid states propagated to PFCP
rule creation, causing an assertion failure inside
ogs_pfcp_ip_to_outer_header_creation() and terminating SMF.
This patch adds defensive checks across NGAP handling paths and rejects
such requests early via SM-Context Update Error (HTTP 400), ensuring that
SMF continues normal operation for other UEs.
Key changes:
- Validate remote_dl_ip before processing
- Reject when IPv4/IPv6 flags are both zero
- Preserve session state by skipping invalid modifications
Prevents DoS-style SMF crash while maintaining 3GPP-compliant behavior.
Issues: #4193
When CreatePDR/PDI contains an F-TEID IE with length 0, SGWU aborted due to
assertion `pdr->f_teid.ipv4 || pdr->f_teid.ipv6` in ogs_pfcp_handle_create_pdr().
This allowed a malformed PFCP Session Establishment Request to remotely crash SGWU.
This patch adds validation for:
- Zero-length F-TEID IE (return INVALID_LENGTH)
- F-TEID without IPv4/IPv6 flag (return INVALID_F_TEID_ALLOCATION_OPTION)
Instead of asserting and aborting, SGWU now rejects the request gracefully by
returning an appropriate Cause/Offending IE.
Issues: #4182
This patch replaces fatal ogs_assert() calls in PFCP object allocation
(ogs_pfcp_{pdr,far,urr,qer}_find_or_add) with graceful error handling.
Previously, exceeding per-session resource limits (e.g., QER pool overflow
triggered via CreatePDR referencing undeclared QER-ID) would cause a process
abort in open5gs-upfd, leading to a remote denial-of-service condition.
The handler now returns PFCP Cause=NO_RESOURCES_AVAILABLE and properly
rejects malformed or resource-exhausting PFCP Session Establishment requests,
allowing the UPF to continue running without terminating all existing sessions.
Fixes: DoS vulnerability triggered by excessive implicit QER allocation.
Issues: #4181
Replace `ogs_assert(nxt == 0)` with validation and graceful error return
when parsing IPv6 jumbo payload where plen=0 but NextHeader is non-zero.
This prevents open5gs-upfd from aborting when receiving a single malformed
GTP-U IPv6 packet crafted to trigger assertion failure, resulting in a
remote DoS condition.
Malformed packets are now safely dropped and logged instead of terminating
the UPF process.
Issues: #4180
According to TS 29.244, FAR-ID is a mandatory IE in CreatePDR. However,
Open5GS previously accepted a Session Establishment Request containing a
CreatePDR without FAR-ID. When subsequent GTP-U packets matched the PDR,
the user-plane fast path dereferenced a NULL FAR pointer and aborted,
leading to a UPF crash (DoS).
This patch adds mandatory IE validation for FAR-ID in
ogs_pfcp_handle_create_pdr(), returning PFCP cause
MANDATORY_IE_MISSING when FAR-ID is absent.
As a result, malformed CreatePDR is rejected at PFCP control plane
instead of causing fatal assertion in the data path.
Fixes crash in `_gtpv1_u_recv_cb()` and improves robustness.
Issues: #4179
When receiving a PFCP Session Establishment Request containing a CreateURR
with an out-of-range URR-ID (e.g. 65535), UPF attempted to index
sess->urr_acc[] without bounds checking, leading to an assertion failure
and process abort.
This patch validates URR-ID before use and rejects the message gracefully
with an error cause if the value exceeds OGS_MAX_NUM_OF_URR. A clearer
log message is also added to indicate the valid range.
Fixes: assertion failure in upf_sess_urr_acc_timers_setup()
Issues: #4169
According to 3GPP TS 29.272 (5.2.1.1.2), when an Update Location Request
is sent due to an initial attach, the MME shall set the
"Initial-Attach-Indicator" flag in the ULR-Flags IE. This ensures that
the HSS updates the MME identity and prevents ULA rejection with
UNKNOWN_SERVING_NODE when UE moves between MMEs or when GUTI mismatch
occurs.
Commercial MME/HSS implementations (e.g., Cisco StarOS) also set the
Initial-Attach-Indicator flag by default to handle UEs that do not reset
their GUTI when changing networks.
This patch hardcodes the Initial-Attach-Indicator bit for all ULR
messages to align with expected practical behavior and resolve attach
failures caused by HSS identity mismatch.
Issues: #4165
* AMF dynamic PLMNs via APIREST
* add new feature now we can register ues when plmn is deleted
* add documentation for use the API AMF-OAM
* update tutorial 08
* fix memory not freed
fix memory not freed
fix memory not freed
* improve releases ues of plmn
The AK buffer is allocated with OGS_AK_LEN, but it was logged using
OGS_KEY_LEN, causing a stack buffer over-read under Address Sanitizer.
This change corrects the log length to OGS_AK_LEN.
Fixes the ASAN error reported during `volte cx-test`.
Issues: #4177
The previous key downloaded from `download.opensuse.org` was expired
(EXPKEYSIG FE7F42F276CEE0E6), causing `apt update` to fail when following
the Debian quickstart instructions.
This patch replaces the deprecated key URLs with valid signing key
download locations from build.opensuse.org and obs.osmocom.org.
Issues: #4175
A malformed CER containing duplicate Auth-Application-Id AVPs caused
freeDiameter to trigger FD_LOG_FATAL within parserules_check_one_rule(),
reaching an unimplemented branch and calling abort(), which terminated
Open5GS daemons (HSS/MME/PCRF/AAA) using the freeDiameter stack.
To avoid crashing on invalid Diameter messages, remove the call to
ogs_assert_if_reached() inside FD_LOG_FATAL logging path. This allows
Open5GS to gracefully reject malformed messages instead of aborting.
Issues: #4155
UPF could crash when handling PFCP Session Establishment/Update
containing a CreateURR with a malformed Dropped-DL-Traffic-Threshold IE.
Added length validation for Dropped-DL-Traffic-Threshold and
Volume Measurement IEs to prevent buffer misuse and return an
appropriate PFCP cause and offending IE value.
Also removed assertion in IE parsing functions and replaced it with
error logging and validation checks.
Issues: #4154, #4152
When PFCP Session Establishment/Modification includes CreatePDR with F-TEID
(CH=1) whose address family flags (IPv4/IPv6) do not match the UPF's GTP-U
resource configuration for the target DNN (Network Instance), UPF asserted
and crashed in ogs_pfcp_object_teid_hash_set(). This occurred because the
existing logic assumed a matching address family and enforced it via
assert().
This patch replaces the assertions with proper validation and returns an
appropriate PFCP cause (REQUEST_REJECTED) when the address family does not
match, or if local F-TEID generation fails. This prevents UPF from crashing
and allows the SMF to receive a graceful failure response.
Changes:
- ogs_pfcp_object_teid_hash_set() now returns PFCP Cause instead of void
- Validate IPv4/IPv6 compatibility for DNN resource and local GTP-U address
- Replace assert() usage with runtime error handling and logging
- Integrate cause checking in SGWU/UPF N4 handlers for both Session
Establishment and Modification
- Avoids crash and reports REQUEST_REJECTED when mismatch occurs
Tested scenario:
- UPF with IPv4-only DNN resource receiving CH F-TEID with IPv6-only flags
(or vice versa) no longer causes crash.
Issues: #4315
This patch introduces assoc_id[] to ogs_sbi_xact_t and stores a snapshot
of the RAN-UE ID (AMF_ASSOC_RAN_UE_ID) when the AMF sends SBI requests
to SMF/PCF. Since the RAN-NG context may change (e.g., during NG
Context release or RRC re-establishment) before the asynchronous SBI
response arrives, relying on sess->ran_ue_id can lead to incorrect
context resolution. The transaction-level snapshot ensures that AMF
uses the correct RAN-UE when handling SBI responses.
Key changes:
- Added assoc_id[] array to ogs_sbi_xact_t.
- Stored RAN-UE snapshot for SBI Client operations.
- Updated AMF handlers (amf-sm, nsmf-handler, nnssf-handler,
nnrf-handler, sbi-path) to use xact->assoc_id[] instead of
sess->ran_ue_id for SBI Client responses.
- Updated NAMF handlers to continue using sess->ran_ue_id since they
operate in SBI Server mode and have no transaction snapshot.
- Refactored function signatures to pass amf_ue and ran_ue explicitly.
- Added detailed comments to sess->ran_ue_id explaining the distinction
between SBI Client and SBI Server behavior.
- Updated test cases and added the new issues4174 test.
This resolves the race where RAN-UE context changes between SBI request
and response, ensuring correct session processing and eliminating
RAN-UE lookup failures during asynchronous callbacks.
Issues #4174