A friend in the community was trying to connect an SMF made by another
manufacturer with an SBI interface and found a big problem with Open5GS.
All of the code in the part that generates the Resource URI
from HTTP.location is invalid.
For example, suppose we create a Resource URI with SMContext as below.
{apiRoot}/nsmf-pdusession/<apiVersion>/sm-contexts/{smContextRef}
In this case, Open5GS extracted the {smContextRef} part of the HTTP.location
and appended it to the beginning
{apiRoot}/nsmf-pdusession/<apiVersion>/sm-contexts/.
This implementation may not work properly if the apiRoot changes.
Consider a different port number as shown below.
<HTTP.location>
127.0.0.4:9999/nsmf-pdusession/v1/sm-contexts/1
The SMF may send an apiRoot to the AMF with a changed port number,
in which case the AMF must honor it.
Therefore, instead of extracting only the smContextRef from HTTP.location,
we modified it to use the whole thing to create a Resource URI.
We modified all NFs that use HTTP.location in the same way, not just SMFs.
In InitialUEMessage, send a NAS message with a message type
other than Registration Request, Deregistration Request, or Service Request,
the following messages from UE will not be accepted.
We found this issue in not only the initial state but multiple states.
We believe if an attacker has the ability to inject a NAS message to the core,
it can perform a DoS attack on the victim UE.
So, I've fixed that The MME/AMF deletes MME_UE_S1AP_ID/AMF_UE_NGAP_ID,
and will not accept any following messages from the UE.
The AMF will crash on the following locations when it receives a sequence
of NAS messages from a UE.
- ogs_nas_encrypt: Assertion `pkbuf->len' failed. (../lib/nas/common/security.c:86)
- gmm_state_authentication: Assertion `r != OGS_ERROR' failed. (../src/amf/gmm-sm.c:1561)
Besides the crashes found above, an incorrect protocol transition
is identified in Open5GS. Without any Registration/Attach Request message,
when the Identity Response message sent, the Core Network responds
with an Authentication Request message. According to the standard,
only the Registration/Attach Request message can start a state transition
from the 5GMM/EMM-DEREGISTERED state to the 5GMM/EMM-COMMON-PROCEDURE-INITIATED.
So I've modified the relevant code to address these issues.
If a Create Bearer Response occurs after a Delete Bearer Response,
SGW-C crashes.
The execution is stopped by the following ASSERT
because it tries to access the UL Tunnel
deleted by the Delete Bearer Response.
```
03/28 17:28:41.229: [gtp] DEBUG: [7] LOCAL Find GTPv2 peer [172.22.0.9]:2123 (../lib/gtp/xact.c:949)
03/28 17:28:41.229: [gtp] DEBUG: [7] LOCAL Receive peer [172.22.0.9]:2123 (../lib/gtp/xact.c:966)
03/28 17:28:41.229: [gtp] DEBUG: [7] LOCAL UPD RX-96 peer [172.22.0.9]:2123 (../lib/gtp/xact.c:448)
03/28 17:28:41.229: [sgwc] DEBUG: Create Bearer Response (../src/sgwc/s11-handler.c:707)
03/28 17:28:41.229: [gtp] DEBUG: [7] LOCAL Commit peer [172.22.0.9]:2123 (../lib/gtp/xact.c:629)
03/28 17:28:41.230: [gtp] DEBUG: [7] LOCAL Delete peer [172.22.0.9]:2123 (../lib/gtp/xact.c:1149)
03/28 17:28:41.230: [sgwc] FATAL: sgwc_s11_handle_create_bearer_response: Assertion `ul_tunnel' failed. (../src/sgwc/s11-handler.c:802)
03/28 17:28:41.231: [core] FATAL: backtrace() returned 8 addresses (../lib/core/ogs-abort.c:37)
./open5gs-sgwcd(+0x189b7) [0x5b3c92cf09b7]
./open5gs-sgwcd(+0x13c6d) [0x5b3c92cebc6d]
/open5gs/install/lib/x86_64-linux-gnu/libogscore.so.2(ogs_fsm_dispatch+0x113) [0x70600ed63402]
./open5gs-sgwcd(+0x629d) [0x5b3c92cde29d]
/open5gs/install/lib/x86_64-linux-gnu/libogscore.so.2(+0x11754) [0x70600ed54754]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x8609) [0x70600ecfc609]
/lib/x86_64-linux-gnu/libc.so.6(clone+0x43) [0x70600ec21353]
```
To solve this problem, I have modified to handle the exception appropriately,
display the error situation in the Cause of the Create Bearer Response,
and proceed with the execution.
AS shown in 3GPP TS 29.244 C.2.1.1 diagram, the meaning of Threshold
value is different in Diameter Gy and in PFCP interfaces.
In Diameter Gy the value sets the trigger for the "remaining credit",
while in PFCP the value sets the trigger for the "used credit".
ThresholdPFCP = Quota - ThresholdGy
If eg. PCRF or AAA diameter link is not yet ready (eg. PCRF crashed),
and a client sends a CreateSessionRequest announcing its ow F-TEID,
then open5gs-smfd answers with Create Session Response Cause=
"Remote peer not responding", but it is not setting the received F-TEID
in the header of the response, instead it sends with TEI=0.
As a result, the peer cannot match the CreateSessionResponse,
and needs to rely on its own timeout timer to figure out
that specific request failed.
To address this issue, I modified the GTP Response message to check
the Sender F-TEID and send it accordingly, setting the destination TEID
to the value of the Sender F-TEID.
I've made this modification only for SMF, but MME and SGW-C have not done so;
if you need to, you can work from the examples in SMF.
Similarly, the same situation can happen with PFCP. If anyone needs to do this
in the future, I think you can work on it this way.
This is the continuation of commit
12158eebb8, which only checked the code in
CCA[Update], but not in CCA[Initial].
The handling in CCA[Initial] is a bit more complex since depending on
the outcome, we may end up with a Result-Code != SUCCESS in MSCC but the
session may still be created at the OCS because the message Result-Code
= SUCCESS. In that scenario, we want to abort setting up the PDN session
but we still need to make sure we terminate the Gy session that was just
created.
Cause is set according to particular NF standard.
Additionally:
- OGS_SBI_HTTP_STATUS_MEHTOD_NOT_ALLOWED typo fixed.
- [PCF] Fixed SM Policy establishment error handling
First of all, it crashes when creating a Dedicated Bearer
on the default Session that is created for the first time.
This behavior should be possible, so the related ASSERT is removed.
Next, the InitialContextRequest is modified
during the Attach Request to include the first Bearer.
Finally, there was an issue where trying to create a Dedicated Bearer
with SGsAP enabled resulted in an InitialContextSetupRequest message
with a PTI of zero. This is because MME initializes the PTI to 0
upon receiving the Create Bearer Request while processing SGsAP.
All of these issues has been fixed.
1. According to ETSI TS 129 118 4.1, if the Network Access Mode (NAM) is set
to "Packet only," no SGs association should be established.
2. If the NAM is set to "Packet and Circuit," and the SGs association is
rejected by the CS core, this rejection should only impact
the SGs association itself and not result in a UE attach rejection
for a UE with a valid HSS account.
'node_timeout' and some other functions can remove a smf_sess_t
while that session is still waiting for a PFCP reply
and has an active PFCP xact.
In this case, xact->data points to the deleted session
and xact's timeout function (sess_5gc_timeout for example)
eventually refers to this already freed session.
This fix prevents duplicate deletes from occurring by checking to see
if the session context has already been deleted when the timeout occurs.
Additionally, it moves session deletions out of timer callbacks into
state machine by reselect_upf().
Due to the way 'ogs_timer_mgr_expire' calls timer callbacks,
one must not stop or expire timers from within a timer callback.
And now one must not remove sessions from within a timer callback.
If eg. PCRF or AAA diameter link is not yet ready (eg. PCRF crashed), and
a client sends a CreateSessionRequest announcing its ow F-TEID,
then open5gs-smfd answers with Create Session Response Cause=
"Remote peer not responding", but it is not setting the received F-TEID
in the header of the response, instead it sends with TEI=0.
As a result, the peer cannot match the CreateSessionResponse, and needs
to rely on its own timeout timer to figure out that specific request failed.
This also happens in PFCP, so to solve this problem, I added teid/seid_presence
to the interface that sends the error message as shown below.
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value);
When we try to send an SBI message to SMF to release a session,
sometimes ran_ue is NULL. This happens when the Mobile Reachable Timer expires
and Implicit Deregistration is triggered.
To account for this case, we added the `ran_ue` parameter to the SBI interface
and made it work even if it is NULL.
This AVP is optional and was added in later releases of the 3GPP TS
32.299 spec. For instance, it shows up in Release 16 (V16.2.0), but
doesn't show up in Release 12 (V12.7.0).
Some OCS, like PortaOne OCS, implement older versions of the release
(V12.14.0), and hence fail when receiving the 3GPP-RAT-Type inside
Multiple-Services-Credit-Control AVP.
Since nowadays we also send the 3GPP-RAT-Type in PS-Information AVP,
which has been specified for longer time (it already shows up in
V12.7.0), drop it from Multiple-Services-Credit-Control to have greater
compatibility with other vendors.
* [SBI] Handle and store AMF info
* [SBI] Add "target GUAMI" discovery option
* [SBI] Handle UeContextTransfer request and response messages
* [AMF] Handle NF discovery from AMF to AMF
* [AMF] Add UE Context Transfer Request/Response from AMF to AMF
* [SCP] Handle UeContextTransfer
* Follow-up on #3052
* [AMF] force authentication after 'Ue context transfer' for now
* [AMF] force authentication after 'Ue context transfer' for now
---------
Co-authored-by: Sukchan Lee <acetcom@gmail.com>
This happens for instance when the session is terminated due to a
rejection coming from the OCS, hence no originating GTP xact producing
the tear down.
The xact may well be NULL, eg. when tearin down the session
(send_ccr_termination_req_gx_gy_s6b()) because OCS rejected an update:
Hence there's no GTP xact originating the tear down, aka e->gtp-xact
passed to the function is NULL.
smf_gx_send_ccr() is already handling this case properly, contrary to smf_gf_send_ccr().
Assume the UE has Attached, the session has been created,
and is in the IDLE state with the UEContextRelease process.
This could result in the following call flow.
1. TAU request without Integrity Protected
2. Authentication request/response
3. Security-mode command/complete
MME can be performed simultaneously by the HSS(S6A) and UE(S1AP).
Update-Location-Request
Service request
Service reject
Delete Session Request
Delete Session Response
Update-Location-Answer
UEContextReleaseCommand for Service reject
TAU reject
UEContextReleaseCommand for TAU reject
UEContextReleaseComplete
UEContextReleaseComplete
MME crashes when UE sends a service request(S1AP) during ULR/ULA(S6A) with HSS,
which has been fixed.
Transaction Identity doesn't map 1-to-1 with Procedure Transaction
Identity: The value ranges change, and PTI cannot use value 0 8which
means unused).
Hence, for now let's simply set the PTI to a valid default value instead
of asserting during mme_sess_add:
Assertion `pti != OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED'
Related: https://github.com/open5gs/open5gs/issues/3020
1. HandoverRequired
2. HandoverRequest
3. HandoverFailure
4. UEContextReleaseCommand
5. HandoverPreparationFailure
If UEContextReleaseComplete is not received,
the Source-UE will have the Target-UE.
6. HandoverRequired
There may be cases where the Source UE has a Target UE
from a previous HandoverRequired process. In this case,
it is recommended to force the deletion of the Target UE information
when receiving a new HandoverRequired.
7. HandoverRequest
8. HandoverFailure
9. UEContextReleaseCommand
10. UEContextReleaseComplete
11. HandoverPreparationFailure
... Crashed ...
For bi-directions, the rules are created in the same form as for downlink
as shown below, so to apply them for uplink, we need to swap the rules
according to the interface.
RX : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
GX : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
PFCP : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
RULE : Source <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> Destination <UE_IP> <UE_PORT>
TFT : Local <UE_IP> <UE_PORT> REMOTE <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
RX : permit in from <UE_IP> <UE_PORT> to <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
GX : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
PFCP : permit out from <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT> to <UE_IP> <UE_PORT>
RULE : Source <UE_IP> <UE_PORT> Destination <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
TFT : Local <UE_IP> <UE_PORT> REMOTE <P-CSCF_RTP_IP> <P-CSCF_RTP_PORT>
APER encoding fails when using the asn_uint642INTEGER function on a 32-bit machine as shown below.
```C
asn_uint642INTEGER(AMF_UE_NGAP_ID, 0xffffffff);
...
aper_encode_to_buffer(...)
```
INTEGER APER encode/decode functions seem to be operating internally with long variables instead of intmax_t.
That is probably the reason of the failure.
@v0-e fixed this issues in the mouse07410/asn1c pull request.
https://github.com/mouse07410/asn1c/pull/176https://github.com/mouse07410/asn1c/pull/177